State of PQC

Protocol · TLS 1.3

TLS

Transport Layer Security protects the web, mail, DNS over HTTPS, VPNs built on it and most application traffic. This page explains how TLS 1.3 establishes keys and authenticates peers, which documents carry the post-quantum changes, where a pre-shared key enters the key schedule, how a connection can be pushed back to weaker algorithms, and what to check in an implementation. Each claim names the document and section it comes from. The companion page covers IPsec and IKEv2.

The protocol and its standards

TLS 1.3 is defined by RFC 9846, which obsoletes RFC 8446 and keeps the protocol unchanged while clarifying it. The post-quantum work adds algorithms to it through two extension points, the named group and the signature scheme, and leaves the handshake intact.

A TLS 1.3 connection has three parts. The handshake agrees the protocol version, the cipher suite, a shared secret and, usually, the server's identity. The key schedule turns the handshake's inputs into traffic keys. The record layer encrypts application data with those keys using an AEAD cipher. The post-quantum migration changes only the inputs to the key schedule and the signature in the handshake. The record layer's symmetric ciphers, AES-GCM and ChaCha20-Poly1305, are not affected beyond the general advice to prefer 256-bit keys.

Two extensions do the negotiation. supported_groups lists the key exchange groups the client accepts, and key_share carries a public value for some of them (RFC 9846 §4.3.7 and §4.3.8). signature_algorithms lists the signature schemes the client will verify (§4.3.3). A post-quantum algorithm is added by registering a new code point in the right registry. TLS 1.2 and earlier have no comparable extension point for a KEM and are not being migrated; RFC 9325 forbids TLS 1.0 and 1.1 and the IETF's post-quantum work targets TLS 1.3 only.

DocumentWhat it doesStatus
RFC 9846TLS 1.3. The handshake (§4), the key schedule (§7.1) and the asymmetric shared secret calculation (§7.4), now worded to cover KEMs as well as (EC)DHE.Standards Track, July 2026. Obsoletes RFC 8446.
RFC 9954Hybrid key exchange design: how two key exchanges are run as one named group, and how their shared secrets are combined.Informational.
RFC 10024The three hybrid groups X25519MLKEM768, SecP256r1MLKEM768 and SecP384r1MLKEM1024, with their code points, encodings and shared secret layout.Standards Track.
draft-ietf-tls-mlkemML-KEM-512, 768 and 1024 as standalone named groups.RFC Editor queue.
draft-ietf-tls-mldsaML-DSA-44, 65 and 87 as signature schemes for certificates and CertificateVerify.RFC Editor queue.
RFC 9257Guidance for external pre-shared keys: entropy, one client and one server per key, and the use cases, which name quantum resistance.Informational.
RFC 9973Certificate authentication combined with an external PSK, so that the PSK adds confidentiality without replacing the certificate.Standards Track. Obsoletes RFC 8773.
RFC 9325Recommendations for secure use of TLS and DTLS: versions, cipher suites and downgrade.Best Current Practice.

Every TLS record in the catalog, with its stage, is on the roadmap.

The handshake

One round trip. The client offers groups and key shares, the server picks one and returns its share, and everything after ServerHello is encrypted. Step through the exchange to see where a post-quantum KEM and a post-quantum signature enter. Use the buttons, the arrow keys, or play.

