REALITY: P256/P384 server-side KEX + HelloRetryRequest support (evaluate whether it's worth it) #84

Open
opened 2026-07-17 21:53:23 +00:00 by vxfemboy · 0 comments
vxfemboy commented 2026-07-17 21:53:23 +00:00 (Migrated from github.com)

Summary

REALITY.5b (server-side ServerHello emission, in progress) implements server-side key exchange for X25519MLKEM768 (4588) + X25519 (29) only. This issue tracks the deferred, larger question of supporting P256 (23) + P384 (24) server-side — which requires HelloRetryRequest (HRR) handling — and whether it is worth doing at all.

Why P256/P384 are hard here (the HRR problem)

Our client (like real Chrome 150) sends TLS 1.3 key_shares only for its top two groupsX25519MLKEM768 and X25519 — while offering P256/P384 in supported_groups without a key_share (see crates/yip-utls/src/hello.rs::key_share_body). Under RFC 8446, a server that wants to use a group for which the client sent no key_share must send a HelloRetryRequest, asking the client to resend its ClientHello with that group's key_share (a full extra round trip).

So for the REALITY relay to byte-match a dest that selects P256/P384, we'd need HRR support in two places:

  1. capture_dest_flight (REALITY.5a, already shipped) — it currently assumes a 1-RTT handshake and would misparse a dest that HRRs. Supporting P256/P384 means reopening 5a to handle the HRR round trip during capture.
  2. 5b/5c/5d emission — the relay would have to emit its own HRR and then process the client's re-sent ClientHello — a whole additional flight in both directions.

By contrast, 4588 and X25519 need no HRR (the client sent those key_shares), so they're a clean 1-RTT path.

Why it's probably not worth it (the "evaluate" part)

A modern TLS 1.3 server facing a Chrome ClientHello that offers X25519MLKEM768 (post-quantum hybrid) + X25519 overwhelmingly selects one of those — it does not fall back to plain P256/P384 ECDHE for the key exchange. So a dest that would trigger HRR for a Chrome hello is rare (old/misconfigured servers). Before building HRR (a substantial addition spanning capture + emission), we should gather evidence: probe a broad set of realistic --reality-dest candidates and measure how many actually select P256/P384 (i.e. would HRR). If ~none do, this stays wontfix.

Interim behavior (REALITY.5b/c/d)

An SNI whose dest selects a group outside {4588, 29} degrades to splice-only (the existing per-SNI degrade path) — fail-safe, no fidelity claim for that SNI, no HRR needed.

References

  • crates/yip-utls/src/hello.rs (key_share_body — key_shares for 4588 + X25519 only)
  • REALITY.5b spec (server-side ServerHello emission)
  • Milestone spec: docs/superpowers/specs/2026-07-15-reality-tls-milestone-design.md
  • Surfaced during REALITY.5b design.
## Summary REALITY.5b (server-side ServerHello emission, in progress) implements server-side key exchange for **X25519MLKEM768 (4588) + X25519 (29)** only. This issue tracks the deferred, larger question of supporting **P256 (23) + P384 (24)** server-side — which requires **HelloRetryRequest (HRR)** handling — and **whether it is worth doing at all**. ## Why P256/P384 are hard here (the HRR problem) Our client (like real Chrome 150) sends TLS 1.3 **key_shares only for its top two groups** — `X25519MLKEM768` and `X25519` — while *offering* P256/P384 in `supported_groups` **without** a key_share (see `crates/yip-utls/src/hello.rs::key_share_body`). Under RFC 8446, a server that wants to use a group for which the client sent **no** key_share **must** send a **HelloRetryRequest**, asking the client to resend its ClientHello with that group's key_share (a full extra round trip). So for the REALITY relay to byte-match a dest that selects P256/P384, we'd need HRR support in **two** places: 1. **`capture_dest_flight` (REALITY.5a, already shipped)** — it currently assumes a 1-RTT handshake and would misparse a dest that HRRs. Supporting P256/P384 means **reopening 5a** to handle the HRR round trip during capture. 2. **5b/5c/5d emission** — the relay would have to emit its own HRR and then process the client's re-sent ClientHello — a whole additional flight in both directions. By contrast, 4588 and X25519 need **no** HRR (the client sent those key_shares), so they're a clean 1-RTT path. ## Why it's probably not worth it (the "evaluate" part) A modern TLS 1.3 server facing a Chrome ClientHello that offers `X25519MLKEM768` (post-quantum hybrid) + `X25519` **overwhelmingly selects one of those** — it does not fall back to plain P256/P384 ECDHE for the key exchange. So a dest that would trigger HRR for a Chrome hello is rare (old/misconfigured servers). Before building HRR (a substantial addition spanning capture + emission), we should **gather evidence**: probe a broad set of realistic `--reality-dest` candidates and measure how many actually select P256/P384 (i.e. would HRR). If ~none do, this stays wontfix. ## Interim behavior (REALITY.5b/c/d) An SNI whose `dest` selects a group outside {4588, 29} **degrades to splice-only** (the existing per-SNI degrade path) — fail-safe, no fidelity claim for that SNI, no HRR needed. ## References - `crates/yip-utls/src/hello.rs` (`key_share_body` — key_shares for 4588 + X25519 only) - REALITY.5b spec (server-side ServerHello emission) - Milestone spec: `docs/superpowers/specs/2026-07-15-reality-tls-milestone-design.md` - Surfaced during REALITY.5b design.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
femboy/yip#84
No description provided.