Why the last hop matters

Quantum computers threaten the long-term confidentiality of Internet traffic: anything encrypted today can be recorded and decrypted later once a sufficiently powerful quantum machine exists. Post-quantum cryptography (PQC) is designed to close that window. After NIST selected Kyber as its post-quantum key agreement standard in July 2022, the deployment burden shifted to industry. Cloudflare now covers the client-to-Cloudflare leg with X25519+Kyber, and is rolling out the same protection for the connection between Cloudflare and origin servers.

That last hop matters because Cloudflare acts as a reverse proxy. A visitor's request travels from browser to Cloudflare (already protected with post-quantum key agreement as of October 2022), then across Cloudflare's internal network (upgrades targeted for completion by end of 2024), and finally to the origin server. That final link has been the unprotected segment — until now. Cloudflare is rolling out support for X25519+Kyber for most outbound connections, including origin servers and Cloudflare Workers fetch() calls.

The rollout is gradual, but you can skip ahead. Enterprise customers can opt in their zone today via API; a dashboard toggle for opting out will be added before the February 2024 enterprise rollout.

Quick start: enable it on your origin

To opt in a zone and skip the gradual rollout:

curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "preferred"}'

After opting in, your server must support TLS 1.3 with the X25519Kyber768Draft00 key agreement enabled and preferred, and be configured with server cipher preference. For nginx compiled with a recent BoringSSL:

	http {
		# [...]
		ssl_ecdh_curve X25519Kyber768Draft00:X25519;
		ssl_prefer_server_ciphers on;
		ssl_protocols TLSv1.3;
	}

Verify the configuration with the BoringSSL bssl tool:

	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]

A successful post-quantum connection shows X25519Kyber768Draft00 rather than plain X25519. More client and server support details are at pq.cloudflareresearch.com.

How TLS 1.3 handles the transition

Understanding why this upgrade is smooth — and where it can break — requires a look at the TLS 1.3 handshake. The client opens with a ClientHello, including the hostname and the key agreement methods it supports. To save a round trip, the client guesses what the server supports and sends one or more client keyshares along with that hello.

Protocol flow for server-authenticated TLS 1.3 with a supported client keyshare on the left and a HelloRetryRequest on the right.

If the guess is right, the server derives the shared key from the client keyshare and replies with its own server keyshare. If the guess is wrong, the server sends a HelloRetryRequest (HRR) asking for a keyshare of a method the client advertised. The server can also send an HRR even when the client guessed correctly, if it prefers a different advertised algorithm.

HRRs are undesirable — they re-introduce the extra round trip that TLS 1.3 was designed to eliminate. Browsers previously mitigated this during the P-256 to X25519 transition by sending both keyshares. Chrome does the same today, sending both X25519 and X25519+Kyber to avoid HRRs. That works, but costs extra computation and wire space. With larger post-quantum keyshares, sending duplicates becomes more expensive, which is why Cloudflare's approach is deliberately careful about when it offers what.

What X25519Kyber768Draft00 actually is

The post-quantum key agreement Cloudflare enables is formally X25519Kyber768Draft00, the industry's early-deployment hybrid. It combines X25519 with a preliminary version of NIST's Kyber selection. Kyber isn't fully standardized yet — NIST has published a draft standard (to be named ML-KEM) and is soliciting public input. The final standard may shift slightly, but no radical changes to security or performance are expected. When ML-KEM lands in 2024, Cloudflare will adopt the corresponding hybrid and deprecate X25519Kyber768Draft00, announcing the timeline on this blog and pq.cloudflareresearch.com.

Cloudflare's inbound connections initially enabled hybrids with both Kyber512 and Kyber768. Those target different security levels: Kyber512 matches AES-128, and Kyber768 matches AES-192. Despite popular claims, AES-128 is not practically broken by quantum computers. Kyber768's wider security margin reflects the designers' comfort level, and Cloudflare follows their recommendation.

Why hybrid

Kyber's hybrid nature is a cautionary measure. Several schemes — Rainbow, GeMMS, and SIDH — survived public review rounds before being broken. Those cases had caveats: SIDH carried significant mathematical attack surface, and niche schemes receive far less cryptanalytic scrutiny than high-profile targets. Kyber is the opposite: it is the prize, and breaking it would bring fame. Even so, combining it with X25519 means that if Kyber were ever broken, connections would still retain the classical security of X25519.

Performance cost

Kyber's computational cost is minimal — it beats X25519, itself already very fast.

    Size keyshares(in bytes) Ops/sec (higher is better)
Algorithm PQ Client Server Client Server
X25519 32 32 17,000 17,000
Kyber768 1,184 1,088 31,000 70,000
X25519Kyber768Draft00 1,216 1,120 11,000 14,000

The combined X25519Kyber768Draft00 is slower than X25519 alone, but the real cost is size. The client's first message carries 1,184 extra bytes for Kyber. That overhead is what drives the careful rollout strategy: Cloudflare must avoid breaking connections to origins that don't yet speak the hybrid, and the larger keyshares make missteps costly.

Why split ClientHello is a problem

In TLS, the ClientHello is usually the first message a client sends when establishing a connection. With the X25519 key exchange, that message fits comfortably in a single network packet. Add Kyber, and it no longer does: the ClientHello must span two packets. TLS allows this, but split ClientHellos were historically so rare that plenty of software and hardware silently assumes they never occur.

