rfc9849v1.txt   rfc9849.txt 
Internet Engineering Task Force (IETF) E. Rescorla Internet Engineering Task Force (IETF) E. Rescorla
Request for Comments: 9849 Independent Request for Comments: 9849 Independent
Category: Standards Track K. Oku Category: Standards Track K. Oku
ISSN: 2070-1721 Fastly ISSN: 2070-1721 Fastly
N. Sullivan N. Sullivan
Cryptography Consulting LLC Cryptography Consulting LLC
C. A. Wood C. A. Wood
Cloudflare Apple
November 2025 February 2026
TLS Encrypted Client Hello TLS Encrypted Client Hello
Abstract Abstract
This document describes a mechanism in Transport Layer Security (TLS) This document describes a mechanism in Transport Layer Security (TLS)
for encrypting a ClientHello message under a server public key. for encrypting a ClientHello message under a server public key.
Status of This Memo Status of This Memo
skipping to change at line 35 skipping to change at line 35
received public review and has been approved for publication by the received public review and has been approved for publication by the
Internet Engineering Steering Group (IESG). Further information on Internet Engineering Steering Group (IESG). Further information on
Internet Standards is available in Section 2 of RFC 7841. Internet Standards is available in Section 2 of RFC 7841.
Information about the current status of this document, any errata, Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc9849. https://www.rfc-editor.org/info/rfc9849.
Copyright Notice Copyright Notice
Copyright (c) 2025 IETF Trust and the persons identified as the Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Revised BSD License text as described in Section 4.e of the include Revised BSD License text as described in Section 4.e of the
Trust Legal Provisions and are provided without warranty as described Trust Legal Provisions and are provided without warranty as described
skipping to change at line 191 skipping to change at line 191
Client <-----> | private.example.org | Client <-----> | private.example.org |
| | | |
| public.example.com | | public.example.com |
| | | |
+---------------------+ +---------------------+
Server Server
(Client-Facing and Backend Combined) (Client-Facing and Backend Combined)
Figure 1: Shared Mode Topology Figure 1: Shared Mode Topology
In Shared Mode, the provider is the origin server for all the domains In shared mode, the provider is the origin server for all the domains
whose DNS records point to it. In this mode, the TLS connection is whose DNS records point to it. In this mode, the TLS connection is
terminated by the provider. terminated by the provider.
+--------------------+ +---------------------+ +--------------------+ +---------------------+
| | | | | | | |
| 2001:DB8::1111 | | 2001:DB8::EEEE | | 2001:DB8::1111 | | 2001:DB8::EEEE |
Client <----------------------------->| | Client <----------------------------->| |
| public.example.com | | private.example.org | | public.example.com | | private.example.org |
| | | | | | | |
+--------------------+ +---------------------+ +--------------------+ +---------------------+
Client-Facing Server Backend Server Client-Facing Server Backend Server
Figure 2: Split Mode Topology Figure 2: Split Mode Topology
In Split Mode, the provider is not the origin server for private In split mode, the provider is not the origin server for private
domains. Rather, the DNS records for private domains point to the domains. Rather, the DNS records for private domains point to the
provider, and the provider's server relays the connection back to the provider, and the provider's server relays the connection back to the
origin server, who terminates the TLS connection with the client. origin server, who terminates the TLS connection with the client.
Importantly, the service provider does not have access to the Importantly, the service provider does not have access to the
plaintext of the connection beyond the unencrypted portions of the plaintext of the connection beyond the unencrypted portions of the
handshake. handshake.
In the remainder of this document, we will refer to the ECH-service In the remainder of this document, we will refer to the ECH-service
provider as the "client-facing server" and the TLS terminator as the provider as the "client-facing server" and to the TLS terminator as
"backend server". These are the same entity in Shared Mode, but in the "backend server". These are the same entity in shared mode, but
Split Mode, the client-facing and backend servers are physically in split mode, the client-facing and backend servers are physically
separated. separated.
See Section 10 for more discussion about the ECH threat model and how See Section 10 for more discussion about the ECH threat model and how
it relates to the client, client-facing server, and backend server. it relates to the client, client-facing server, and backend server.
3.2. Encrypted ClientHello (ECH) 3.2. Encrypted ClientHello (ECH)
A client-facing server enables ECH by publishing an ECH A client-facing server enables ECH by publishing an ECH
configuration, which is an encryption public key and associated configuration, which is an encryption public key and associated
metadata. Domains which wish to use ECH must publish this metadata. Domains which wish to use ECH must publish this
skipping to change at line 433 skipping to change at line 433
enabler for authenticated key mismatch signals (see Section 7). In enabler for authenticated key mismatch signals (see Section 7). In
contrast, the inner ClientHello is the true ClientHello used upon ECH contrast, the inner ClientHello is the true ClientHello used upon ECH
negotiation. negotiation.
5. The "encrypted_client_hello" Extension 5. The "encrypted_client_hello" Extension
To offer ECH, the client sends an "encrypted_client_hello" extension To offer ECH, the client sends an "encrypted_client_hello" extension
in the ClientHelloOuter. When it does, it MUST also send the in the ClientHelloOuter. When it does, it MUST also send the
extension in ClientHelloInner. extension in ClientHelloInner.
enum { ~~ enum { encrypted_client_hello(0xfe0d), (65535) } ExtensionType; ~~
encrypted_client_hello(0xfe0d), (65535)
} ExtensionType;
The payload of the extension has the following structure: The payload of the extension has the following structure:
enum { outer(0), inner(1) } ECHClientHelloType; enum { outer(0), inner(1) } ECHClientHelloType;
struct { struct {
ECHClientHelloType type; ECHClientHelloType type;
select (ECHClientHello.type) { select (ECHClientHello.type) {
case outer: case outer:
HpkeSymmetricCipherSuite cipher_suite; HpkeSymmetricCipherSuite cipher_suite;
skipping to change at line 479 skipping to change at line 477
ClientHelloOuter sent in response to HelloRetryRequest. ClientHelloOuter sent in response to HelloRetryRequest.
payload: The serialized and encrypted EncodedClientHelloInner payload: The serialized and encrypted EncodedClientHelloInner
structure, encrypted using HPKE as described in Section 6.1. structure, encrypted using HPKE as described in Section 6.1.
When a client offers the outer version of an "encrypted_client_hello" When a client offers the outer version of an "encrypted_client_hello"
extension, the server MAY include an "encrypted_client_hello" extension, the server MAY include an "encrypted_client_hello"
extension in its EncryptedExtensions message, as described in extension in its EncryptedExtensions message, as described in
Section 7.1, with the following payload: Section 7.1, with the following payload:
struct { ~~ struct { ECHConfigList retry_configs; } ECHEncryptedExtensions; ~~
ECHConfigList retry_configs;
} ECHEncryptedExtensions;
The response is valid only when the server used the ClientHelloOuter. The response is valid only when the server used the ClientHelloOuter.
If the server sent this extension in response to the inner variant, If the server sent this extension in response to the inner variant,
then the client MUST abort with an "unsupported_extension" alert. then the client MUST abort with an "unsupported_extension" alert.
retry_configs: An ECHConfigList structure containing one or more retry_configs: An ECHConfigList structure containing one or more
ECHConfig structures, in decreasing order of preference, to be ECHConfig structures, in decreasing order of preference, to be
used by the client as described in Section 6.1.6. These are known used by the client as described in Section 6.1.6. These are known
as the server's "retry configurations". as the server's "retry configurations".
Finally, when the client offers the "encrypted_client_hello", if the Finally, when the client offers the "encrypted_client_hello", if the
payload is the inner variant and the server responds with payload is the inner variant and the server responds with
HelloRetryRequest, it MUST include an "encrypted_client_hello" HelloRetryRequest, it MUST include an "encrypted_client_hello"
extension with the following payload: extension with the following payload:
struct { ~~ struct { opaque confirmation[8]; } ECHHelloRetryRequest; ~~
opaque confirmation[8];
} ECHHelloRetryRequest;
The value of ECHHelloRetryRequest.confirmation is set to The value of ECHHelloRetryRequest.confirmation is set to
hrr_accept_confirmation as described in Section 7.2.1. hrr_accept_confirmation as described in Section 7.2.1.
This document also defines the "ech_required" alert, which the client This document also defines the "ech_required" alert, which the client
MUST send when it offered an "encrypted_client_hello" extension that MUST send when it offered an "encrypted_client_hello" extension that
was not accepted by the server. (See Section 11.2.) was not accepted by the server. (See Section 11.2.)
5.1. Encoding the ClientHelloInner 5.1. Encoding the ClientHelloInner
Before encrypting, the client pads and optionally compresses Before encrypting, the client pads and optionally compresses
ClientHelloInner into an EncodedClientHelloInner structure, defined ClientHelloInner into an EncodedClientHelloInner structure, defined
below: below:
struct { ~~ struct { ClientHello client_hello; uint8 zeros[length_of_padding];
ClientHello client_hello; } EncodedClientHelloInner; ~~
uint8 zeros[length_of_padding];
} EncodedClientHelloInner;
The client_hello field is computed by first making a copy of The client_hello field is computed by first making a copy of
ClientHelloInner and setting the legacy_session_id field to the empty ClientHelloInner and setting the legacy_session_id field to the empty
string. In TLS, this field uses the ClientHello structure defined in string. In TLS, this field uses the ClientHello structure defined in
Section 4.1.2 of [RFC8446]. In DTLS, it uses the ClientHello Section 4.1.2 of [RFC8446]. In DTLS, it uses the ClientHello
structured defined in Section 5.3 of [RFC9147]. This does not structure defined in Section 5.3 of [RFC9147]. This does not include
include Handshake structure's four-byte header in TLS, nor twelve- Handshake structure's four-byte header in TLS, nor twelve-byte header
byte header in DTLS. The zeros field MUST be all zeroes of length in DTLS. The zeros field MUST be all zeroes of length
length_of_padding (see Section 6.1.3). length_of_padding (see Section 6.1.3).
Repeating large extensions, such as "key_share" with post-quantum Repeating large extensions, such as "key_share" with post-quantum
algorithms, between ClientHelloInner and ClientHelloOuter can lead to algorithms, between ClientHelloInner and ClientHelloOuter can lead to
excessive size. To reduce the size impact, the client MAY substitute excessive size. To reduce the size impact, the client MAY substitute
extensions which it knows will be duplicated in ClientHelloOuter. It extensions which it knows will be duplicated in ClientHelloOuter. It
does so by removing and replacing extensions from does so by removing and replacing extensions from
EncodedClientHelloInner with a single "ech_outer_extensions" EncodedClientHelloInner with a single "ech_outer_extensions"
extension, defined as follows: extension, defined as follows:
enum { ~~ enum { ech_outer_extensions(0xfd00), (65535) } ExtensionType;
ech_outer_extensions(0xfd00), (65535)
} ExtensionType;
ExtensionType OuterExtensions<2..254>; ExtensionType OuterExtensions<2..254>; ~~
OuterExtensions contains the removed ExtensionType values. Each OuterExtensions contains the removed ExtensionType values. Each
value references the matching extension in ClientHelloOuter. The value references the matching extension in ClientHelloOuter. The
values MUST be ordered contiguously in ClientHelloInner, and the values MUST be ordered contiguously in ClientHelloInner, and the
"ech_outer_extensions" extension MUST be inserted in the "ech_outer_extensions" extension MUST be inserted in the
corresponding position in EncodedClientHelloInner. Additionally, the corresponding position in EncodedClientHelloInner. Additionally, the
extensions MUST appear in ClientHelloOuter in the same relative extensions MUST appear in ClientHelloOuter in the same relative
order. However, there is no requirement that they be contiguous. order. However, there is no requirement that they be contiguous.
For example, OuterExtensions may contain extensions A, B, and C, For example, OuterExtensions may contain extensions A, B, and C,
while ClientHelloOuter contains extensions A, D, B, C, E, and F. while ClientHelloOuter contains extensions A, D, B, C, E, and F.
skipping to change at line 627 skipping to change at line 617
in possession of a compatible ECH configuration and sends GREASE ECH in possession of a compatible ECH configuration and sends GREASE ECH
(see Section 6.2) otherwise. (see Section 6.2) otherwise.
6.1. Offering ECH 6.1. Offering ECH
To offer ECH, the client first chooses a suitable ECHConfig from the To offer ECH, the client first chooses a suitable ECHConfig from the
server's ECHConfigList. To determine if a given ECHConfig is server's ECHConfigList. To determine if a given ECHConfig is
suitable, it checks that it supports the KEM algorithm identified by suitable, it checks that it supports the KEM algorithm identified by
ECHConfig.contents.kem_id, at least one KDF/AEAD algorithm identified ECHConfig.contents.kem_id, at least one KDF/AEAD algorithm identified
by ECHConfig.contents.cipher_suites, and the version of ECH indicated by ECHConfig.contents.cipher_suites, and the version of ECH indicated
by ECHConfig.contents.version. Once a suitable configuration is by ECHConfig.version. Once a suitable configuration is found, the
found, the client selects the cipher suite it will use for client selects the cipher suite it will use for encryption. It MUST
encryption. It MUST NOT choose a cipher suite or version not NOT choose a cipher suite or version not advertised by the
advertised by the configuration. If no compatible configuration is configuration. If no compatible configuration is found, then the
found, then the client SHOULD proceed as described in Section 6.2. client SHOULD proceed as described in Section 6.2.
Next, the client constructs the ClientHelloInner message just as it Next, the client constructs the ClientHelloInner message just as it
does a standard ClientHello, with the exception of the following does a standard ClientHello, with the exception of the following
rules: rules:
1. It MUST NOT offer to negotiate TLS 1.2 or below. This is 1. It MUST NOT offer to negotiate TLS 1.2 or below. This is
necessary to ensure the backend server does not negotiate a TLS necessary to ensure the backend server does not negotiate a TLS
version that is incompatible with ECH. version that is incompatible with ECH.
2. It MUST NOT offer to resume any session for TLS 1.2 and below. 2. It MUST NOT offer to resume any session for TLS 1.2 and below.
skipping to change at line 655 skipping to change at line 645
4. It MUST include the "encrypted_client_hello" extension of type 4. It MUST include the "encrypted_client_hello" extension of type
inner as described in Section 5. (This requirement is not inner as described in Section 5. (This requirement is not
applicable when the "encrypted_client_hello" extension is applicable when the "encrypted_client_hello" extension is
generated as described in Section 6.2.) generated as described in Section 6.2.)
The client then constructs EncodedClientHelloInner as described in The client then constructs EncodedClientHelloInner as described in
Section 5.1. It also computes an HPKE encryption context and enc Section 5.1. It also computes an HPKE encryption context and enc
value as: value as:
pkR = DeserializePublicKey(ECHConfig.contents.public_key) ~~ pkR = DeserializePublicKey(ECHConfig.contents.public_key) enc,
enc, context = SetupBaseS(pkR, context = SetupBaseS(pkR, "tls ech" || 0x00 || ECHConfig) ~~
"tls ech" || 0x00 || ECHConfig)
Next, it constructs a partial ClientHelloOuterAAD as it does a Next, it constructs a partial ClientHelloOuterAAD as it does a
standard ClientHello, with the exception of the following rules: standard ClientHello, with the exception of the following rules:
1. It MUST offer to negotiate TLS 1.3 or above. 1. It MUST offer to negotiate TLS 1.3 or above.
2. If it compressed any extensions in EncodedClientHelloInner, it 2. If it compressed any extensions in EncodedClientHelloInner, it
MUST copy the corresponding extensions from ClientHelloInner. MUST copy the corresponding extensions from ClientHelloInner.
The copied extensions additionally MUST be in the same relative The copied extensions additionally MUST be in the same relative
order as in ClientHelloInner. order as in ClientHelloInner.
3. It MUST copy the legacy_session_id field from ClientHelloInner. 3. It MUST copy the legacy_session_id field from ClientHelloInner.
This allows the server to echo the correct session ID for TLS This allows the server to echo the correct session ID for TLS
1.3's compatibility mode (see Appendix D.4 of [RFC8446]) when ECH 1.3's compatibility mode (see Appendix D.4 of [RFC8446]) when ECH
is negotiated. Note that compatibility mode is not used in DTLS is negotiated. Note that compatibility mode is not used in DTLS
1.3, but following this rule will produce the correct results for 1.3, but following this rule will produce the correct results for
both TLS 1.3 and DTLS 1.3. both TLS 1.3 and DTLS 1.3.
4. It MAY copy any other field from the ClientHelloInner except 4. It MAY copy any other field from the ClientHelloInner except
ClientHelloInner.random. Instead, It MUST generate a fresh ClientHelloInner.random. Instead, it MUST generate a fresh
ClientHelloOuter.random using a secure random number generator. ClientHelloOuter.random using a secure random number generator.
(See Section 10.12.1.) (See Section 10.12.1.)
5. It SHOULD place the value of ECHConfig.contents.public_name in 5. It SHOULD place the value of ECHConfig.contents.public_name in
the "server_name" extension. Clients that do not follow this the "server_name" extension. Clients that do not follow this
step, or place a different value in the "server_name" extension, step, or place a different value in the "server_name" extension,
risk breaking the retry mechanism described in Section 6.1.6 or risk breaking the retry mechanism described in Section 6.1.6 or
failing to interoperate with servers that require this step to be failing to interoperate with servers that require this step to be
done; see Section 7.1. done; see Section 7.1.
6. When the client offers the "pre_shared_key" extension in 6. When the client offers the "pre_shared_key" extension in
ClientHelloInner, it SHOULD also include a GREASE ClientHelloInner, it SHOULD also include a GREASE
"pre_shared_key" extension in ClientHelloOuter, generated in the "pre_shared_key" extension in ClientHelloOuter, generated in the
manner described in Section 6.1.2. The client MUST NOT use this manner described in Section 6.1.2. The client MUST NOT use this
extension to advertise a Pre-Shared Key (PSK) to the client- extension to advertise a PSK to the client-facing server. (See
facing server. (See Section 10.12.3.) When the client includes Section 10.12.3.) When the client includes a GREASE
a GREASE "pre_shared_key" extension, it MUST also copy the "pre_shared_key" extension, it MUST also copy the
"psk_key_exchange_modes" from the ClientHelloInner into the "psk_key_exchange_modes" from the ClientHelloInner into the
ClientHelloOuter. ClientHelloOuter.
7. When the client offers the "early_data" extension in 7. When the client offers the "early_data" extension in
ClientHelloInner, it MUST also include the "early_data" extension ClientHelloInner, it MUST also include the "early_data" extension
in ClientHelloOuter. This allows servers that reject ECH and use in ClientHelloOuter. This allows servers that reject ECH and use
ClientHelloOuter to safely ignore any early data sent by the ClientHelloOuter to safely ignore any early data sent by the
client per [RFC8446], Section 4.2.10. client per [RFC8446], Section 4.2.10.
The client might duplicate non-sensitive extensions in both messages. The client might duplicate non-sensitive extensions in both messages.
skipping to change at line 744 skipping to change at line 733
* payload, a placeholder byte string containing L zeros. * payload, a placeholder byte string containing L zeros.
If configuration identifiers (see Section 10.4) are to be ignored, If configuration identifiers (see Section 10.4) are to be ignored,
config_id SHOULD be set to a randomly generated byte in the first config_id SHOULD be set to a randomly generated byte in the first
ClientHelloOuter and, in the event of a HelloRetryRequest (HRR), MUST ClientHelloOuter and, in the event of a HelloRetryRequest (HRR), MUST
be left unchanged for the second ClientHelloOuter. be left unchanged for the second ClientHelloOuter.
The client serializes this structure to construct the The client serializes this structure to construct the
ClientHelloOuterAAD. It then computes the final payload as: ClientHelloOuterAAD. It then computes the final payload as:
final_payload = context.Seal(ClientHelloOuterAAD, ~~ final_payload = context.Seal(ClientHelloOuterAAD,
EncodedClientHelloInner) EncodedClientHelloInner) ~~
Including ClientHelloOuterAAD as the HPKE AAD binds the Including ClientHelloOuterAAD as the HPKE AAD binds the
ClientHelloOuter to the ClientHelloInner, thus preventing attackers ClientHelloOuter to the ClientHelloInner, thus preventing attackers
from modifying ClientHelloOuter while keeping the same from modifying ClientHelloOuter while keeping the same
ClientHelloInner, as described in Section 10.12.3. ClientHelloInner, as described in Section 10.12.3.
Finally, the client replaces payload with final_payload to obtain Finally, the client replaces payload with final_payload to obtain
ClientHelloOuter. The two values have the same length, so it is not ClientHelloOuter. The two values have the same length, so it is not
necessary to recompute length prefixes in the serialized structure. necessary to recompute length prefixes in the serialized structure.
skipping to change at line 812 skipping to change at line 801
By way of example, clients typically support a small number of By way of example, clients typically support a small number of
application profiles. For instance, a browser might support HTTP application profiles. For instance, a browser might support HTTP
with ALPN values ["http/1.1", "h2"] and WebRTC media with ALPNs with ALPN values ["http/1.1", "h2"] and WebRTC media with ALPNs
["webrtc", "c-webrtc"]. Clients SHOULD pad this extension by ["webrtc", "c-webrtc"]. Clients SHOULD pad this extension by
rounding up to the total size of the longest ALPN extension across rounding up to the total size of the longest ALPN extension across
all application profiles. The target padding length of most all application profiles. The target padding length of most
ClientHello extensions can be computed in this way. ClientHello extensions can be computed in this way.
In contrast, clients do not know the longest SNI value in the client- In contrast, clients do not know the longest SNI value in the client-
facing server's anonymity set without server input. Clients SHOULD facing server's anonymity set without server input. Clients SHOULD
use the ECHConfig's maximum_name_length field as follows, where L is use the ECHConfig's maximum_name_length field as follows, where M is
the maximum_name_length value. the maximum_name_length value.
1. If the ClientHelloInner contained a "server_name" extension with 1. If the ClientHelloInner contained a "server_name" extension with
a name of length D, add max(0, L - D) bytes of padding. a name of length D, add max(0, M - D) bytes of padding.
2. If the ClientHelloInner did not contain a "server_name" extension 2. If the ClientHelloInner did not contain a "server_name" extension
(e.g., if the client is connecting to an IP address), add L + 9 (e.g., if the client is connecting to an IP address), add M + 9
bytes of padding. This is the length of a "server_name" bytes of padding. This is the length of a "server_name"
extension with an L-byte name. extension with an M-byte name.
Finally, the client SHOULD pad the entire message as follows: Finally, the client SHOULD pad the entire message as follows:
1. Let L be the length of the EncodedClientHelloInner with all the 1. Let L be the length of the EncodedClientHelloInner with all the
padding computed so far. padding computed so far.
2. Let N = 31 - ((L - 1) % 32) and add N bytes of padding. 2. Let N = 31 - ((L - 1) % 32) and add N bytes of padding.
This rounds the length of EncodedClientHelloInner up to a multiple of This rounds the length of EncodedClientHelloInner up to a multiple of
32 bytes, reducing the set of possible lengths across all clients. 32 bytes, reducing the set of possible lengths across all clients.
skipping to change at line 977 skipping to change at line 966
connection and a node with configuration B in the second. Note that connection and a node with configuration B in the second. Note that
this guidance does not apply to the cases in the previous paragraph this guidance does not apply to the cases in the previous paragraph
where the server has securely disabled ECH. where the server has securely disabled ECH.
If a client does not retry, it MUST report an error to the calling If a client does not retry, it MUST report an error to the calling
application. application.
6.1.7. Authenticating for the Public Name 6.1.7. Authenticating for the Public Name
When the server rejects ECH, it continues with the handshake using When the server rejects ECH, it continues with the handshake using
the plaintext "server_name" extension instead (see Section 7). Then, the plaintext "server_name" extension instead (see Section 7).
clients that offer ECH authenticate the connection with the public Clients that offer ECH then authenticate the connection with the
name as follows: public name as follows:
* The client MUST verify that the certificate is valid for * The client MUST verify that the certificate is valid for
ECHConfig.contents.public_name. If invalid, it MUST abort the ECHConfig.contents.public_name. If invalid, it MUST abort the
connection with the appropriate alert. connection with the appropriate alert.
* If the server requests a client certificate, the client MUST * If the server requests a client certificate, the client MUST
respond with an empty Certificate message, denoting no client respond with an empty Certificate message, denoting no client
certificate. certificate.
In verifying the client-facing server certificate, the client MUST In verifying the client-facing server certificate, the client MUST
interpret the public name as a DNS-based reference identity interpret the public name as a DNS-based reference identity
[RFC6125]. Clients that incorporate DNS names and IP addresses into [RFC9525]. Clients that incorporate DNS names and IP addresses into
the same syntax (e.g. Section 7.4 of [RFC3986] and [WHATWG-IPV4]) the same syntax (e.g. Section 7.4 of [RFC3986] and [WHATWG-IPV4])
MUST reject names that would be interpreted as IPv4 addresses. MUST reject names that would be interpreted as IPv4 addresses.
Clients that enforce this by checking ECHConfig.contents.public_name Clients that enforce this by checking ECHConfig.contents.public_name
do not need to repeat the check when processing ECH rejection. do not need to repeat the check when processing ECH rejection.
Note that authenticating a connection for the public name does not Note that authenticating a connection for the public name does not
authenticate it for the origin. The TLS implementation MUST NOT authenticate it for the origin. The TLS implementation MUST NOT
report such connections as successful to the application. It report such connections as successful to the application. It
additionally MUST ignore all session tickets and session IDs additionally MUST ignore all session tickets and session IDs
presented by the server. These connections are only used to trigger presented by the server. These connections are only used to trigger
skipping to change at line 1131 skipping to change at line 1120
application-level warning message when these are observed. application-level warning message when these are observed.
* By giving the extraneous configurations an invalid public key and * By giving the extraneous configurations an invalid public key and
a public name not associated with the server so that the initial a public name not associated with the server so that the initial
ClientHelloOuter will not be decryptable and the server cannot ClientHelloOuter will not be decryptable and the server cannot
perform the recovery flow described in Section 6.1.6. perform the recovery flow described in Section 6.1.6.
7. Server Behavior 7. Server Behavior
As described in Section 3.1, servers can play two roles, either as As described in Section 3.1, servers can play two roles, either as
the client-facing server or as the back-end server. Depending on the the client-facing server or as the backend server. Depending on the
server role, the ECHClientHello will be different: server role, the ECHClientHello will be different:
* A client-facing server expects an ECHClientHello.type of outer, * A client-facing server expects an ECHClientHello.type of outer,
and proceeds as described in Section 7.1 to extract a and proceeds as described in Section 7.1 to extract a
ClientHelloInner, if available. ClientHelloInner, if available.
* A backend server expects an ECHClientHello.type of inner, and * A backend server expects an ECHClientHello.type of inner, and
proceeds as described in Section 7.2. proceeds as described in Section 7.2.
In split mode, a client-facing server which receives a ClientHello In split mode, a client-facing server which receives a ClientHello
skipping to change at line 1198 skipping to change at line 1187
follows. follows.
The server verifies that the ECHConfig supports the cipher suite The server verifies that the ECHConfig supports the cipher suite
indicated by the ECHClientHello.cipher_suite and that the version of indicated by the ECHClientHello.cipher_suite and that the version of
ECH indicated by the client matches the ECHConfig.version. If not, ECH indicated by the client matches the ECHConfig.version. If not,
the server continues to the next candidate ECHConfig. the server continues to the next candidate ECHConfig.
Next, the server decrypts ECHClientHello.payload, using the private Next, the server decrypts ECHClientHello.payload, using the private
key skR corresponding to ECHConfig, as follows: key skR corresponding to ECHConfig, as follows:
context = SetupBaseR(ECHClientHello.enc, skR, ~~ context = SetupBaseR(ECHClientHello.enc, skR, "tls ech" || 0x00 ||
"tls ech" || 0x00 || ECHConfig) ECHConfig) EncodedClientHelloInner =
EncodedClientHelloInner = context.Open(ClientHelloOuterAAD, context.Open(ClientHelloOuterAAD, ECHClientHello.payload) ~~
ECHClientHello.payload)
ClientHelloOuterAAD is computed from ClientHelloOuter as described in ClientHelloOuterAAD is computed from ClientHelloOuter as described in
Section 5.2. The info parameter to SetupBaseR is the concatenation Section 5.2. The info parameter to SetupBaseR is the concatenation
"tls ech", a zero byte, and the serialized ECHConfig. If decryption "tls ech", a zero byte, and the serialized ECHConfig. If decryption
fails, the server continues to the next candidate ECHConfig. fails, the server continues to the next candidate ECHConfig.
Otherwise, the server reconstructs ClientHelloInner from Otherwise, the server reconstructs ClientHelloInner from
EncodedClientHelloInner, as described in Section 5.1. It then stops EncodedClientHelloInner, as described in Section 5.1. It then stops
iterating over the candidate ECHConfig values. iterating over the candidate ECHConfig values.
Once the server has chosen the correct ECHConfig, it MAY verify that Once the server has chosen the correct ECHConfig, it MAY verify that
skipping to change at line 1277 skipping to change at line 1265
ClientHelloOuter also contains the "encrypted_client_hello" ClientHelloOuter also contains the "encrypted_client_hello"
extension. If not, it MUST abort the handshake with a extension. If not, it MUST abort the handshake with a
"missing_extension" alert. Otherwise, it checks that "missing_extension" alert. Otherwise, it checks that
ECHClientHello.cipher_suite and ECHClientHello.config_id are ECHClientHello.cipher_suite and ECHClientHello.config_id are
unchanged, and that ECHClientHello.enc is empty. If not, it MUST unchanged, and that ECHClientHello.enc is empty. If not, it MUST
abort the handshake with an "illegal_parameter" alert. abort the handshake with an "illegal_parameter" alert.
Finally, it decrypts the new ECHClientHello.payload as a second Finally, it decrypts the new ECHClientHello.payload as a second
message with the previous HPKE context: message with the previous HPKE context:
EncodedClientHelloInner = context.Open(ClientHelloOuterAAD, ~~ EncodedClientHelloInner = context.Open(ClientHelloOuterAAD,
ECHClientHello.payload) ECHClientHello.payload) ~~
ClientHelloOuterAAD is computed as described in Section 5.2, but ClientHelloOuterAAD is computed as described in Section 5.2, but
using the second ClientHelloOuter. If decryption fails, the client- using the second ClientHelloOuter. If decryption fails, the client-
facing server MUST abort the handshake with a "decrypt_error" alert. facing server MUST abort the handshake with a "decrypt_error" alert.
Otherwise, it reconstructs the second ClientHelloInner from the new Otherwise, it reconstructs the second ClientHelloInner from the new
EncodedClientHelloInner as described in Section 5.1, using the second EncodedClientHelloInner as described in Section 5.1, using the second
ClientHelloOuter for any referenced extensions. ClientHelloOuter for any referenced extensions.
The client-facing server then forwards the resulting ClientHelloInner The client-facing server then forwards the resulting ClientHelloInner
to the backend server. It forwards all subsequent TLS messages to the backend server. It forwards all subsequent TLS messages
skipping to change at line 1324 skipping to change at line 1312
The backend server embeds in ServerHello.random a string derived from The backend server embeds in ServerHello.random a string derived from
the inner handshake. It begins by computing its ServerHello as the inner handshake. It begins by computing its ServerHello as
usual, except the last 8 bytes of ServerHello.random are set to zero. usual, except the last 8 bytes of ServerHello.random are set to zero.
It then computes the transcript hash for ClientHelloInner up to and It then computes the transcript hash for ClientHelloInner up to and
including the modified ServerHello, as described in [RFC8446], including the modified ServerHello, as described in [RFC8446],
Section 4.4.1. Let transcript_ech_conf denote the output. Finally, Section 4.4.1. Let transcript_ech_conf denote the output. Finally,
the backend server overwrites the last 8 bytes of the the backend server overwrites the last 8 bytes of the
ServerHello.random with the following string: ServerHello.random with the following string:
accept_confirmation = HKDF-Expand-Label( ~~ accept_confirmation = HKDF-Expand-Label( HKDF-Extract(0,
HKDF-Extract(0, ClientHelloInner.random), ClientHelloInner.random), "ech accept confirmation",
"ech accept confirmation", transcript_ech_conf, 8) ~~
transcript_ech_conf,
8)
where HKDF-Expand-Label is defined in [RFC8446], Section 7.1, "0" where HKDF-Expand-Label is defined in [RFC8446], Section 7.1, "0"
indicates a string of Hash.length bytes set to zero, and Hash is the indicates a string of Hash.length bytes set to zero, and Hash is the
hash function used to compute the transcript hash. In DTLS, the hash function used to compute the transcript hash. In DTLS, the
modified version of HKDF-Expand-Label defined in [RFC9147], modified version of HKDF-Expand-Label defined in [RFC9147],
Section 5.9 is used instead. Section 5.9 is used instead.
The backend server MUST NOT perform this operation if it negotiated The backend server MUST NOT perform this operation if it negotiated
TLS 1.2 or below. Note that doing so would overwrite the downgrade TLS 1.2 or below. Note that doing so would overwrite the downgrade
signal for TLS 1.3 (see [RFC8446], Section 4.1.3). signal for TLS 1.3 (see [RFC8446], Section 4.1.3).
skipping to change at line 1358 skipping to change at line 1344
The backend server begins by computing HelloRetryRequest as usual, The backend server begins by computing HelloRetryRequest as usual,
except that it also contains an "encrypted_client_hello" extension except that it also contains an "encrypted_client_hello" extension
with a payload of 8 zero bytes. It then computes the transcript hash with a payload of 8 zero bytes. It then computes the transcript hash
for the first ClientHelloInner, denoted ClientHelloInner1, up to and for the first ClientHelloInner, denoted ClientHelloInner1, up to and
including the modified HelloRetryRequest. Let including the modified HelloRetryRequest. Let
transcript_hrr_ech_conf denote the output. Finally, the backend transcript_hrr_ech_conf denote the output. Finally, the backend
server overwrites the payload of the "encrypted_client_hello" server overwrites the payload of the "encrypted_client_hello"
extension with the following string: extension with the following string:
hrr_accept_confirmation = HKDF-Expand-Label( ~~ hrr_accept_confirmation = HKDF-Expand-Label( HKDF-Extract(0,
HKDF-Extract(0, ClientHelloInner1.random), ClientHelloInner1.random), "hrr ech accept confirmation",
"hrr ech accept confirmation", transcript_hrr_ech_conf, 8) ~~
transcript_hrr_ech_conf,
8)
In the subsequent ServerHello message, the backend server sends the In the subsequent ServerHello message, the backend server sends the
accept_confirmation value as described in Section 7.2. accept_confirmation value as described in Section 7.2.
8. Deployment Considerations 8. Deployment Considerations
The design of ECH as specified in this document necessarily requires The design of ECH as specified in this document necessarily requires
changes to client, client-facing server, and backend server. changes to client, client-facing server, and backend server.
Coordination between client-facing and backend server requires care, Coordination between client-facing and backend server requires care,
as deployment mistakes can lead to compatibility issues. These are as deployment mistakes can lead to compatibility issues. These are
skipping to change at line 1501 skipping to change at line 1485
A middlebox that filters based on plaintext packet contents is one A middlebox that filters based on plaintext packet contents is one
example of a passive attacker. In contrast, active attackers can example of a passive attacker. In contrast, active attackers can
also write packets into the network for malicious purposes, such as also write packets into the network for malicious purposes, such as
interfering with existing connections, probing servers, and querying interfering with existing connections, probing servers, and querying
DNS. In short, an active attacker corresponds to the conventional DNS. In short, an active attacker corresponds to the conventional
threat model [RFC3552] for TLS 1.3 [RFC8446]. threat model [RFC3552] for TLS 1.3 [RFC8446].
Passive and active attackers can exist anywhere in the network, Passive and active attackers can exist anywhere in the network,
including between the client and client-facing server, as well as including between the client and client-facing server, as well as
between the client-facing and backend servers when running ECH in between the client-facing and backend servers when running ECH in
Split Mode. However, for Split Mode in particular, ECH makes two split mode. However, for split mode in particular, ECH makes two
additional assumptions: additional assumptions:
1. The channel between each client-facing and each backend server is 1. The channel between each client-facing and each backend server is
authenticated such that the backend server only accepts messages authenticated such that the backend server only accepts messages
from trusted client-facing servers. The exact mechanism for from trusted client-facing servers. The exact mechanism for
establishing this authenticated channel is out of scope for this establishing this authenticated channel is out of scope for this
document. document.
2. The attacker cannot correlate messages between a client and 2. The attacker cannot correlate messages between a client and
client-facing server with messages between client-facing and client-facing server with messages between client-facing and
skipping to change at line 1709 skipping to change at line 1693
adversary that observes this can deduce that the ECH-enabled adversary that observes this can deduce that the ECH-enabled
connection was made to a host that the client previously connected to connection was made to a host that the client previously connected to
and which is within the same anonymity set. and which is within the same anonymity set.
10.8. Cookies 10.8. Cookies
Section 4.2.2 of [RFC8446] defines a cookie value that servers may Section 4.2.2 of [RFC8446] defines a cookie value that servers may
send in HelloRetryRequest for clients to echo in the second send in HelloRetryRequest for clients to echo in the second
ClientHello. While ECH encrypts the cookie in the second ClientHello. While ECH encrypts the cookie in the second
ClientHelloInner, the backend server's HelloRetryRequest is ClientHelloInner, the backend server's HelloRetryRequest is
unencrypted.This means differences in cookies between backend unencrypted. This means differences in cookies between backend
servers, such as lengths or cleartext components, may leak servers, such as lengths or cleartext components, may leak
information about the server identity. information about the server identity.
Backend servers in an anonymity set SHOULD NOT reveal information in Backend servers in an anonymity set SHOULD NOT reveal information in
the cookie which identifies the server. This may be done by handling the cookie which identifies the server. This may be done by handling
HelloRetryRequest statefully, thus not sending cookies, or by using HelloRetryRequest statefully, thus not sending cookies, or by using
the same cookie construction for all backend servers. the same cookie construction for all backend servers.
Note that, if the cookie includes a key name, analogous to Section 4 Note that, if the cookie includes a key name, analogous to Section 4
of [RFC5077], this may leak information if different backend servers of [RFC5077], this may leak information if different backend servers
issue cookies with different key names at the time of the connection. issue cookies with different key names at the time of the connection.
In particular, if the deployment operates in Split Mode, the backend In particular, if the deployment operates in split mode, the backend
servers may not share cookie encryption keys. Backend servers may servers may not share cookie encryption keys. Backend servers may
mitigate this either by handling key rotation with trial decryption mitigate this either by handling key rotation with trial decryption
or by coordinating to match key names. or by coordinating to match key names.
10.9. Attacks Exploiting Acceptance Confirmation 10.9. Attacks Exploiting Acceptance Confirmation
To signal acceptance, the backend server overwrites 8 bytes of its To signal acceptance, the backend server overwrites 8 bytes of its
ServerHello.random with a value derived from the ServerHello.random with a value derived from the
ClientHelloInner.random. (See Section 7.2 for details.) This ClientHelloInner.random. (See Section 7.2 for details.) This
behavior increases the likelihood of the ServerHello.random colliding behavior increases the likelihood of the ServerHello.random colliding
skipping to change at line 1859 skipping to change at line 1843
10.10.5. Maintain Forward Secrecy 10.10.5. Maintain Forward Secrecy
This design does not provide forward secrecy for the inner This design does not provide forward secrecy for the inner
ClientHello because the server's ECH key is static. However, the ClientHello because the server's ECH key is static. However, the
window of exposure is bound by the key lifetime. It is RECOMMENDED window of exposure is bound by the key lifetime. It is RECOMMENDED
that servers rotate keys regularly. that servers rotate keys regularly.
10.10.6. Enable Multi-party Security Contexts 10.10.6. Enable Multi-party Security Contexts
This design permits servers operating in Split Mode to forward This design permits servers operating in split mode to forward
connections directly to backend origin servers. The client connections directly to backend origin servers. The client
authenticates the identity of the backend origin server, thereby authenticates the identity of the backend origin server, thereby
allowing the backend origin server to hide behind the client-facing allowing the backend origin server to hide behind the client-facing
server without the client-facing server decrypting and reencrypting server without the client-facing server decrypting and reencrypting
the connection. the connection.
Conversely, if the DNS records used for configuration are Conversely, if the DNS records used for configuration are
authenticated, e.g., via DNSSEC, spoofing a client-facing server authenticated, e.g., via DNSSEC, spoofing a client-facing server
operating in Split Mode is not possible. See Section 10.2 for more operating in split mode is not possible. See Section 10.2 for more
details regarding plaintext DNS. details regarding plaintext DNS.
Authenticating the ECHConfig structure naturally authenticates the Authenticating the ECHConfig structure naturally authenticates the
included public name. This also authenticates any retry signals from included public name. This also authenticates any retry signals from
the client-facing server because the client validates the server the client-facing server because the client validates the server
certificate against the public name before retrying. certificate against the public name before retrying.
10.10.7. Support Multiple Protocols 10.10.7. Support Multiple Protocols
This design has no impact on application layer protocol negotiation. This design has no impact on application layer protocol negotiation.
skipping to change at line 1919 skipping to change at line 1903
the attacker learns that its test certificate name was incorrect. As the attacker learns that its test certificate name was incorrect. As
an example, suppose the client's SNI value in its inner ClientHello an example, suppose the client's SNI value in its inner ClientHello
is "example.com," and the attacker replied with a Certificate for is "example.com," and the attacker replied with a Certificate for
"test.com". If the client produces a verification failure alert "test.com". If the client produces a verification failure alert
because of the mismatch faster than it would due to the Certificate because of the mismatch faster than it would due to the Certificate
signature validation, information about the name leaks. Note that signature validation, information about the name leaks. Note that
the attacker can also withhold the CertificateVerify message. In the attacker can also withhold the CertificateVerify message. In
that scenario, a client which first verifies the Certificate would that scenario, a client which first verifies the Certificate would
then respond similarly and leak the same information. then respond similarly and leak the same information.
Client Attacker Server ~~ Client Attacker Server ClientHello + key_share + ech ------>
ClientHello (intercept) -----> X (drop)
+ key_share
+ ech ------> (intercept) -----> X (drop)
ServerHello ServerHello
+ key_share + key_share
{EncryptedExtensions} {EncryptedExtensions}
{CertificateRequest*} {CertificateRequest*}
{Certificate*} {Certificate*}
{CertificateVerify*} {CertificateVerify*}
<------ <------ Alert
Alert ------> ~~
------>
Figure 3: Client Reaction Attack Figure 3: Client Reaction Attack
ClientHelloInner.random prevents this attack. In particular, since ClientHelloInner.random prevents this attack. In particular, since
the attacker does not have access to this value, it cannot produce the attacker does not have access to this value, it cannot produce
the right transcript and handshake keys needed for encrypting the the right transcript and handshake keys needed for encrypting the
Certificate message. Thus, the client will fail to decrypt the Certificate message. Thus, the client will fail to decrypt the
Certificate and abort the connection. Certificate and abort the connection.
10.12.2. HelloRetryRequest Hijack Mitigation 10.12.2. HelloRetryRequest Hijack Mitigation
skipping to change at line 1958 skipping to change at line 1939
(ech) extension to the server, which triggers a legitimate (ech) extension to the server, which triggers a legitimate
HelloRetryRequest in return. Rather than forward the retry to the HelloRetryRequest in return. Rather than forward the retry to the
client, the attacker attempts to generate its own ClientHello in client, the attacker attempts to generate its own ClientHello in
response based on the contents of the first ClientHello and response based on the contents of the first ClientHello and
HelloRetryRequest exchange with the result that the server encrypts HelloRetryRequest exchange with the result that the server encrypts
the Certificate to the attacker. If the server used the SNI from the the Certificate to the attacker. If the server used the SNI from the
first ClientHello and the key share from the second (attacker- first ClientHello and the key share from the second (attacker-
controlled) ClientHello, the Certificate produced would leak the controlled) ClientHello, the Certificate produced would leak the
client's chosen SNI to the attacker. client's chosen SNI to the attacker.
Client Attacker Server ~~ Client Attacker Server ClientHello + key_share + ech ------>
ClientHello (forward) -------> HelloRetryRequest + key_share (intercept) <-------
+ key_share
+ ech ------> (forward) ------->
HelloRetryRequest
+ key_share
(intercept) <-------
ClientHello ClientHello
+ key_share' + key_share'
+ ech' -------> + ech' ------->
ServerHello ServerHello
+ key_share + key_share
{EncryptedExtensions} {EncryptedExtensions}
{CertificateRequest*} {CertificateRequest*}
{Certificate*} {Certificate*}
{CertificateVerify*} {CertificateVerify*}
{Finished} {Finished}
<------- <-------
(process server flight) (process server flight) ~~
Figure 4: HelloRetryRequest Hijack Attack Figure 4: HelloRetryRequest Hijack Attack
This attack is mitigated by using the same HPKE context for both This attack is mitigated by using the same HPKE context for both
ClientHello messages. The attacker does not possess the context's ClientHello messages. The attacker does not possess the context's
keys, so it cannot generate a valid encryption of the second inner keys, so it cannot generate a valid encryption of the second inner
ClientHello. ClientHello.
If the attacker could manipulate the second ClientHello, it might be If the attacker could manipulate the second ClientHello, it might be
possible for the server to act as an oracle if it required parameters possible for the server to act as an oracle if it required parameters
skipping to change at line 2015 skipping to change at line 1991
To begin, the attacker first interacts with a server to obtain a To begin, the attacker first interacts with a server to obtain a
resumption ticket for a given test domain, such as "example.com". resumption ticket for a given test domain, such as "example.com".
Later, upon receipt of a ClientHelloOuter, it modifies it such that Later, upon receipt of a ClientHelloOuter, it modifies it such that
the server will process the resumption ticket with ClientHelloInner. the server will process the resumption ticket with ClientHelloInner.
If the server only accepts resumption PSKs that match the server If the server only accepts resumption PSKs that match the server
name, it will fail the PSK binder check with an alert when name, it will fail the PSK binder check with an alert when
ClientHelloInner is for "example.com" but silently ignore the PSK and ClientHelloInner is for "example.com" but silently ignore the PSK and
continue when ClientHelloInner is for any other name. This continue when ClientHelloInner is for any other name. This
introduces an oracle for testing encrypted SNI values. introduces an oracle for testing encrypted SNI values.
Client Attacker Server ~~ Client Attacker Server
handshake and ticket handshake and ticket
for "example.com" for "example.com"
<--------> <-------->
ClientHello ClientHello
+ key_share + key_share
+ ech + ech
+ ech_outer_extensions(pre_shared_key) + ech_outer_extensions(pre_shared_key)
+ pre_shared_key + pre_shared_key
--------> -------->
(intercept) (intercept)
ClientHello ClientHello
+ key_share + key_share
+ ech + ech
+ ech_outer_extensions(pre_shared_key) + ech_outer_extensions(pre_shared_key)
+ pre_shared_key' + pre_shared_key'
--------> -------->
Alert Alert
-or- -or-
ServerHello ServerHello
... ...
Finished Finished
<-------- <-------- ~~
Figure 5: Message Flow for Malleable ClientHello Figure 5: Message Flow for Malleable ClientHello
This attack may be generalized to any parameter which the server This attack may be generalized to any parameter which the server
varies by server name, such as ALPN preferences. varies by server name, such as ALPN preferences.
ECH mitigates this attack by only negotiating TLS parameters from ECH mitigates this attack by only negotiating TLS parameters from
ClientHelloInner and authenticating all inputs to the ClientHelloInner and authenticating all inputs to the
ClientHelloInner (EncodedClientHelloInner and ClientHelloOuter) with ClientHelloInner (EncodedClientHelloInner and ClientHelloOuter) with
the HPKE AEAD. See Section 5.2. The decompression process in the HPKE AEAD. See Section 5.2. The decompression process in
skipping to change at line 2074 skipping to change at line 2050
the number of extensions, the overall decoding process would take the number of extensions, the overall decoding process would take
O(M*N) time, where M is the number of extensions in O(M*N) time, where M is the number of extensions in
ClientHelloOuter and N is the size of OuterExtensions. ClientHelloOuter and N is the size of OuterExtensions.
* If the same ClientHelloOuter extension can be copied multiple * If the same ClientHelloOuter extension can be copied multiple
times, an attacker could cause the client-facing server to times, an attacker could cause the client-facing server to
construct a large ClientHelloInner by including a large extension construct a large ClientHelloInner by including a large extension
in ClientHelloOuter of length L and an OuterExtensions list in ClientHelloOuter of length L and an OuterExtensions list
referencing N copies of that extension. The client-facing server referencing N copies of that extension. The client-facing server
would then use O(N*L) memory in response to O(N+L) bandwidth from would then use O(N*L) memory in response to O(N+L) bandwidth from
the client. In split-mode, an O(N*L)-sized packet would then be the client. In split mode, an O(N*L)-sized packet would then be
transmitted to the backend server. transmitted to the backend server.
ECH mitigates this attack by requiring that OuterExtensions be ECH mitigates this attack by requiring that OuterExtensions be
referenced in order, that duplicate references be rejected, and by referenced in order, that duplicate references be rejected, and by
recommending that client-facing servers use a linear scan to perform recommending that client-facing servers use a linear scan to perform
decompression. These requirements are detailed in Section 5.1. decompression. These requirements are detailed in Section 5.1.
11. IANA Considerations 11. IANA Considerations
11.1. Update of the TLS ExtensionType Registry 11.1. Update of the TLS ExtensionType Registry
skipping to change at line 2113 skipping to change at line 2089
11.3. ECH Configuration Extension Registry 11.3. ECH Configuration Extension Registry
IANA has created a new "TLS ECHConfig Extension" registry in a new IANA has created a new "TLS ECHConfig Extension" registry in a new
"TLS Encrypted Client Hello (ECH) Configuration Extensions" registry "TLS Encrypted Client Hello (ECH) Configuration Extensions" registry
group. New registrations will list the following attributes: group. New registrations will list the following attributes:
Value: The two-byte identifier for the ECHConfigExtension, i.e., the Value: The two-byte identifier for the ECHConfigExtension, i.e., the
ECHConfigExtensionType ECHConfigExtensionType
Extension Name: Name of the ECHConfigExtension Extension Name: Name of the ECHConfigExtension
Recommended: A "Y" or "N" value indicating if the extension is TLS Recommended: A "Y" or "N" value indicating if the TLS Working Group
WG recommends that the extension be supported. This column is recommends that the extension be supported. This column is
assigned a value of "N" unless explicitly requested. Adding a assigned a value of "N" unless explicitly requested. Adding a
value with a value of "Y" requires Standards Action [RFC8126]. value of "Y" requires Standards Action [RFC8126].
Reference: The specification where the ECHConfigExtension is defined Reference: The specification where the ECHConfigExtension is defined
Notes: Any notes associated with the entry Notes: Any notes associated with the entry
New entries in the "TLS ECHConfig Extension" registry are subject to New entries in the "TLS ECHConfig Extension" registry are subject to
the Specification Required registration policy ([RFC8126], the Specification Required registration policy ([RFC8126],
Section 4.6), with the policies described in [RFC8447], Section 17. Section 4.6), with the policies described in [RFC8447], Section 17.
IANA has added the following note to the "TLS ECHConfig Extension" IANA has added the following note to the "TLS ECHConfig Extension"
registry: registry:
Note: The role of the designated expert is described in RFC 8447. Note: The role of the designated expert is described in RFC 8447.
skipping to change at line 2147 skipping to change at line 2123
The initial contents for this registry consists of multiple reserved The initial contents for this registry consists of multiple reserved
values with the following attributes, which are repeated for each values with the following attributes, which are repeated for each
registration: registration:
Value: 0x0000, 0x1A1A, 0x2A2A, 0x3A3A, 0x4A4A, 0x5A5A, 0x6A6A, Value: 0x0000, 0x1A1A, 0x2A2A, 0x3A3A, 0x4A4A, 0x5A5A, 0x6A6A,
0x7A7A, 0x8A8A, 0x9A9A, 0xAAAA, 0xBABA, 0xCACA, 0xDADA, 0xEAEA, 0x7A7A, 0x8A8A, 0x9A9A, 0xAAAA, 0xBABA, 0xCACA, 0xDADA, 0xEAEA,
0xFAFA 0xFAFA
Extension Name: RESERVED Extension Name: RESERVED
Recommended: Y Recommended: Y
Reference: RFC 9849 Reference: RFC 9849
Notes: Grease entries Notes: GREASE entries
12. References 12. References
12.1. Normative References 12.1. Normative References
[HPKE] Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid [HPKE] Barnes, R., Bhargavan, K., Lipp, B., and C. Wood, "Hybrid
Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180, Public Key Encryption", RFC 9180, DOI 10.17487/RFC9180,
February 2022, <https://www.rfc-editor.org/info/rfc9180>. February 2022, <https://www.rfc-editor.org/info/rfc9180>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC5890] Klensin, J., "Internationalized Domain Names for [RFC5890] Klensin, J., "Internationalized Domain Names for
Applications (IDNA): Definitions and Document Framework", Applications (IDNA): Definitions and Document Framework",
RFC 5890, DOI 10.17487/RFC5890, August 2010, RFC 5890, DOI 10.17487/RFC5890, August 2010,
<https://www.rfc-editor.org/info/rfc5890>. <https://www.rfc-editor.org/info/rfc5890>.
[RFC6125] Saint-Andre, P. and J. Hodges, "Representation and
Verification of Domain-Based Application Service Identity
within Internet Public Key Infrastructure Using X.509
(PKIX) Certificates in the Context of Transport Layer
Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March
2011, <https://www.rfc-editor.org/info/rfc6125>.
[RFC7918] Langley, A., Modadugu, N., and B. Moeller, "Transport [RFC7918] Langley, A., Modadugu, N., and B. Moeller, "Transport
Layer Security (TLS) False Start", RFC 7918, Layer Security (TLS) False Start", RFC 7918,
DOI 10.17487/RFC7918, August 2016, DOI 10.17487/RFC7918, August 2016,
<https://www.rfc-editor.org/info/rfc7918>. <https://www.rfc-editor.org/info/rfc7918>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26, Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017, RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>. <https://www.rfc-editor.org/info/rfc8126>.
skipping to change at line 2206 skipping to change at line 2175
[RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, "The [RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, "The
Datagram Transport Layer Security (DTLS) Protocol Version Datagram Transport Layer Security (DTLS) Protocol Version
1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022, 1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022,
<https://www.rfc-editor.org/info/rfc9147>. <https://www.rfc-editor.org/info/rfc9147>.
[RFC9460] Schwartz, B., Bishop, M., and E. Nygren, "Service Binding [RFC9460] Schwartz, B., Bishop, M., and E. Nygren, "Service Binding
and Parameter Specification via the DNS (SVCB and HTTPS and Parameter Specification via the DNS (SVCB and HTTPS
Resource Records)", RFC 9460, DOI 10.17487/RFC9460, Resource Records)", RFC 9460, DOI 10.17487/RFC9460,
November 2023, <https://www.rfc-editor.org/info/rfc9460>. November 2023, <https://www.rfc-editor.org/info/rfc9460>.
[RFCYYY1] Schwartz, B., Bishop, M., and E. Nygren, "Bootstrapping [RFC9525] Saint-Andre, P. and R. Salz, "Service Identity in TLS",
TLS Encrypted ClientHello with DNS Service Bindings", RFC 9525, DOI 10.17487/RFC9525, November 2023,
RFC YYY1, DOI 10.17487/RFCYYY1, November 2025, <https://www.rfc-editor.org/info/rfc9525>.
<https://www.rfc-editor.org/info/rfcYYY1>.
12.2. Informative References 12.2. Informative References
[DNS-TERMS] [DNS-TERMS]
Hoffman, P. and K. Fujiwara, "DNS Terminology", BCP 219, Hoffman, P. and K. Fujiwara, "DNS Terminology", BCP 219,
RFC 9499, DOI 10.17487/RFC9499, March 2024, RFC 9499, DOI 10.17487/RFC9499, March 2024,
<https://www.rfc-editor.org/info/rfc9499>. <https://www.rfc-editor.org/info/rfc9499>.
[ECH-Analysis] [ECH-Analysis]
Bhargavan, K., Cheval, V., and C. Wood, "A Symbolic Bhargavan, K., Cheval, V., and C. Wood, "A Symbolic
skipping to change at line 2287 skipping to change at line 2255
[RFC8744] Huitema, C., "Issues and Requirements for Server Name [RFC8744] Huitema, C., "Issues and Requirements for Server Name
Identification (SNI) Encryption in TLS", RFC 8744, Identification (SNI) Encryption in TLS", RFC 8744,
DOI 10.17487/RFC8744, July 2020, DOI 10.17487/RFC8744, July 2020,
<https://www.rfc-editor.org/info/rfc8744>. <https://www.rfc-editor.org/info/rfc8744>.
[RFC9250] Huitema, C., Dickinson, S., and A. Mankin, "DNS over [RFC9250] Huitema, C., Dickinson, S., and A. Mankin, "DNS over
Dedicated QUIC Connections", RFC 9250, Dedicated QUIC Connections", RFC 9250,
DOI 10.17487/RFC9250, May 2022, DOI 10.17487/RFC9250, May 2022,
<https://www.rfc-editor.org/info/rfc9250>. <https://www.rfc-editor.org/info/rfc9250>.
[RFCYYY1] Schwartz, B., Bishop, M., and E. Nygren, "Bootstrapping
TLS Encrypted ClientHello with DNS Service Bindings",
RFC YYY1, DOI 10.17487/RFCYYY1, December 2025,
<https://www.rfc-editor.org/info/rfcYYY1>.
[WHATWG-IPV4] [WHATWG-IPV4]
WHATWG, "URL - IPv4 Parser", WHATWG Living Standard, May WHATWG, "URL - IPv4 Parser", WHATWG Living Standard, May
2021, <https://url.spec.whatwg.org/#concept-ipv4-parser>. 2021, <https://url.spec.whatwg.org/#concept-ipv4-parser>.
Appendix A. Linear-Time Outer Extension Processing Appendix A. Linear-Time Outer Extension Processing
The following procedure processes the "ech_outer_extensions" The following procedure processes the "ech_outer_extensions"
extension (see Section 5.1) in linear time, ensuring that each extension (see Section 5.1) in linear time, ensuring that each
referenced extension in the ClientHelloOuter is included at most referenced extension in the ClientHelloOuter is included at most
once: once:
skipping to change at line 2338 skipping to change at line 2311
Kazuho Oku Kazuho Oku
Fastly Fastly
Email: kazuhooku@gmail.com Email: kazuhooku@gmail.com
Nick Sullivan Nick Sullivan
Cryptography Consulting LLC Cryptography Consulting LLC
Email: nicholas.sullivan+ietf@gmail.com Email: nicholas.sullivan+ietf@gmail.com
Christopher A. Wood Christopher A. Wood
Cloudflare Apple
Email: caw@heapingbits.net Email: caw@heapingbits.net
 End of changes. 48 change blocks. 
144 lines changed or deleted 117 lines changed or added

This html diff was produced by rfcdiff 1.48.