Resolve conflicts against the NodeDB signer/key primitives (#11050) and the
admin-key PKI decrypt budget (#11100).
- NodeDB: drop this branch's hasSeenXeddsaSigner in favour of develop's
isKnownXeddsaSigner. They answer the same question, but develop's reads the
dedicated warm signer bit (warmSignerOf) rather than the WarmProtected
category, and TrafficManagementModule already depends on it. Keep develop's
copyPublicKey/copyPublicKeyAuthoritative, isVerifiedSignerForKey and
commitRemoteKey/KeyCommitTrust.
- checkXeddsaReceivePolicy: keep this branch's Strict/Balanced/Compatible
policy, which is a superset of develop's balanced-only downgrade gate, and
call isKnownXeddsaSigner from it. develop's !pki_encrypted term is dropped
because the policy returns early for PKI packets before that check.
- perhapsDecode: keep develop's key resolution (NodeDB then pending-key, only
for real PKI candidates) plus its admin-key token bucket, and re-apply this
branch's pkiAttempted flag feeding the DECODE_OPAQUE verdict. Keep both
passesRoutingAuthGate and adminKeyFallbackAllowed/Refund.
- test_A17: model eviction the way NodeDB actually does it, passing the warm
signer bit as well as the XeddsaSigner category, since isKnownXeddsaSigner
reads the former.
Native suite: 38 suites, 743/743 cases, no sanitizer findings.
Audit of the XEdDSA packet-signing implementation (#10478) surfaced several
issues in when unsigned packets are accepted on receive or emitted on send.
This fixes them and adds regression coverage.
- Unicast NodeInfo exchange no longer breaks against signer nodes: the
NodeInfoModule downgrade drop is gated to broadcasts, since senders never
sign unicast (want_response replies, directed exchanges).
- Replace the payload-size sign heuristic with an exact encoded-size gate
(signedDataFits) and mirror it on the receive side, removing a dead band
where 167-168 B broadcasts were signed then failed TOO_LARGE.
- Extract the receive policy into checkXeddsaReceivePolicy() and apply it to
plaintext-MQTT decoded downlink, which previously skipped signature
verification and downgrade protection entirely.
- Reject signatures whose length is neither 0 nor 64 as malformed, so a
crafted partial signature can't inflate the size estimate and dodge the
unsigned-downgrade drop.
- Hold cryptLock on the MQTT verify path (shared Ed25519 key cache).
- Clear any client-preset signature on packets we originate, on all builds.
- Randomized (hedged) signing per the Signal XEdDSA spec: bump the
meshtastic/Crypto pin to the build where XEdDSA::sign mixes 32 bytes of
caller randomness into the nonce as Z (meshtastic/Crypto#3), and seed those
bytes in xeddsa_sign from HardwareRNG (checked, with a seeded-CSPRNG
fallback). test_crypto pins that repeated signs differ and both verify.
Adds test coverage: test_packet_signing groups A-E (receive matrix, send
policy, NodeInfo backstop, encoding invariants, decoded-ingress policy),
test_mqtt end-to-end downlink cases, and a test_crypto randomization check.
* Test commit for XEdDSA support
* Update to Crypto lib in Meshtatic org
* Generate a new node identity on key generation (#7628)
* Generate a new node identity on key generation
* Fixes
* Fixes
* Fixes
* Messed up
* Fixes
* Update src/modules/AdminModule.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/mesh/NodeDB.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Figured it out!
* Cleanup
* Update src/mesh/NodeDB.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/mesh/NodeDB.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update src/modules/AdminModule.cpp
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update crypto commit hash
* Some fixes for xeddsa pr (#9610)
* fix: add null check for getMeshNode() in NodeInfoModule
getMeshNode() can return nullptr for unknown nodes. Dereferencing
without a check crashes the firmware when receiving NodeInfo from
a node not yet in the database.
* fix: enforce XEdDSA signature verification and prevent stripping
Previously, failed signature verification still allowed the packet
through, making signatures purely cosmetic. Now:
- Failed verification drops the packet (DECODE_FAILURE)
- Successfully verified nodes get HAS_XEDDSA_SIGNED bitfield set
- Unsigned packets from previously-signing nodes are rejected
- Log levels reduced from WARN/ERROR to DEBUG/WARN as appropriate
* fix: include packet metadata in XEdDSA signature
The signature now covers [fromNode | packetId | portnum | payload]
instead of just the payload bytes. This prevents:
- Replay attacks (different packetId fails verification)
- Reattribution (different fromNode fails verification)
- Portnum redirection (different portnum fails verification)
Also adds a key initialization check to xeddsa_sign (returns false
if XEdDSA keys are all zeros) and checks the return value in the
encode path.
* fix: handle existing key pair in AdminModule security config
When a user provides both a valid private key and public key via
admin config, the crypto engine's DH private key and owner public
key were never loaded. DMs and XEdDSA signing would silently break.
Add an else branch to load both keys into the crypto engine.
* perf: cache Ed25519 public key conversion in xeddsa_verify
curve_to_ed_pub() performs field element parsing, inversion, and
multiplication on every call. Since packets from the same node
tend to arrive in bursts, a single-entry cache avoids repeating
this expensive conversion for consecutive packets from one sender.
* fix: skip identity cleanup when node number is unchanged
createNewIdentity() was called on every generateCryptoKeyPair(),
including normal boots where the same key is regenerated. This
caused unnecessary NodeDB writes and old-node cleanup logic to
run when the node number hadn't actually changed.
Also fixes only zeroing byte[0] of the old node's public key
instead of clearing the entire array.
* fix: replace hardcoded 120 with derived XEDDSA_SIGNATURE_SIZE constant
The payload size check for XEdDSA signing used a magic number (120).
Replace with a derivation from DATA_PAYLOAD_LEN and XEDDSA_SIGNATURE_SIZE
so the limit adjusts automatically if constants change. This also
increases the max signable payload from 120 to 169 bytes, which is
still safe since the actual encoded size is checked after pb_encode.
* fix: add const qualifiers to XEdDSA verify and curve_to_ed_pub inputs
pubKey, payload, and signature parameters in xeddsa_verify are
input-only and should not be modified. Same for curve_pubkey in
curve_to_ed_pub.
* chore: remove commented-out old Crypto dependency in portduino.ini
* Leave out the admin module change for now
---------
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
* trunk
* protobuf re-update
* Protobufs
* Merge resolution fix
* Put XEDDSA on the right bit
* NodeDB update to new nodeInfoLite accessors, etc
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Refine unsigned packet rejection logic in Router (#10534)
* use hardware random to fill the first 32 signature bytes with entropy prior to signing.
* Add XEdDSA packet-signing policy tests and update dependencies for macos
* Minor fixes
* integrate XEdDSA support and update dependencies across multiple modules
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Wessel <github@weebl.me>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>