DHKEM decapsulation ignores the supplied receiver-public-key length
The public KEM dispatcher validates secret-key, encapsulation, and output sizes for DHKEM25519 and DHKEM448 but does not validate optional_len. It then treats optional as the receiver public key. The lower layer copies a fixed curve-sized value from that pointer, so a non-null short buffer causes an out-of-bounds read.
Vulnerable code
In cipher/kem.c, function _gcry_kem_decap:
if (seckey_len != GCRY_KEM_DHKEM25519_SECKEY_LEN
|| ciphertext_len != GCRY_KEM_DHKEM25519_ENCAPS_LEN
|| shared_len != GCRY_KEM_DHKEM25519_SHARED_LEN)
return GPG_ERR_INV_ARG;
return _gcry_ecc_dhkem_decap (algo, seckey, ciphertext, shared,
optional);Why it matters
Supplying a one-byte optional buffer is accepted by the dispatcher despite DHKEM's fixed-width receiver-public-key contract; the ASan reproducer observed a fixed 32-byte read beyond that allocation. An exact length check made the reproducer return an error cleanly. An attacker must influence arguments to the direct KEM API; the likely result is a crash, although adjacent readable bytes can also affect the derived secret. No direct memory disclosure was demonstrated.
Proposed fix
For each DHKEM variant, reject (optional && optional_len != PUBKEY_LEN) and (!optional && optional_len != 0) before dispatch, then pass the validated length into the lower layer as defense in depth. Preserve the intentional NULL, 0 mode, which recomputes the receiver public key from the secret key. Add ASan regression tests for null/inconsistent, one-byte-short, exact, and oversized optional buffers for both X25519 and X448, plus known-answer tests for both valid modes.