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 76 skipping to change at line 76
6.1.4. Determining ECH Acceptance 6.1.4. Determining ECH Acceptance
6.1.5. Handshaking with ClientHelloInner 6.1.5. Handshaking with ClientHelloInner
6.1.6. Handshaking with ClientHelloOuter 6.1.6. Handshaking with ClientHelloOuter
6.1.7. Authenticating for the Public Name 6.1.7. Authenticating for the Public Name
6.1.8. Impact of Retry on Future Connections 6.1.8. Impact of Retry on Future Connections
6.2. GREASE ECH 6.2. GREASE ECH
6.2.1. Client Greasing 6.2.1. Client Greasing
6.2.2. Server Greasing 6.2.2. Server Greasing
7. Server Behavior 7. Server Behavior
7.1. Client-Facing Server 7.1. Client-Facing Server
7.1.1. Sending HelloRetryRequest 7.1.1. Processing ClientHello after HelloRetryRequest
7.2. Backend Server 7.2. Backend Server
7.2.1. Sending HelloRetryRequest 7.2.1. Sending HelloRetryRequest
8. Deployment Considerations 8. Deployment Considerations
8.1. Compatibility Issues 8.1. Compatibility Issues
8.1.1. Misconfiguration and Deployment Concerns 8.1.1. Misconfiguration and Deployment Concerns
8.1.2. Middleboxes 8.1.2. Middleboxes
8.2. Deployment Impact 8.2. Deployment Impact
9. Compliance Requirements 9. Compliance Requirements
10. Security Considerations 10. Security Considerations
10.1. Security and Privacy Goals 10.1. Security and Privacy Goals
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 465 skipping to change at line 465
uses the inner variant. The inner extension has an empty payload, uses the inner variant. The inner extension has an empty payload,
which is included because TLS servers are not allowed to provide which is included because TLS servers are not allowed to provide
extensions in ServerHello which were not included in ClientHello. extensions in ServerHello which were not included in ClientHello.
The outer extension has the following fields: The outer extension has the following fields:
config_id: The ECHConfigContents.key_config.config_id for the chosen config_id: The ECHConfigContents.key_config.config_id for the chosen
ECHConfig. ECHConfig.
cipher_suite: The cipher suite used to encrypt ClientHelloInner. cipher_suite: The cipher suite used to encrypt ClientHelloInner.
This MUST match a value provided in the corresponding This MUST match a value provided in the corresponding
ECHConfigContents.cipher_suites list. ECHConfigContents.key_config.cipher_suites list.
enc: The HPKE encapsulated key used by servers to decrypt the enc: The HPKE encapsulated key used by servers to decrypt the
corresponding payload field. This field is empty in a corresponding payload field. This field is empty in a
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"
skipping to change at line 523 skipping to change at line 523
struct { struct {
ClientHello client_hello; ClientHello client_hello;
uint8 zeros[length_of_padding]; uint8 zeros[length_of_padding];
} EncodedClientHelloInner; } 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- the Handshake structure's four-byte header in TLS, nor the twelve-
byte header in DTLS. The zeros field MUST be all zeroes of length byte header in DTLS. The zeros field MUST be all zeros 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) ech_outer_extensions(0xfd00), (65535)
} ExtensionType; } ExtensionType;
ExtensionType OuterExtensions<2..254>; ExtensionType OuterExtensions<2..254>;
OuterExtensions contains the removed ExtensionType values. Each OuterExtensions contains a list of the removed ExtensionType values.
value references the matching extension in ClientHelloOuter. The Each value references the matching extension in ClientHelloOuter.
values MUST be ordered contiguously in ClientHelloInner, and the 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.
The "ech_outer_extensions" extension can only be included in The "ech_outer_extensions" extension can only be included in
EncodedClientHelloInner and MUST NOT appear in either EncodedClientHelloInner and MUST NOT appear in either
ClientHelloOuter or ClientHelloInner. ClientHelloOuter or ClientHelloInner.
skipping to change at line 588 skipping to change at line 588
* "encrypted_client_hello" is referenced in OuterExtensions. * "encrypted_client_hello" is referenced in OuterExtensions.
* The extensions in ClientHelloOuter corresponding to those in * The extensions in ClientHelloOuter corresponding to those in
OuterExtensions do not occur in the same order. OuterExtensions do not occur in the same order.
These requirements prevent an attacker from performing a packet These requirements prevent an attacker from performing a packet
amplification attack by crafting a ClientHelloOuter which amplification attack by crafting a ClientHelloOuter which
decompresses to a much larger ClientHelloInner. This is discussed decompresses to a much larger ClientHelloInner. This is discussed
further in Section 10.12.4. further in Section 10.12.4.
Implementations SHOULD construct the ClientHelloInner in linear time. Receiving implementations SHOULD construct the ClientHelloInner in
Quadratic time implementations (such as may happen via naive copying) linear time. Quadratic time implementations (such as may happen via
create a denial-of-service risk. Appendix A describes a linear-time naive copying) create a denial-of-service risk. Appendix A describes
procedure that may be used for this purpose. a linear-time procedure that may be used for this purpose.
5.2. Authenticating the ClientHelloOuter 5.2. Authenticating the ClientHelloOuter
To prevent a network attacker from modifying the ClientHelloOuter To prevent a network attacker from modifying the ClientHelloOuter
while keeping the same encrypted ClientHelloInner (see while keeping the same encrypted ClientHelloInner (see
Section 10.12.3), ECH authenticates ClientHelloOuter by passing Section 10.12.3), ECH authenticates ClientHelloOuter by passing
ClientHelloOuterAAD as the associated data for HPKE sealing and ClientHelloOuterAAD as the associated data for HPKE sealing and
opening operations. The ClientHelloOuterAAD is a serialized opening operations. The ClientHelloOuterAAD is a serialized
ClientHello structure, defined in Section 4.1.2 of [RFC8446] for TLS ClientHello structure, defined in Section 4.1.2 of [RFC8446] for TLS
and Section 5.3 of [RFC9147] for DTLS, which matches the and Section 5.3 of [RFC9147] for DTLS, which matches the
ClientHelloOuter except that the payload field of the ClientHelloOuter except that the payload field of the
"encrypted_client_hello" is replaced with a byte string of the same "encrypted_client_hello" is replaced with a byte string of the same
length but whose contents are zeros. This value does not include length but whose contents are zeros. This value does not include the
Handshake structure's four-byte header in TLS nor twelve-byte header Handshake structure's four-byte header in TLS nor the twelve-byte
in DTLS. header in DTLS.
6. Client Behavior 6. Client Behavior
Clients that implement the ECH extension behave in one of two ways: Clients that implement the ECH extension behave in one of two ways:
either they offer a real ECH extension, as described in Section 6.1, either they offer a real ECH extension, as described in Section 6.1,
or they send a Generate Random Extensions And Sustain Extensibility or they send a Generate Random Extensions And Sustain Extensibility
(GREASE) [RFC8701] ECH extension, as described in Section 6.2. (GREASE) [RFC8701] ECH extension, as described in Section 6.2. The
Clients of the latter type do not negotiate ECH. Instead, they client offers ECH if it is in possession of a compatible ECH
configuration and sends GREASE ECH (see Section 6.2) otherwise.
Clients of the latter type do not negotiate ECH; instead, they
generate a dummy ECH extension that is ignored by the server. (See generate a dummy ECH extension that is ignored by the server. (See
Section 10.10.4 for an explanation.) The client offers ECH if it is Section 10.10.4 for an explanation.) It is also possible for clients
in possession of a compatible ECH configuration and sends GREASE ECH to always send GREASE ECH without implementing the remainder of this
(see Section 6.2) otherwise. specification.
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.key_config.kem_id, at least one KDF/AEAD algorithm
by ECHConfig.contents.cipher_suites, and the version of ECH indicated identified by ECHConfig.contents.key_config.cipher_suites, and the
by ECHConfig.contents.version. Once a suitable configuration is version of ECH indicated by ECHConfig.version. Once a suitable
found, the client selects the cipher suite it will use for configuration is found, the client selects the cipher suite it will
encryption. It MUST NOT choose a cipher suite or version not use for encryption. It MUST NOT choose a cipher suite or version not
advertised by the configuration. If no compatible configuration is advertised by the configuration. If no compatible configuration is
found, then the client SHOULD proceed as described in Section 6.2. found, then the 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.
skipping to change at line 655 skipping to change at line 657
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.key_config.public_key)
enc, context = SetupBaseS(pkR, enc, 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 812 skipping to change at line 814
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 847 skipping to change at line 849
EncryptedExtension, so that handshake message also needs to be padded EncryptedExtension, so that handshake message also needs to be padded
using TLS record layer padding. using TLS record layer padding.
6.1.4. Determining ECH Acceptance 6.1.4. Determining ECH Acceptance
As described in Section 7, the server may either accept ECH and use As described in Section 7, the server may either accept ECH and use
ClientHelloInner or reject it and use ClientHelloOuter. This is ClientHelloInner or reject it and use ClientHelloOuter. This is
determined by the server's initial message. determined by the server's initial message.
If the message does not negotiate TLS 1.3 or higher, the server has If the message does not negotiate TLS 1.3 or higher, the server has
rejected ECH. Otherwise, it is either a ServerHello or rejected ECH. Otherwise, the message will be either a ServerHello or
HelloRetryRequest. a HelloRetryRequest.
If the message is a ServerHello, the client computes If the message is a ServerHello, the client computes
accept_confirmation as described in Section 7.2. If this value accept_confirmation as described in Section 7.2. If this value
matches the last 8 bytes of ServerHello.random, the server has matches the last 8 bytes of ServerHello.random, the server has
accepted ECH. Otherwise, it has rejected ECH. accepted ECH. Otherwise, it has rejected ECH.
If the message is a HelloRetryRequest, the client checks for the If the message is a HelloRetryRequest, the client checks for the
"encrypted_client_hello" extension. If none is found, the server has "encrypted_client_hello" extension. If none is found, the server has
rejected ECH. Otherwise, if it has a length other than 8, the client rejected ECH. Otherwise, if the extension has a length other than 8,
aborts the handshake with a "decode_error" alert. Otherwise, the the client MUST abort the handshake with a "decode_error" alert.
client computes hrr_accept_confirmation as described in Otherwise, the client computes hrr_accept_confirmation as described
Section 7.2.1. If this value matches the extension payload, the in Section 7.2.1. If this value matches the extension payload, the
server has accepted ECH. Otherwise, it has rejected ECH. server has accepted ECH. Otherwise, it has rejected ECH.
If the server accepts ECH, the client handshakes with If the server accepts ECH, the client handshakes with
ClientHelloInner as described in Section 6.1.5. Otherwise, the ClientHelloInner as described in Section 6.1.5. Otherwise, the
client handshakes with ClientHelloOuter as described in client handshakes with ClientHelloOuter as described in
Section 6.1.6. Section 6.1.6.
6.1.5. Handshaking with ClientHelloInner 6.1.5. Handshaking with ClientHelloInner
If the server accepts ECH, the client proceeds with the connection as If the server accepts ECH, the client proceeds with the connection as
skipping to change at line 940 skipping to change at line 942
processing described below and then abort the connection with an processing described below and then abort the connection with an
"ech_required" alert before sending any application data to the "ech_required" alert before sending any application data to the
server. server.
If the server provided "retry_configs" and if at least one of the If the server provided "retry_configs" and if at least one of the
values contains a version supported by the client, the client can values contains a version supported by the client, the client can
regard the ECH configuration as securely replaced by the server. It regard the ECH configuration as securely replaced by the server. It
SHOULD retry the handshake with a new transport connection using the SHOULD retry the handshake with a new transport connection using the
retry configurations supplied by the server. retry configurations supplied by the server.
Clients can implement a new transport connection in a way that best Because the new ECH configuration replaces the old ECH configuration,
suits their deployment. For example, clients can reuse the same clients can implement a new transport connection in any way that is
server IP address when establishing the new transport connection or consistent with the previous ECH configuration. For example, clients
they can choose to use a different IP address if provided with can reuse the same server IP address when establishing the new
options from DNS. ECH does not mandate any specific implementation transport connection or they can choose to use a different IP address
choices when establishing this new connection. if DNS provided other IP addresses for the previous configuration.
However, it is not safe to use IP addresses discovered with a new DNS
query, as those may correspond to a different ECH server
configuration, for instance associated with a different ECH server
with a different public_name.
The retry configurations are meant to be used for retried The retry configurations are meant to be used for retried
connections. Further use of retry configurations could yield a connections. Further use of retry configurations could yield a
tracking vector. In settings where the client will otherwise already tracking vector. In settings where the client will otherwise already
let the server track the client, e.g., because the client will send let the server track the client, e.g., because the client will send
cookies to the server in parallel connections, using the retry cookies to the server in parallel connections, using the retry
configurations for these parallel connections does not introduce a configurations for these parallel connections does not introduce a
new tracking vector. new tracking vector.
If none of the values provided in "retry_configs" contains a If none of the values provided in "retry_configs" contains a
skipping to change at line 977 skipping to change at line 983
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
retries, as described in Section 6.1.6. This may be implemented, for retries, as described in Section 6.1.6. This may be implemented, for
instance, by reporting a failed connection with a dedicated error instance, by reporting a failed connection with a dedicated error
code. code.
Prior to attempting a connection, a client SHOULD validate the Prior to attempting a connection, a client SHOULD validate the
ECHConfig. Clients SHOULD ignore any ECHConfig structure with a ECHConfig.contents.public_name. Clients SHOULD ignore any ECHConfig
public_name that is not a valid host name in preferred name syntax structure with a public_name that is not a valid host name in
(see Section 2 of [DNS-TERMS]). That is, to be valid, the preferred name syntax (see Section 2 of [DNS-TERMS]). That is, to be
public_name needs to be a dot-separated sequence of LDH labels, as valid, the public_name needs to be a dot-separated sequence of LDH
defined in Section 2.3.1 of [RFC5890], where: labels, as defined in Section 2.3.1 of [RFC5890], where:
* the sequence does not begin or end with an ASCII dot, and * the sequence does not begin or end with an ASCII dot, and
* all labels are at most 63 octets. * all labels are at most 63 octets.
Clients additionally SHOULD ignore the structure if the final LDH Clients additionally SHOULD ignore the structure if the final LDH
label either consists of all ASCII digits (i.e., '0' through '9') or label either consists of all ASCII digits (i.e., '0' through '9') or
is "0x" or "0X" followed by some, possibly empty, sequence of ASCII is "0x" or "0X" followed by some, possibly empty, sequence of ASCII
hexadecimal digits (i.e., '0' through '9', 'a' through 'f', and 'A' hexadecimal digits (i.e., '0' through '9', 'a' through 'f', and 'A'
through 'F'). This avoids public_name values that may be interpreted through 'F'). This avoids public_name values that may be interpreted
skipping to change at line 1071 skipping to change at line 1077
6.2.1. Client Greasing 6.2.1. Client Greasing
If the client attempts to connect to a server and does not have an If the client attempts to connect to a server and does not have an
ECHConfig structure available for the server, it SHOULD send a GREASE ECHConfig structure available for the server, it SHOULD send a GREASE
[RFC8701] "encrypted_client_hello" extension in the first ClientHello [RFC8701] "encrypted_client_hello" extension in the first ClientHello
as follows: as follows:
* Set the config_id field to a random byte. * Set the config_id field to a random byte.
* Set the cipher_suite field to a supported * Set the cipher_suite field to a supported
HpkeSymmetricCipherSuite. The selection SHOULD vary to exercise HpkeSymmetricCipherSuite. The selection SHOULD vary, so that all
all supported configurations, but MAY be held constant for plausible configurations are exercised, but MAY be held constant
successive connections to the same server in the same session. for successive connections to the same server in the same session.
Note: A "plausible" configuration is one that an observer might
expect to see. A client that fully supports ECH will have a set
of supported HPKE cipher suites to select from. A client that
only supports GREASE ECH has no such list, so it should select
from a set of values that are in common usage.
* Set the enc field to a randomly generated valid encapsulated * Set the enc field to a randomly generated valid encapsulated
public key output by the HPKE KEM. public key output by the HPKE KEM.
* Set the payload field to a randomly generated string of L+C bytes, * Set the payload field to a randomly generated string of L+C bytes,
where C is the ciphertext expansion of the selected AEAD scheme where C is the ciphertext expansion of the selected AEAD scheme
and L is the size of the EncodedClientHelloInner the client would and L is the size of the EncodedClientHelloInner the client would
compute when offering ECH, padded according to Section 6.1.3. compute when offering ECH, padded according to Section 6.1.3.
If sending a second ClientHello in response to a HelloRetryRequest, If sending a second ClientHello in response to a HelloRetryRequest,
skipping to change at line 1131 skipping to change at line 1142
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.
If ECHClientHello.type is not a valid ECHClientHelloType, then the
server MUST abort with an "illegal_parameter" alert.
In split mode, a client-facing server which receives a ClientHello In split mode, a client-facing server which receives a ClientHello
with ECHClientHello.type of inner MUST abort with an with ECHClientHello.type of inner MUST abort with an
"illegal_parameter" alert. Similarly, in split mode, a backend "illegal_parameter" alert. Similarly, in split mode, a backend
server which receives a ClientHello with ECHClientHello.type of outer server which receives a ClientHello with ECHClientHello.type of outer
MUST abort with an "illegal_parameter" alert. MUST abort with an "illegal_parameter" alert.
In shared mode, a server plays both roles, first decrypting the In shared mode, a server plays both roles, first decrypting the
ClientHelloOuter and then using the contents of the ClientHelloInner. ClientHelloOuter and then using the contents of the ClientHelloInner.
A shared mode server which receives a ClientHello with A shared mode server which receives a ClientHello with
ECHClientHello.type of inner MUST abort with an "illegal_parameter" ECHClientHello.type of inner MUST abort with an "illegal_parameter"
alert, because such a ClientHello should never be received directly alert, because such a ClientHello should never be received directly
from the network. from the network.
If ECHClientHello.type is not a valid ECHClientHelloType, then the
server MUST abort with an "illegal_parameter" alert.
If the "encrypted_client_hello" is not present, then the server If the "encrypted_client_hello" is not present, then the server
completes the handshake normally, as described in [RFC8446]. completes the handshake normally, as described in [RFC8446].
7.1. Client-Facing Server 7.1. Client-Facing Server
Upon receiving an "encrypted_client_hello" extension in an initial Upon receiving an "encrypted_client_hello" extension in an initial
ClientHello, the client-facing server determines if it will accept ClientHello, the client-facing server determines if it will accept
ECH prior to negotiating any other TLS parameters. Note that ECH prior to negotiating any other TLS parameters. Note that
successfully decrypting the extension will result in a new successfully decrypting the extension will result in a new
ClientHello to process, so even the client's TLS version preferences ClientHello to process, so even the client's TLS version preferences
skipping to change at line 1201 skipping to change at line 1212
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 || ECHConfig) "tls ech" || 0x00 || ECHConfig)
EncodedClientHelloInner = context.Open(ClientHelloOuterAAD, EncodedClientHelloInner = 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 1259 skipping to change at line 1270
support multiple versions at once. support multiple versions at once.
Note that decryption failure could indicate a GREASE ECH extension Note that decryption failure could indicate a GREASE ECH extension
(see Section 6.2), so it is necessary for servers to proceed with the (see Section 6.2), so it is necessary for servers to proceed with the
connection and rely on the client to abort if ECH was required. In connection and rely on the client to abort if ECH was required. In
particular, the unrecognized value alone does not indicate a particular, the unrecognized value alone does not indicate a
misconfigured ECH advertisement (Section 8.1.1). Instead, servers misconfigured ECH advertisement (Section 8.1.1). Instead, servers
can measure occurrences of the "ech_required" alert to detect this can measure occurrences of the "ech_required" alert to detect this
case. case.
7.1.1. Sending HelloRetryRequest 7.1.1. Processing ClientHello after HelloRetryRequest
After sending or forwarding a HelloRetryRequest, the client-facing After sending or forwarding a HelloRetryRequest, the client-facing
server does not repeat the steps in Section 7.1 with the second server does not repeat the steps in Section 7.1 with the second
ClientHelloOuter. Instead, it continues with the ECHConfig selection ClientHelloOuter. Instead, it continues with the ECHConfig selection
from the first ClientHelloOuter as follows: from the first ClientHelloOuter as follows:
If the client-facing server accepted ECH, it checks that the second If the client-facing server accepted ECH, it checks that the second
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 1375 skipping to change at line 1386
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
discussed in Section 8.1. discussed in Section 8.1.
Beyond coordination difficulties, ECH deployments may also induce Beyond coordination difficulties, ECH deployments may also create
challenges for use cases of information that ECH protects. In challenges for uses of information that ECH protects. In particular,
particular, use cases which depend on this unencrypted information use cases which depend on this unencrypted information may no longer
may no longer work as desired. This is elaborated upon in work as desired. This is elaborated upon in Section 8.2.
Section 8.2.
8.1. Compatibility Issues 8.1. Compatibility Issues
Unlike most TLS extensions, placing the SNI value in an ECH extension Unlike most TLS extensions, placing the SNI value in an ECH extension
is not interoperable with existing servers, which expect the value in is not interoperable with existing servers, which expect the value in
the existing plaintext extension. Thus, server operators SHOULD the existing plaintext extension. Thus, server operators SHOULD
ensure servers understand a given set of ECH keys before advertising ensure servers understand a given set of ECH keys before advertising
them. Additionally, servers SHOULD retain support for any previously them. Additionally, servers SHOULD retain support for any previously
advertised keys for the duration of their validity. advertised keys for the duration of their validity.
skipping to change at line 1501 skipping to change at line 1511
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 1626 skipping to change at line 1636
perform trial decryption since they cannot identify the client's perform trial decryption since they cannot identify the client's
chosen ECH key using the config_id value. As a result, ignoring chosen ECH key using the config_id value. As a result, ignoring
configuration identifiers may exacerbate DoS attacks. Specifically, configuration identifiers may exacerbate DoS attacks. Specifically,
an adversary may send malicious ClientHello messages, i.e., those an adversary may send malicious ClientHello messages, i.e., those
which will not decrypt with any known ECH key, in order to force which will not decrypt with any known ECH key, in order to force
wasteful decryption. Servers that support this feature should, for wasteful decryption. Servers that support this feature should, for
example, implement some form of rate limiting mechanism to limit the example, implement some form of rate limiting mechanism to limit the
potential damage caused by such attacks. potential damage caused by such attacks.
Unless specified by the application using (D)TLS or externally Unless specified by the application using (D)TLS or externally
configured, implementations MUST NOT use this mode. configured, client implementations MUST NOT use this mode.
10.5. Outer ClientHello 10.5. Outer ClientHello
Any information that the client includes in the ClientHelloOuter is Any information that the client includes in the ClientHelloOuter is
visible to passive observers. The client SHOULD NOT send values in visible to passive observers. The client SHOULD NOT send values in
the ClientHelloOuter which would reveal a sensitive ClientHelloInner the ClientHelloOuter which would reveal a sensitive ClientHelloInner
property, such as the true server name. It MAY send values property, such as the true server name. It MAY send values
associated with the public name in the ClientHelloOuter. associated with the public name in the ClientHelloOuter.
In particular, some extensions require the client send a server-name- In particular, some extensions require the client send a server-name-
skipping to change at line 1709 skipping to change at line 1719
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 1869
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 1936 skipping to change at line 1946
{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: because the attacker
the attacker does not have access to this value, it cannot produce does not have access to this value, it cannot produce the right
the right transcript and handshake keys needed for encrypting the transcript and handshake keys needed for encrypting the Certificate
Certificate message. Thus, the client will fail to decrypt the message. Thus, the client will fail to decrypt the Certificate and
Certificate and abort the connection. abort the connection.
10.12.2. HelloRetryRequest Hijack Mitigation 10.12.2. HelloRetryRequest Hijack Mitigation
This attack aims to exploit server HRR state management to recover This attack aims to exploit server HRR state management to recover
information about a legitimate ClientHello using its own attacker- information about a legitimate ClientHello using its own attacker-
controlled ClientHello. To begin, the attacker intercepts and controlled ClientHello. To begin, the attacker intercepts and
forwards a legitimate ClientHello with an "encrypted_client_hello" forwards a legitimate ClientHello with an "encrypted_client_hello"
(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
skipping to change at line 2074 skipping to change at line 2084
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 2123
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 2157
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 2209
[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 2289
[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 2333 skipping to change at line 2340
Authors' Addresses Authors' Addresses
Eric Rescorla Eric Rescorla
Independent Independent
Email: ekr@rtfm.com Email: ekr@rtfm.com
Kazuho Oku Kazuho Oku
Fastly Fastly
Email: kazuhooku@gmail.com Email: kazuhooku@gmail.com
Additional contact information:
奥 一穂
Fastly
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. 52 change blocks. 
109 lines changed or deleted 121 lines changed or added

This html diff was produced by rfcdiff 1.48.