The TLS 1.3 handshake with a hybrid key share and a post-quantum signature Client Server ClientHello supported_groups · key_share: X25519MLKEM768 (ML-KEM ek ‖ X25519) · signature_algorithms: mldsa65, ecdsa… · pre_shared_key* HelloRetryRequest the server wants a group the client offered but sent no share for; the client repeats ClientHello with that share: one extra round trip ServerHello key_share: X25519MLKEM768 (ML-KEM ciphertext ‖ X25519 share) · pre_shared_key* · random (downgrade sentinel in the last 8 bytes) both sides hold the shared secret: Handshake Secret derived, every message below is encrypted {EncryptedExtensions · CertificateRequest* · Certificate · CertificateVerify · Finished} Certificate: the server's chain, ML-DSA or ECDSA/RSA keys · CertificateVerify: a signature over the whole transcript so far · Finished: a MAC over it {Certificate* · CertificateVerify* · Finished} the client's Finished covers everything both sides sent; a changed offer or a removed group breaks it [Application Data] [NewSessionTicket] a resumption PSK for the next connection, derived from this handshake's resumption_master_secret
  1. Two parties, one round trip. The client speaks first. Everything the client offers and everything the server chooses is recorded in the transcript, and both Finished messages are MACs over that transcript (RFC 9846 §4.5.3), which is what makes a downgrade detectable.
  2. ClientHello. The client lists the groups it accepts in supported_groups and sends a public value for some of them in key_share. For a hybrid group the value is the ML-KEM encapsulation key followed by the X25519 share, 1216 bytes for X25519MLKEM768 (RFC 10024 §4.1). It lists the signature schemes it can verify in signature_algorithms, and, when it has one, a PSK identity in pre_shared_key with the allowed modes in psk_key_exchange_modes (RFC 9846 §4.3.11 and §4.3.9).
  3. HelloRetryRequest. If the server supports a group the client listed but did not send a share for, it asks for that share and the client sends a second ClientHello. This costs a round trip, and it is the usual price of a client that prefers a classical group while the server prefers a hybrid one (RFC 9846 §4.2.4). Clients may send a share for more than one group to avoid it, at the cost of a larger ClientHello.
  4. ServerHello. The server picks one offered group and returns its share: for a hybrid group, the ML-KEM ciphertext it produced by encapsulating to the client's key, followed by its own X25519 share (RFC 10024 §4.1). The client decapsulates and both sides compute the shared secret, which for a hybrid group is the ML-KEM secret followed by the X25519 secret (§4.3). The key schedule turns it into the Handshake Secret, and every later message is encrypted. If a PSK was offered and accepted, the server's pre_shared_key names which one.
  5. Server authentication. The server sends its certificate chain and a CertificateVerify signature over the transcript so far, using a scheme from the client's list (RFC 9846 §4.5.2). This is where a post-quantum signature enters: ML-DSA code points 0x0904 to 0x0906 from draft-ietf-tls-mldsa, or a classical one. With a PSK the certificate messages are usually omitted and the PSK authenticates instead; RFC 9973 lets both be used together.
  6. Client Finished and application data. The client verifies the signature and the server's Finished, sends its own certificate if one was requested, and its Finished. Traffic keys for application data are derived from the Main Secret (RFC 9846 §7.1).
  7. Resumption. After the handshake the server may send NewSessionTicket. The ticket carries a PSK derived from this connection's resumption_master_secret, so the next connection can skip certificates. That PSK is only as strong as the handshake that produced it, which matters in the key schedule below.

Key establishment

The shared secret comes from a named group. Post-quantum groups come in two kinds: a hybrid of a classical curve and ML-KEM, which is deployed on most of the web today, and ML-KEM alone.

Hybrid groups, RFC 10024

A hybrid group runs two key exchanges inside one key_share entry and feeds both secrets to the key schedule as one value. RFC 9954 sets the design: fixed-length secrets concatenated and used as the key schedule's IKM, no extra round trips, and a KEM that is IND-CCA2 secure so that a reused encapsulation key cannot be attacked (RFC 9954 §3.3 and §6). RFC 10024 defines the groups:

GroupCode pointClient shareServer shareShared secret
X25519MLKEM7680x11EC (4588)ML-KEM ek ‖ X25519, 1216 BML-KEM ct ‖ X25519, 1120 BML-KEM ss ‖ X25519 ss, 64 B
SecP256r1MLKEM7680x11EB (4587)P-256 ‖ ML-KEM ek, 1249 BP-256 ‖ ML-KEM ct, 1153 BP-256 ss ‖ ML-KEM ss, 64 B
SecP384r1MLKEM10240x11ED (4589)P-384 ‖ ML-KEM ek, 1665 BP-384 ‖ ML-KEM ct, 1665 BP-384 ss ‖ ML-KEM ss, 80 B

The order differs: X25519MLKEM768 puts the ML-KEM part first, the NIST-curve groups put the curve first, for historical reasons the RFC records (§4.1). The earlier Kyber draft code points X25519Kyber768Draft00 (25497) and SecP256r1Kyber768Draft00 (25498) are obsoleted by RFC 10024 (§7.4) and their registry entries are marked not recommended. The client's ML-KEM share is a fresh key for each handshake; the RFC warns that encapsulation randomness is exposed if the random number generator is weak and points to SP 800-227 for KEM use (§6).

ML-KEM alone, draft-ietf-tls-mlkem

