Skip to content

Hybrid KEM combiner design feedback: SHA3-256 concat vs HKDF for X25519 + ML-KEM-1024 #346

Description

@cleitonaugusto

Context

I've been building a post-quantum authenticated command-and-control layer for MAVLink v2 drones using crates from this org: ml-kem for session key encapsulation, ml-dsa for per-command signing, hmac + sha3 for the session MAC. The library is at https://github.com/cleitonaugusto/CleitonQ if the code is useful context.

One thing I'd value feedback on is the hybrid KDF combiner.

The combiner pattern

For session establishment, I combine X25519 and ML-KEM-1024 shared secrets using a SHA3-256 concatenation combiner (NIST SP 800-227 §4.3.1):

pub fn derive_hybrid_session_key(x25519_ss: &[u8; 32], ml_kem_ss: &[u8; 32]) -> [u8; 32] {
    let mut h = Sha3_256::new();
    h.update(x25519_ss);
    h.update(ml_kem_ss);
    h.update(b"cleitonq-hybrid-v1");  // domain separation
    h.finalize().into()
}

The rationale: secure as long as either component is pseudo-random (so a broken X25519 or a broken ML-KEM-1024 doesn't compromise the session key in isolation), and SHA3-256 as a random oracle gives this property.

The question: would you prefer HKDF-SHA3-256(salt=x25519_ss, ikm=ml_kem_ss, info=label) over the concatenation form here? HKDF has the extract-then-expand structure that seems designed for exactly this kind of multi-source key material, but SP 800-227 lists both as valid combiners for hybrid KEMs. Is there a reason to prefer one over the other when both inputs are fixed-length (32 bytes) and the output is used directly as a MAC key?

The relay finding (as context for the use case)

During testing I found something that might be worth noting for anyone else building authenticated protocols over MAVLink: any authentication material appended after a MAVLink v2 frame boundary — after the CRC — is silently stripped by any MAVLink-aware relay (MAVProxy, mavlink-router, QGC) during normal parse-and-forward. The relay reads exactly 10 + LEN + 2 bytes per spec and discards the rest.

This affects any signature scheme (classical or post-quantum) that uses the "append-after-frame" pattern. The fix is to carry authentication material as first-class MAVLink messages so relays treat them as valid but opaque frames. A GitHub Security Advisory (GHSA-f5rj-mrxh-r7vm) documents the class of affected schemes.

The reason I mention it: if anyone else is evaluating ml-kem or ml-dsa for similar protocol-level authenticated channels, this constraint shapes the wire format significantly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions