Hi John,
On 7/10/26 23:31, John Mattsson wrote:
Hi Nico,
Suppose the RNG outputs 32 byte outputs where the first 40 bits
are an index that can be used by the attacker to recover the
remaining 216 bits when the attacker also knows part of a seed for
the RNG. In this case the attacker must see those 40 bits in
order to recover the remaining 216 bits, but hashing means they
will not see them and will have too- large a work factor to
recover the original `m`.
This seems like an excellent description of how hashing could help
when applied to ServerHello.random. However, the server_share does
not contain m; it contains only the ciphertext c (or c || K_B in the
case of X25519MLKEM768). Therefore, I do not see how the additional
step m ← SHA3-256(m) would help, even with a static ek, and even
less so with the ephemeral ek used in TLS. It is also worth noting
that, in ML-KEM, m is hashed before it is used. The difference
compared to Kyber is that ML-KEM does not hash m twice.
The answer is that the client recovers m from the server because they
get to pick their own ML-KEM.Decaps() and they control their own ML-KEM
secret key. FIPS 203 says they do not hash the system random value and
if your system random value is produced by Dual_EC_DRBG, it is game over
in many circumstances. TLS compounds the matter and turns that into an
oracle. This isn't even news, it's what was discussed on the pqc-forum
three years ago.
Kind regards,
Jacob Appelbaum
Cheers, John Preuß Mattsson
From: Nico Williams <[email protected]> Date: Friday, 10 July
2026 at 20:55 To: John Mattsson <[email protected]> Cc:
Jacob Appelbaum <[email protected]>; [email protected]
<[email protected]>; Tanja Lange <[email protected]>;
[email protected] <[email protected]> Subject: Re: [TLS] Re: WG Last Call:
draft-ietf-tls-mlkem-08 (Ends 2026-07-08)
On Fri, Jul 10, 2026 at 11:07:45AM +0000, John Mattsson wrote:
Could you provide a detailed technical explanation of how an
attacker controlling the RNG could break ML-KEM but not Kyber with
the m �� H(m) step?
Suppose the RNG outputs 32 byte outputs where the first 40 bits are
an index that can be used by the attacker to recover the remaining
216 bits when the attacker also knows part of a seed for the RNG.
In this case the attacker must see those 40 bits in order to recover
the remaining 216 bits, but hashing means they will not see them and
will have too- large a work factor to recover the original `m`.
However, as noted, the nonces too need to be hashed RNG outputs to
defeat such an attack.
Of course the attacker could just provide the victim with an RNG
where the attacker just knows the seed and only needs to know the
index of RNG outputs corresponding to `m`. In this case the
attacker would only have to brute-force a small index, and now
hashing `m` does nothing to protect the victim.
So in a way hashing `m` adds no value because if the attacker knows
you'll be hashing `m`: since we're talking about an attacker that
can convince you to use their RNG they can just make you use one
where hashing `m` achieves nothing.
But it might be more difficult to switch out the RNG at this late a
stage. On that basis one might recommend some application level
whitening of RNG outputs: on the off chance that the attacker was in
fact counting on the use of raw RNG outputs for `m` [and nonces].
3. It may be too late now, but I strongly believe RFC8446bis
should recommend the use of multiple independent entropy sources
to mitigate both accidental failures and intentional weaknesses.
RFC 8937 is one way to achieve this, but it is neither the only
approach nor necessarily the best one. Many operating systems
already combine multiple entropy sources, including keyboard and
mouse interrupts, USB events, network and storage timing,
scheduler timing, CPU hardware RNGs, TPM RNGs, EFI RNGs, and CPU
jitter.
Indeed. Even further, apps should do this too on top of what the OS
does.
Nico --
_______________________________________________
TLS mailing list -- [email protected]
To unsubscribe send an email to [email protected]