MLKEM512 (0x0200), MLKEM768 (0x0201) and MLKEM1024 (0x0202) are named groups that carry only the ML-KEM key and ciphertext. They are in the RFC Editor queue. A standalone group loses the fallback the hybrid provides if ML-KEM were found weak, which is why most deployments and RFC 9954 prefer the hybrid for now; CNSA 2.0's TLS profile requires MLKEM1024 be offered first and selected, with ML-KEM-1024 alone as the eventual target.

Size and round trips

A hybrid share adds about 1.2 kB to each of ClientHello and ServerHello. Over TCP this is a larger first flight; over DTLS and QUIC it can exceed one datagram and the handshake is fragmented or amplification-limited, which draft-ietf-uta-pqc-app discusses. A client that sends only an X25519 share to a server that prefers a hybrid pays a HelloRetryRequest. draft-ietf-tls-key-share-prediction lets DNS advertise a server's groups so the client can send the right share first, and draft-westerbaan-tls-keyshare-recommendations advises on which shares to send.

Authentication

TLS authenticates with a signature over the transcript, a certificate chain that binds the signing key to a name, or a pre-shared key. Only the signature and the chain need post-quantum replacements, and those are further behind than key establishment.

Signatures. CertificateVerify signs the transcript hash with the key in the end-entity certificate, using a scheme the client listed in signature_algorithms (RFC 9846 §4.5.2). draft-ietf-tls-mldsa adds mldsa44, mldsa65 and mldsa87 (0x0904 to 0x0906), in pure mode with an empty context string, and is in the RFC Editor queue. Drafts for FN-DSA and SLH-DSA exist but have not been adopted at the same pace. CNSA 2.0 names ML-DSA-87 as the only post-quantum signature for its TLS profile.

Certificates. A post-quantum CertificateVerify is only as strong as the chain above it. The certificate work lives in the LAMPS working group, and an ML-DSA leaf under an RSA root still rests on RSA. Chains also grow: an ML-DSA-65 signature is 3309 bytes and a public key 1952 bytes (FIPS 204, Table 2), so a chain with two intermediates adds roughly 15 kB to the server's first flight. draft-ietf-tls-trust-anchor-ids lets a client say which roots it trusts so the server can pick a shorter chain, and Merkle Tree Certificates aim to replace the chain with a short inclusion proof.

Hybrid authentication. Three approaches are in draft: composite ML-DSA signatures that bundle a classical and a post-quantum signature as one scheme (draft-ietf-tls-composite-mldsa), dual certificates where the server sends two chains and two CertificateVerify messages (draft-ietf-tls-dual-cert-auth), and KEM-based authentication where the server proves possession of a KEM key instead of signing (draft-ietf-tls-authkem). None has reached the RFC Editor.

Pre-shared keys. A PSK authenticates by the Finished MAC: only a holder of the key can compute it. RFC 9257 §4.1 says each external PSK should be known to exactly one client and one server, because a key shared more widely lets any holder impersonate any other. A PSK does not identify a party by name to anyone but its holders and gives no non-repudiation. RFC 9973 is for deployments that want both: the certificate identifies the server, the PSK adds confidentiality.

The key schedule, and where a PSK enters

RFC 9846 §7.1 derives every key from three inputs in a fixed order: the PSK, the asymmetric shared secret, and zeros. A key delivered by QKD, or provisioned by hand, enters as an external PSK at the top. Step through the derivation, then through what a quantum attacker can and cannot recover.

