When a PKCS#8 v2 key includes [1] publicKey, the X25519, ML-DSA and Falcon decoders import it without checking that it matches the private key. Ed25519 and Ed448 already check, through check_key when the caller is untrusted.
- X25519: RFC 7748 Alice's private key paired with Bob's public key decodes successfully, and
wc_curve25519_export_public then returns Bob's key.
- ML-DSA: key A's DER with key B's public key spliced in decodes, then fails to verify its own signatures.
- Falcon: a liboqs-generated key with one public-key coefficient changed decodes successfully (confirmed by probe).
Impact: a mismatched or tampered key file loads as valid. #10019 makes this more reachable, because RFC-form keys from other implementations now load. Fix: derive the public key, or check tr = H(pk) for ML-DSA, and compare. A PR will follow once #10019 lands.
When a PKCS#8 v2 key includes
[1] publicKey, the X25519, ML-DSA and Falcon decoders import it without checking that it matches the private key. Ed25519 and Ed448 already check, throughcheck_keywhen the caller is untrusted.wc_curve25519_export_publicthen returns Bob's key.Impact: a mismatched or tampered key file loads as valid. #10019 makes this more reachable, because RFC-form keys from other implementations now load. Fix: derive the public key, or check
tr = H(pk)for ML-DSA, and compare. A PR will follow once #10019 lands.