Add OuterExtensions encoding for TLS ECH client#10306
Open
sebastian-carpenter wants to merge 4 commits intowolfSSL:masterfrom
Open
Add OuterExtensions encoding for TLS ECH client#10306sebastian-carpenter wants to merge 4 commits intowolfSSL:masterfrom
sebastian-carpenter wants to merge 4 commits intowolfSSL:masterfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds client-side ECH ech_outer_extensions encoding support (RFC 9849 §5.1) to shrink the sealed ClientHelloInner, with new APIs to enable/disable at CTX/SSL scope and CI interop updates.
Changes:
- Implement OuterExtensions encoding/expansion in the TLS extensions write/size paths and ClientHelloInner hashing/sealing.
- Add CTX/SSL options + public setters to opt out of the encoding (enabled by default).
- Extend CI OpenSSL ECH interop to run with an ML-KEM hybrid group and new
--pqcplumbing.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| wolfssl/ssl.h | Exposes new public APIs to toggle ECH OuterExtensions encoding. |
| wolfssl/internal.h | Adds new ECH/writeEncoded flag and CTX/SSL option bits for encoding control. |
| src/ssl_ech.c | Implements the new CTX/SSL setters controlling the encoding behavior. |
| src/internal.c | Propagates CTX encoding-disable setting into per-SSL options at init. |
| src/tls.c | Adds OuterExtensions encoding selection and fixes expansion length rewrite for session-id cases. |
| src/tls13.c | Separates “expanded” vs “encoded” inner sizes and hashes expanded form before sealing encoded form. |
| tests/api.c | Adds coverage for disabling encoding via CTX and SSL APIs. |
| .github/workflows/openssl-ech.yml | Enables ML-KEM and runs OpenSSL↔wolfSSL interop using a PQC hybrid group. |
| .github/scripts/openssl-ech.sh | Adds --pqc CLI support and forwards it to the wolfSSL client. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds client-side ECH
ech_outer_extensionsencoding (RFC 9849 §5.1). The inner ClientHello now encodes duplicate extensions so they can be expanded on the server-side later. This can shrink the HPKE-sealed payload significantly.Enabled by default. Opt-out:
wolfSSL_CTX_SetEchEncodeOE(ctx, enable)wolfSSL_SetEchEncodeOE(ssl, enable)Changes
TLSX_ECH_IsEncodeable— gate list of non-compressible extensions (SNI, ECH, ALPN, PSK, early_data).TLSX_ECH_BuildOuterExtensions— walksssl->extensionsthenssl->ctx->extensionsand emits theech_outer_extensionsblock. Capped at 127 extensions.TLSX_GetSizeWithEch/TLSX_WriteWithEch— size and write the encoded inner as[ech_outer_extensions][non-encodables](what is sent on the wire), and the expanded inner as[encodables][non-encodables](what is hashed for the transcript).TLSX_ECH_ExpandOuterExtensions— fix extension-length rewrite when the outer carries a session id.SendTls13ClientHello— computes both inner sizes, hashes the expanded form viaEchHashHelloInner, then rewrites the buffer in encoded form for HPKE seal.ech->innerCountis set explicitly afterTLSX_FinalizeEchrather than as a side effect of hashing.EchHashHelloInner— always receives the expanded body; no longer stripspaddingLen + Nt.Options.disableEchEncodeOE/WOLFSSL_CTX.disableEchEncodeOEplusWOLFSSL_ECH.writeEncodedflag to select expanded vs. encoded within a singleTLSX_WriteRequestpath.openssl-ech.sh/openssl-ech.yml) — adds--pqcargument and runs withSecP384r1MLKEM1024so the inner exceeds openssl's ECH limit (if OuterExtensions was not used).Testing
test_wolfSSL_Tls13_ECH_outer_extensionscovers CTX- and SSL-level disable.Checklist