The TLS 1.3 key schedule showing the PSK, the hybrid shared secret and the derived secrets PSK external (provisioned or QKD), resumption, none no PSK: zeros of Hash.length external PSK, ≥ 128 bits of entropy resumption PSK (NewSessionTicket) 0 (salt) HKDF-Extract = Early Secret binder_key client_early_traffic_secret Derive-Secret(·, "derived", "") asymmetric shared secret ML-KEM ss (32 B) ‖ X25519 ss (32 B) psk_ke mode: zeros instead HKDF-Extract = Handshake Secret client_handshake_traffic_secret server_handshake_traffic_secret Derive-Secret(·, "derived", "") 0 (IKM) HKDF-Extract = Main Secret client_application_traffic_secret_0 server_application_traffic_secret_0 exporter_secret resumption_master_secret NewSessionTicket: the PSK for the next connection quantum attacker recovers X25519 ss Hybrid group, no PSK: the ML-KEM half of the shared secret is unknown, so the Handshake Secret and all below it are safe. Classical group, no PSK: Early Secret is public, the shared secret is recovered, every key follows from the recording. External PSK, psk_dhe_ke: Early Secret depends on the PSK, so the Handshake Secret is unknown even given the (EC)DHE secret. The key exchange still gives forward secrecy if the PSK later leaks (RFC 9257 §6). With a certificate as well, use RFC 9973. Resumption PSK: derived from the previous connection's Main Secret. If that handshake was classical with no external PSK, the ticket's PSK follows from that recording, and this connection with it. Resumption adds nothing the first handshake lacked.
  1. Three inputs. The schedule is a chain of HKDF-Extract calls. Each takes a salt from the step above and an input keying material from the left: first the PSK, then the asymmetric shared secret, then zeros (RFC 9846 §7.1). An input that is absent is replaced by a string of zero bytes of the hash length, so the chain always has the same shape.
  2. Early Secret = HKDF-Extract(0, PSK). The PSK is the first IKM. An external PSK is one the two sides were provisioned with, by any means including a QKD link; a resumption PSK came from a previous connection (§4.3.11). The binder key, which proves the client holds the PSK, and the early-data key are derived here.
  3. Derived. A Derive-Secret step with the label "derived" turns the Early Secret into the salt for the next extract. A secret that an attacker cannot compute here stays unknown for the rest of the chain, whatever the next input is.
  4. Handshake Secret = HKDF-Extract(derived, shared secret). The asymmetric shared secret is the IKM. For X25519MLKEM768 it is the 32-byte ML-KEM secret followed by the 32-byte X25519 secret (RFC 10024 §4.3); the two halves are not combined any further, the extract does that. In psk_ke mode there is no key exchange and zeros are used (RFC 9846 §7.1).
  5. Handshake traffic secrets. Client and server handshake traffic secrets encrypt everything after ServerHello, including the certificates.
  6. Main Secret = HKDF-Extract(derived, 0). The last extract takes zeros. Application traffic secrets, the exporter secret and the resumption_master_secret are derived from it. RFC 9846 renames this the Main Secret and keeps the "master" labels for compatibility.
  7. Resumption. The resumption_master_secret feeds the PSK in a NewSessionTicket, which becomes the next connection's Early Secret input. The loop is why a resumption PSK carries forward whatever protection the first handshake had, and no more.
  8. A quantum attacker recovers the classical half. Assume a recording of the handshake and a computer that solves the X25519 discrete logarithm. With a hybrid group, the ML-KEM secret is still unknown, so the Handshake Secret is safe. With a classical group and no PSK, every secret in the chain is computable from the recording.
  9. An external PSK is sufficient. If the PSK has at least 128 bits of entropy (RFC 9257 §6), the Early Secret and its "derived" salt are unknown to the attacker, and so is the Handshake Secret even with the whole (EC)DHE secret in hand. This holds in psk_dhe_ke mode, where the key exchange still runs, and in psk_ke mode, where it does not; RFC 9257 §6 asks for psk_dhe_ke so that a later PSK compromise does not expose past traffic. It protects confidentiality, not identity: the PSK authenticates only to its holders.
  10. A resumption PSK is not. It is derived from the previous Main Secret. If that connection used a classical group and no external PSK, the attacker derives the ticket's PSK from the first recording and the resumed connection with it. Protection has to be present in the full handshake.
What a PSK buys in TLS 1.3. An external PSK with at least 128 bits of entropy, known to one client and one server, makes every traffic key of the connection depend on a value a quantum computer cannot recover from the recording, whichever key exchange ran. A QKD-delivered key used this way gives the same result. It must be an external PSK, not a resumption ticket, and it authenticates the peer only as "a holder of this key"; for a named identity, combine it with a certificate as RFC 9973 specifies, in psk_dhe_ke mode.
What it does not buy. The handshake's signature stays classical unless ML-DSA is used, so an active attacker with a quantum computer could still forge a certificate for a server that has no PSK with the client; with a PSK the attacker cannot complete the handshake, because the binder and Finished need the key. A PSK shared by more than two parties lets any holder impersonate the others (RFC 9257 §4.1). And the PSK has to reach both ends by some other channel; neither TLS nor the RFCs say how.

Downgrade