That assumption is a form of protocol ossification, and it is the central obstacle to deploying post-quantum key agreement. Cloudflare's earlier post-quantum experiments in 2019 found middleboxes from one vendor dropping connections with split ClientHellos. Chrome has been gradually ramping up post-quantum connections to surface these issues early; most vendors fix them quickly once reported, but Cloudflare cannot rely on browser ramps to find every bug. For outbound connections to origin servers, Cloudflare is often the only client talking to that server, so it must proceed more carefully.

Using HelloRetryRequest to stay safe

Instead of sending a full post-quantum keyshare in the first ClientHello, Cloudflare now advertises support for X25519+Kyber while also sending a classical X25519 keyshare. If the origin does not support the hybrid scheme, the connection proceeds as before. Advertising an unsupported keyshare is safe thanks to GREASE, the mechanism browsers use to send unpredictable codepoints so that no implementation can get away with failing on unknown values.

If the origin does support X25519+Kyber, it responds with a HelloRetryRequest, prompting Cloudflare to send a second ClientHello containing the post-quantum keyshare. This adds a roundtrip, but it means the extra-large ClientHello only appears when the origin has explicitly indicated support. Even then, a broken middlebox or server could fail on the second ClientHello. The HRR approach does not fix every broken implementation; it simply ensures those failures do not block post-quantum adoption for the majority of connections that work correctly.

Debugging failures

When a post-quantum connection fails, the first task is identifying which component is at fault. The problem is rarely the origin server alone; load balancers and routers can also interfere. Cloudflare has seen failures caused by servers reserving only a small buffer for the ClientHello, assuming it would fit in roughly 1000 bytes. Another common variant is a server that reads the ClientHello with a single recv() call, which works for a single-packet ClientHello but misses data when the message is split.

Not all issues involve split ClientHello. For example, servers using the Rust TLS library rustls before version 0.21.7 did not correctly implement HelloRetryRequest, causing failures unrelated to packet size.

Configuration options

Cloudflare offers three settings for outbound post-quantum connections. These settings apply to every outbound connection for a zone, including Workers fetch() requests.

Setting Meaning
supported Advertise support for post-quantum key agreement, but send a classical keyshare in the first ClientHello.When the origin supports and prefers X25519+Kyber, a post-quantum connection will be established, but it incurs an extra roundtrip.This is the most compatible way to enable post-quantum.
preferred Send a post-quantum keyshare in the first ClientHello.When the origin supports X25519+Kyber, a post-quantum connection will be established without an extra roundtrip. We continue advertising support for classical keyshares as well, so that origins that do not support X25519+Kyber will continue to function. This is the most performant way to enable post-quantum.
off Do not send or advertise support for post-quantum key agreement to the origin.
(default) Allow us to determine the best behavior for your zone. (More about that later.)

The setting is managed through the API:

curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "(setting)"}'

Parameters:

Parameter Value
setting supported, preferred, or off, with meaning as described above
zone_id Identifier of the zone to control. You can look up the zone_id in the dashboard.
API token Token used to authenticate you. You can create one in the dashboard. Use create custom token and under permissions select zone → zone settings → edit.

Verifying origin support

In preferred mode, verify that the origin supports the correct post-quantum key agreement using the bssl tool from BoringSSL:

	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]

In supported mode, or during gradual rollout, the origin must prefer post-quantum key agreement even when the initial ClientHello contained only a classical keyshare. Cloudflare's BoringSSL fork provides a tool for this check:

	$ git clone https://github.com/cloudflare/boringssl-pq
	[...]
	$ cd boringssl-pq && cmake -B build && make -C build
$ build/bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00 -disable-second-keyshare
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]

Scanning origins to remove the extra roundtrip

The HelloRetryRequest approach safely advertises post-quantum support, but costs an extra roundtrip for origins that support it. The preferred setting eliminates that roundtrip by sending the hybrid keyshare immediately, but requires manual configuration. Cloudflare is working toward a setting that requires no intervention at all.

Cloudflare now scans all active origins roughly every 24 hours, running about ten TLS connections per origin to test support for different key agreements and preferences. Preliminary data shows that 0.5% of origins support post-quantum connections. A small fraction (<0.34%) fail to establish a connection when a post-quantum keyshare is sent in the first ClientHello. Notably, most of those failures occur after the origin returns a HelloRetryRequest: the origin fails when it receives the second ClientHello containing a classical keyshare. The causes are under investigation, and Cloudflare is contacting vendors to address them.

Later this year, these scan results will determine the default setting for zones that have not been configured explicitly. Origins that reliably support post-quantum key agreement will receive a hybrid keyshare directly, avoiding the HelloRetryRequest roundtrip.

The scanner has a second benefit. By default Cloudflare sends X25519, but roughly 4% of origins do not support or prefer it and instead respond with a HelloRetryRequest requesting another group such as P-384.

Key agreement Fraction supported Fraction preferred
X25519 96% 96%
P-256 97% 0.6%
P-384 89% 2.3%
P-521 82% 0.1%
X25519Kyber768Draft00 0.5% 0.5%

The scan results will also let Cloudflare send the keyshare the origin prefers on the first attempt, removing that roundtrip for non-post-quantum connections as well.

Rolling forward

To address the store-now/decrypt-later threat, post-quantum cryptography must reach every encrypted connection, including those between Cloudflare and origin servers. Cloudflare invites origin operators to enable post-quantum key agreement and share their experiences or report issues via [email protected]. Deployment status and client/server support information is available at pq.cloudflareresearch.com.