File: crates/crypto/src/lib.rs:392-424
Severity: security
Obvious? no
The function uses an ephemeral X25519 secret + recipient's static X25519 (derived from Ed25519) to wrap a ChannelKey. There is no sender authentication in the wrap itself — anyone with the recipient's public key can produce a valid EncryptedChannelKey containing an attacker-chosen key. In Willow this is mitigated because RotateChannelKey events are Ed25519-signed by an author with ManageChannels permission, so the wrap appears inside a signed envelope. But this is a sharp edge: any future code path that consumes EncryptedChannelKey outside a signed event (e.g. a direct DM key handoff, a relay-served bootstrap blob, or an out-of-band invite payload) would inherit an unauthenticated wrap.
Fix: bind the sender's identity into the AAD (e.g. include sender Ed25519 pubkey in the Ed25519-signed wrapper struct or use a sender-authenticated KEM).
Filed by /general-audit @ 6404719 (2026-05-03). master: #567.
File:
crates/crypto/src/lib.rs:392-424Severity: security
Obvious? no
The function uses an ephemeral X25519 secret + recipient's static X25519 (derived from Ed25519) to wrap a
ChannelKey. There is no sender authentication in the wrap itself — anyone with the recipient's public key can produce a validEncryptedChannelKeycontaining an attacker-chosen key. In Willow this is mitigated becauseRotateChannelKeyevents are Ed25519-signed by an author withManageChannelspermission, so the wrap appears inside a signed envelope. But this is a sharp edge: any future code path that consumesEncryptedChannelKeyoutside a signed event (e.g. a direct DM key handoff, a relay-served bootstrap blob, or an out-of-band invite payload) would inherit an unauthenticated wrap.Fix: bind the sender's identity into the AAD (e.g. include sender Ed25519 pubkey in the Ed25519-signed wrapper struct or use a sender-authenticated KEM).
Filed by
/general-audit@6404719(2026-05-03). master: #567.