A downgrade is a connection that ends up using weaker algorithms than both sides support. TLS 1.3 detects most of them cryptographically; the cases to worry about are the ones that happen inside the rules.

  • Inside TLS 1.3, tampering is caught. Both Finished MACs cover the full transcript, so an attacker who removes the hybrid group from ClientHello or alters ServerHello produces a handshake that fails at Finished (RFC 9846 §4.5.3). The attacker can make the connection fail, not make it weaker.
  • Version downgrade is caught by the sentinel. A TLS 1.3 server that negotiates TLS 1.2 sets the last eight bytes of ServerHello.random to 44 4F 57 4E 47 52 44 01, and a 1.3 client that sees them aborts (RFC 9846 §4.2.3). TLS 1.2 has no post-quantum key exchange, so this is the version boundary that matters.
  • Negotiation is the server's choice. If the client offers both a hybrid and a classical group, the server picks. A server that prefers X25519 over X25519MLKEM768 is not attacked, it is misconfigured, and the handshake is valid. The same holds for signature schemes. Policy, not the protocol, decides whether a classical choice is acceptable.
  • Fallback outside the protocol. Some clients retry with a smaller ClientHello when a connection fails, for example when a middlebox drops a handshake over a certain size. A retry that drops the hybrid share is a downgrade the transcript cannot see because it is a new handshake. RFC 9954 §1.4 lists the compatibility cases in which a hybrid-aware side may be willing to downgrade, and RFC 9325 §3.1.3 forbids falling back to a version below TLS 1.2.
  • PSK modes. A server that selects psk_ke when the client also offered psk_dhe_ke gives up forward secrecy. RFC 9973 requires psk_dhe_ke for its initial handshake. A client that offers only psk_dhe_ke cannot be moved to psk_ke.

What to test

A packet capture of the handshake and the implementation's key log are enough for most of these. The named group and the signature scheme are visible in ClientHello and ServerHello; the certificates are visible once the handshake keys are known.

  • Which group was selected. Read ServerHello's key_share group. Expect 0x11EC, 0x11EB or 0x11ED for a hybrid, 0x0200 to 0x0202 for ML-KEM alone. Check that the obsoleted Kyber draft code points 25497 and 25498 are neither offered nor accepted.
  • Share layout. Check the client share length, 1216 bytes for X25519MLKEM768, and the server share, 1120 bytes. A wrong order of the two halves gives a handshake that fails against a correct peer; test against an independent implementation, not only the same library on both sides.
  • Preference order. Offer a hybrid and a classical group and confirm the server selects the hybrid. Offer only a classical share for a hybrid-preferring server and confirm a HelloRetryRequest, not a silent classical choice, if policy requires post-quantum.
  • Policy under failure. Make the hybrid handshake fail, for instance by dropping large records, and confirm the client does not retry with a classical-only offer.
  • Signature scheme. With the key log, decrypt CertificateVerify and confirm the scheme, 0x0904 to 0x0906 for ML-DSA, and that the chain is post-quantum to the root if that is the requirement.
  • Fresh keys. Capture two handshakes and confirm the ML-KEM encapsulation key differs. A reused key is a bug and a forward-secrecy loss.
  • PSK handling. With an external PSK, confirm the server selects psk_dhe_ke, that the PSK is at least 128 bits, that a wrong PSK fails at the binder, and that resumption tickets are not treated as equivalent to the external key by policy.
  • Versions. Confirm TLS 1.0 and 1.1 are refused and that a forced TLS 1.2 negotiation shows the downgrade sentinel in ServerHello.random.
  • Size behaviour. For DTLS and QUIC, confirm the first flight fragments and reassembles correctly with a hybrid share and an ML-DSA chain, and that amplification limits do not stall the handshake.
  • Randomness. Confirm the ML-KEM key generation and encapsulation draw from the system's approved random source; RFC 10024 §6 explains why.

Sources

Section numbers in the text refer to these documents.

Published

  • RFC 9846 The Transport Layer Security (TLS) Protocol Version 1.3obsoletes RFC 8446
  • RFC 9954 Hybrid Key Exchange in TLS 1.3
  • RFC 10024 Post-Quantum Traditional (PQ/T) Hybrid Key Agreement Mechanisms for TLS 1.3
  • RFC 9257 Guidance for External Pre-Shared Key (PSK) Usage in TLS
  • RFC 9973 TLS 1.3 Extension for Using Certificates with an External Pre-Shared Keyobsoletes RFC 8773
  • RFC 9325 Recommendations for Secure Use of TLS and DTLS

In progress