DHKEM decapsulation ignores the supplied receiver-public-key length
Closed, ResolvedPublic

Assigned To
Authored By
• werner
Tue, Aug 4, 4:58 PM
Subscribers

Description

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.

Related Objects

Event Timeline

• werner triaged this task as Normal priority.Tue, Aug 4, 4:58 PM
• werner created this task.
• werner created this object with visibility "Public (No Login Required)".
• werner created this object with edit policy "Contributor (Project)".
• werner updated the task description. (Show Details)
• gniibe changed the task status from Open to Testing.Wed, Aug 12, 4:53 AM
• gniibe mentioned this in Unknown Object (Maniphest Task).Mon, Aug 24, 8:26 AM
• werner shifted this object from the Restricted Space space to the S1 Public space.