Hi Nick, Some comments:
- The distinction between passive and active adversaries is correct, but is it useful to make that distinction in this context? In some cases, it may be difficult to protect against active attackers, and one may need to settle for a passive security goal. In this case, however, I think we should aim to protect against both. - I do not think focusing on algorithms is the right approach for the IETF. We should consider all protocol fields that reveal randomness. Even when considering algorithms, modern RSA algorithms, as well as encryption schemes used for key transport, reveal randomness. - Regarding the statement: "For a Dual_EC-shape DRBG a single 32-byte m is enough. Other state-recoverable constructions may require more.” An attacker who knows the initial state of a deterministic DRBG typically needs much less than this to recover future outputs. Cheers, John Preuß Mattsson From: Nick Sullivan <[email protected]> Date: Monday, 13 July 2026 at 11:59 To: [email protected] <[email protected]> Subject: [TLS] RNG state should not cascade across TLS connections Hi TLSWG, Pulling this up from a deep subthread so it doesn't get lost. There are two distinct attacks against a state-recoverable DRBG worth naming separately. Both work the same way: one exposure of RNG output lets the attacker walk state forward and predict every subsequent draw from the same DRBG. Scenario 1: passive eavesdropper. Recovery vector is a wire nonce like ServerHello.Random. Applies to both KEMs and DH. Scenario 2: adversary client. Recovery vector is `m`, which the adversary recovers by decapsulating the server's ciphertext. Applies to KEMs only, not to DH. Scenario 2 applies to KEMs but not DH because the FO transform requires the decapsulator to recover the encapsulator's `m`. DH's peer sees only `a·G` behind ECDLP. No raw randomness ever crosses. This is a KEM-abstraction property, not ML-KEM-specific. The attacker in Scenario 2 needs to make enough connections to your server to accumulate the `m` values needed to recover DRBG state. For a Dual_EC-shape DRBG a single 32-byte `m` is enough. Other state-recoverable constructions may require more. What both scenarios share: once DRBG state is recovered, the attacker passively decrypts every subsequent connection to that server from just the network flow. Every user, every session, decrypted from the wire without touching the server again. This continues until the DRBG reseeds. For a stack that does not explicitly reseed, that means for the life of the process. Predicted `m` plus observed `ek` gives the KEM shared secret directly. This is the mechanism behind the 2015 Juniper ScreenOS Dual_EC incident, which put passive VPN decryption within reach of whoever held the trapdoor to the substituted Q constant. Nothing about ML-KEM makes it immune to the same mechanism. That cascade is the actual concern. How the server arranges its DRBGs determines which scenario the attacker would take. Under a shared DRBG (ServerHello.Random and `m` from the same source), Scenario 1 is available to any passive observer without an active connection. This is Ben Kaduk's point. Splitting the DRBGs closes Scenario 1 but leaves Scenario 2 as the primary path against the DRBG that feeds `m`. David Benjamin has argued that the fix belongs at the RNG layer, not at ML-KEM or inside TLS. That seems right. Use a DRBG whose output does not reveal its state (duh), and which provides post-compromise recovery (via reseeding from fresh entropy by design, or via per-connection reinitialization at the caller). Either way, any state exposure is bounded in time. This approach is KEM-generic and applies beyond ML-KEM. Runnable PoCs for both scenarios are trivial to construct. Let me know if I have this summary right. Nick
_______________________________________________ TLS mailing list -- [email protected] To unsubscribe send an email to [email protected]
