jiebi/TextFlow huggingface dataset:
Original text:
disadvantage that the server has to retain a table of all the server names it supports.]]  The semantics of this structure are simple: any of the listed keys may be used to encrypt the SNI for the associated domain name.  The cipher suite list is orthogonal to the list of keys, so each key may

Reviewer comments:
At the moment, there is no extensibility in ESNIKeys. That means that if we want to add additional attributes, we would be forced to define a new DNS record that gets queried simultaneously. I think we do not want to do that. Hence the extensions field. The text is tentative; please feel free to change in any ways.
LGTM.
With merged, I wonder if the ESNIKeys struct should just be renamed to something not specific to ESNI, but something more like "generic TLS config in DNS" so that it can be more cleanly reused by unrelated features. "ServerConfiguration" comes to mind from the early TLS 1.3 days.
If we were to re-use these keys for other purposes, that seems fine. However, I'm not sure we want to do that. Semi-static keys, for example, should ideally be separate.
The keys yes, but I imagine the extensions field can hold "arbitrary" data, so while the keys would be ESNI-specific, you could also include extensions that have nothing to do with ESNI.
Thinking about this some more, this would also require changing the "_esni." prefix to something else. In any case I can see how this might be out of scope for this spec. In the end it's a matter of deciding whether future TLS extensions that need similar DNS records, should be able to reuse the same structure (so no additional TXT record with its own prefix would be required), or if they should define their own structure (and have a separate TXT record). I'm happy to close this if it goes too much out of scope.
Right, I think it's verging on being out of scope. What do others think? NAME NAME
My preference goes to keeping the name as-is, considering the fact that the role of ESNIKeys is (at least for the moment) to negotiate properties between the client and the fronting server (not the hidden server), and that the only property we need to negotiate between the two is the information necessary for ESNI protection. It is true that the DNS record can covey properties related to the hidden server (as you know, I've argued for using it to carry the server certificate chain). But IMO that's a change of concept, and I prefer keeping the concept simple for the time being.
Ok.

Revised text:
disadvantage that the server has to retain a table of all the server names it supports.]] <ins> A list of extensions that the client can take into consideration when generating a Client Hello message.  The format is defined in I-D.ietf-tls-tls13; Section 4.2.  The purpose of the field is to provide room for additional features in the future; this document does not define any extension. </ins> The semantics of this structure are simple: any of the listed keys may be used to encrypt the SNI for the associated domain name.  The cipher suite list is orthogonal to the list of keys, so each key may
Original text:
10.4.4. <del> As more clients enable ECHO support, e.g., as normal part of Web browser functionality, with keys supplied by shared hosting providers, the presence of ECHO extensions becomes less suspicious and part of common or predictable client behavior.  In other words, if all Web browsers start using ECHO, the presence of this value does not signal suspicious behavior to passive eavesdroppers. Additionally, this specification allows for clients to send GREASE ECHO extensions (see grease-extensions), which helps ensure the ecosystem handles the values correctly. </del>  10.4.5.

Reviewer comments:
Addresses . cc NAME
There's no explicit signal indicating that ECHO was negotiated for a connection. Thus, clients must perform trial decryption with both possible handshake keys. If we intend to keep this, then we should crisply state that "don't stick out" is limited to explicit signals, i.e., implicit signals such as size-related information is probably out of scope. (It's certainly an open question what is the "best" padding scheme for handshake messages.) cc NAME

Revised text:
10.4.4.  <ins> The only explicit signal indicating possible use of ECHO is the ClientHello "encrypted_client_hello" extension.  Server handshake messages do not contain any signal indicating use or negotiation of ECHO.  Clients MAY GREASE the "encrypted_client_hello" extension, as described in grease-extensions, which helps ensure the ecosystem handles ECHO correctly.  Moreover, as more clients enable ECHO support, e.g., as normal part of Web browser functionality, with keys supplied by shared hosting providers, the presence of ECHO extensions becomes less unusual and part of typical client behavior.  In other words, if all Web browsers start using ECHO, the presence of this value will not signal unusual behavior to passive eavesdroppers. </ins> 10.4.5.
Original text:
10.2. <del> Supporting optional record digests and trial decryption opens oneself up to DoS attacks.  Specifically, an adversary may send malicious ClientHello messages, i.e., those which will not decrypt with any known ECHO key, in order to force decryption.  Servers that support this feature should, for example, implement some form of rate limiting mechanism to limit the damage caused by such attacks. </del>  10.3.

Reviewer comments:
Addresses . cc NAME
And possibly also include a bit inside ESNIConfig that tells clients whether or not to populate record_digest. (See URL for some relevant definitions.)
Works for me.

Revised text:
10.2.  <ins> Optional record digests may be useful in scenarios where clients and client-facing servers do not want to reveal information about the client-facing server in the "encrypted_client_hello" extension.  In such settings, servers must perform trial decrypt upon receipt of an empty record digest, which may exacerbate DoS attacks.  Specifically, an adversary may send malicious ClientHello messages, i.e., those which will not decrypt with any known ECHO key, in order to force wasteful decryption.  Servers that support this feature should, for example, implement some form of rate limiting mechanism to limit the damage caused by such attacks. </ins> 10.3.
Original text:
<del> Encrypted ClientHello for TLS 1.3 </del>  draft-ietf-tls-esni-latest Abstract <del> This document defines a mechanism for encrypting a TLS 1.3 ClientHello. </del>  1. Encrypted Client Hello (ECH), which allows clients to encrypt the entirety of their ClientHello to a supporting server.  This protects the SNI and other potentially sensitive fields, such as the ALPN <del> list. </del>  2.

Reviewer comments:
Seeing no pushback on the list, this moves the draft from Experimental to ST.
The design can apply to TLS 1.4 and beyond (presumably).
Done in .

Revised text:
 <ins> TLS Encrypted Client Hello </ins> draft-ietf-tls-esni-latest Abstract  <ins> This document describes a mechanism in Transport Layer Security (TLS) for encrypting a ClientHello message under a server public key. </ins> 1. Encrypted Client Hello (ECH), which allows clients to encrypt the entirety of their ClientHello to a supporting server.  This protects the SNI and other potentially sensitive fields, such as the ALPN  <ins> list.  This extension is only supported with (D)TLS 1.3 RFC8446 and newer versions of the protocol. </ins> 2.
Original text:
The ECHConfig structure contains the following fields: The version of the structure.  For this specification, that value <del> SHALL be 0xff03.  Clients MUST ignore any ECHConfig structure with </del>  a version they do not understand. An opaque byte string whose contents depend on the version of the 11.1. <del> IANA is requested to create an entry, encrypted_client_hello(0xffce), in the existing registry for ExtensionType (defined in RFC8446), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". </del>  11.2.

Reviewer comments:
Once we have some implementations that interop, we'll go ahead with early codepoint allocation. The new version matches -07, which will be the next draft version we submit. cc NAME NAME
We need to pick some values for the "encryptedclienthello(TBD)" and for the HTTPSSVC RR type before we can do interop. Allocating some values from the private ranges for those before draft-07 is pushed out would be good so we can do some interop testing. (Or for whatever is the next draft for which we want to do interop.)

Revised text:
The ECHConfig structure contains the following fields: The version of the structure.  For this specification, that value  <ins> SHALL be 0xff07.  Clients MUST ignore any ECHConfig structure with </ins> a version they do not understand. An opaque byte string whose contents depend on the version of the 11.1.  <ins> IANA is requested to create the following two entries in the existing registry for ExtensionType (defined in RFC8446): encrypted_client_hello(57), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". outer_extension(58), with the "TLS 1.3" column values being set to "CH", and "Recommended" column being set to "Yes". </ins> 11.2.
Original text:
The client then generates a ClientHelloInner value.  In addition to the normal values, ClientHelloInner MUST also contain: <del> an "ech_nonce" extension </del>  TLS padding RFC7685 (see padding) IANA is requested to create the following two entries in the existing registry for ExtensionType (defined in RFC8446): <del> encrypted_client_hello(57), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". </del>  <del> outer_extension(58), with the "TLS 1.3" column values being set to </del>  "CH", and "Recommended" column being set to "Yes".  11.2. IANA is requested to create an entry, ech_required(121) in the

Reviewer comments:
We'll request early codepoints after we get some implementation experience.
Yeah, as I was specifying the extension codepoint I noticed the collision between this variable, so I figured changing it here was best.
I have no objection to echononce -> echononce_value but did you mean to do it in this PR?

Revised text:
The client then generates a ClientHelloInner value.  In addition to the normal values, ClientHelloInner MUST also contain:  <ins> an "ech_nonce" extension, containing "ech_nonce_value" derived above </ins> TLS padding RFC7685 (see padding) IANA is requested to create the following two entries in the existing registry for ExtensionType (defined in RFC8446):  <ins> encrypted_client_hello(0xff02), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". </ins>  <ins> ech_nonce(0xff03), with the "TLS 1.3" column values being set to </ins> "CH", and "Recommended" column being set to "Yes". <ins> outer_extension(0xff04), with the "TLS 1.3" column values being set to "CH", and "Recommended" column being set to "Yes". </ins> 11.2. IANA is requested to create an entry, ech_required(121) in the
Original text:
Optional record digests may be useful in scenarios where clients and client-facing servers do not want to reveal information about the client-facing server in the "encrypted_client_hello" extension.  In <del> such settings, servers must perform trial decrypt upon receipt of an empty record digest, which may exacerbate DoS attacks.  Specifically, an adversary may send malicious ClientHello messages, i.e., those which will not decrypt with any known ECH key, in order to force wasteful decryption.  Servers that support this feature should, for example, implement some form of rate limiting mechanism to limit the damage caused by such attacks. </del>  10.4.

Reviewer comments:
As discussed on the list, add a small bit of text in the section 10.3 to outline the behavior of clients seeking to protect server's privacy.
Thanks!

Revised text:
Optional record digests may be useful in scenarios where clients and client-facing servers do not want to reveal information about the client-facing server in the "encrypted_client_hello" extension.  In  <ins> such settings, clients send either an empty record_digest or a randomly generated record_digest in the ClientEncryptedCH.  (The precise implementation choice for this mechanism is out of scope for this document.)  Servers in these settings must perform trial decryption since they cannot identify the client's chosen ECH key using the record_digest value.  As a result, support for optional record digests may exacerbate DoS attacks.  Specifically, an adversary may send malicious ClientHello messages, i.e., those which will not decrypt with any known ECH key, in order to force wasteful decryption.  Servers that support this feature should, for example, implement some form of rate limiting mechanism to limit the damage caused by such attacks. </ins> 10.4.
Original text:
The serialized and encrypted ClientHelloInner structure, AEAD- encrypted using HPKE with the selected KEM, KDF, and AEAD <del> algorithm and key generated as described below. </del>  If the server accepts ECH, it does not send this extension.  If it rejects ECH, then it sends the following structure in

Reviewer comments:
This ensures that each paragraph line breaks at 80 characters. No other change is intended (editorial or otherwise).
Do you want to borrow the linter that we use in QUIC? Just copy to your Makefile along with .
Brilliant!

Revised text:
The serialized and encrypted ClientHelloInner structure, AEAD- encrypted using HPKE with the selected KEM, KDF, and AEAD  <ins> algorithm and key generated as described below.  {:br} </ins> If the server accepts ECH, it does not send this extension.  If it rejects ECH, then it sends the following structure in
Original text:
[[OPEN ISSUE: An alternative to padding is to instead send a hash of the server name.  This would be fixed-length, but have the disadvantage that the server has to retain a table of all the server <del> names it supports.]] </del>  A list of extensions that the client can take into consideration when generating a Client Hello message.  The format is defined in

Reviewer comments:
The approach does not work if the mapping between the fronting server and the hidden server contains a wildcard.
LGTM!
Current text says: the "encryptedservername" extension. However, I am not sure if this is the desired behavior. I would rather suggest encrypting even when the hostname exceeds the padded_length. Having some protection is better than none. The issue is that in certain deployments it is impossible to guess what the maximum length of the hostname will be. Consider . It uses a wildcard certificate. Anybody can add a new hostname of any length by creating a new Github account (it might be true that Github some limitation on the length, but that does not necessarily mean that Github shares the maximum length information with the fronting CDN, assuming that it uses a CDN).
I have filed that fixes another issue (it's just a clarification of an open issue) related to wildcard delegation.
Technically, it is possible to guess the maximum length of the hostname, as that maximum textual representation length is defined as 253 bytes per RFC 1034.
Yes. So the question is if a CDN that has a wildcard mapping needs to set to 253 (since current text is a MUST NOT for sending a server name longer than the paddedlength), or if we should introduce a different rule.
How about something like: padded_length : The length to pad the ServerNameList value to prior to encryption. This value SHOULD be set to the largest ServerNameList the fronting server expects to support rounded up the nearest multiple of 16. If the fronting server supports wildcard names, it SHOULD set this value to 256.
NAME Thank you for the suggestion. I was feeling uneasy (and am still feeling a bit) about requiring the client to send an ESNI extension as large as ~300 bytes, assuming that CDN's would have at least one wildcard mappings. But it's about the first packet sent from the client, and we typically have enough room even when 0-RTT data is involved. So I think that we can live with that.
To be

Revised text:
[[OPEN ISSUE: An alternative to padding is to instead send a hash of the server name.  This would be fixed-length, but have the disadvantage that the server has to retain a table of all the server  <ins> names it supports, and will not work if the mapping between the fronting server and the hidden server uses wildcards.]] </ins> A list of extensions that the client can take into consideration when generating a Client Hello message.  The format is defined in
Original text:
server's length hint L (ECHCOnfig.maximum_name_length) when computing the padding as follows: <del> If L > D, add L - D bytes of padding.  This rounds to the server's advertised hint, i.e., ECHConfig.maximum_name_length. </del>  <del> Otherwise, add 32 - (D % 32) bytes of padding.  This rounds D up to the nearest multiple of 32 bytes. </del>  In addition to padding ClientHelloInner, clients and servers will also need to pad all other handshake messages that have sensitive-

Reviewer comments:
Consider the following values for L and D, where L is the server's hint and D is the length of the domain name. This change pads D according to the following rules. D1: D L is at least 32 elements. Thanks, NAME
cc NAME NAME NAME NAME NAME
TBH I am not sure that this is worth it, but I believe it is correct.
Section 7.2 says This has some problems: If L == D, or D > L and D % 32 == 0, this results in unnecessary padding. If L == D == 31, there is no length protection. The output is 32, and that is the only length that produces that output. The easiest solution is to replace "32 - (D % 32)" with "(L - D) & 0x1f". This pads up to the nearest L + 32*n. If it's considered important to pad to a multiple of 32, I would suggest ensuring that the initial bucket is at least 32, e.g.

Revised text:
server's length hint L (ECHCOnfig.maximum_name_length) when computing the padding as follows:  <ins> If L >= D, add L - D bytes of padding.  This rounds to the server's advertised hint, i.e., ECHConfig.maximum_name_length. </ins>  <ins> Otherwise, let P = 31 - ((D - 1) % 32), and add P bytes of padding, plus an additional 32 bytes if D + P < L + 32.  This rounds D up to the nearest multiple of 32 bytes that permits at least 32 bytes of length ambiguity. </ins> In addition to padding ClientHelloInner, clients and servers will also need to pad all other handshake messages that have sensitive-
Original text:
OuterExtensions.hash, the server aborts the connection with an "illegal_parameter" alert. <del> Clients SHOULD only use this mechanism for extensions which are large.  All other extensions SHOULD appear in both ClientHelloInner and ClientHelloOuter even if they have identical values. </del> 7. 7.1.

Reviewer comments:
This addresses .
In Section 6.1: if I were implementing this extension, I think the simplest thing would be to compress all copied extensions by default: it's not computationally intensive; it minimizes bandwidth overhead; and it's simpler for future "big" extensions, since no code changes would be needed here. I suggest removing this guidance.
addresses this issue.

Revised text:
OuterExtensions.hash, the server aborts the connection with an "illegal_parameter" alert.  7. 7.1.
Original text:
Otherwise, when the handshake completes successfully with the public name authenticated, the client MUST abort the connection with an <del> "ech_required" alert.  It then processes the "retry_keys" field from the server's "encrypted_client_hello" extension. </del>  If one of the values contains a version supported by the client, it can regard the ECH keys as securely replaced by the server.  It introducing pinning concerns or a tracking vector, should a malicious server present client-specific retry keys to identify clients. <del> If none of the values provided in "retry_keys" contains a supported version, the client can regard ECH as securely disabled by the server.  As below, it SHOULD then retry the handshake with a new </del>  transport connection and ECH disabled. If the field contains any other value, the client MUST abort the connection, with the following added behavior: It MUST include the "encrypted_client_hello" extension with the <del> "retry_keys" field set to one or more ECHConfig structures with </del>  up-to-date keys.  Servers MAY supply multiple ECHConfig values of different versions.  This allows a server to support multiple versions at once.

Reviewer comments:
Addresses
The spec uses both and when referring to the contents of . These should be made consistent (preferably using the former).
Agreed -- let's unify around ! Would you be able to propose text?
( is a remnant of the old name. I guess we missed a few.)
Thanks!

Revised text:
Otherwise, when the handshake completes successfully with the public name authenticated, the client MUST abort the connection with an  <ins> "ech_required" alert.  It then processes the "retry_configs" field from the server's "encrypted_client_hello" extension. </ins> If one of the values contains a version supported by the client, it can regard the ECH keys as securely replaced by the server.  It introducing pinning concerns or a tracking vector, should a malicious server present client-specific retry keys to identify clients.  <ins> If none of the values provided in "retry_configs" contains a supported version, the client can regard ECH as securely disabled by the server.  As below, it SHOULD then retry the handshake with a new </ins> transport connection and ECH disabled. If the field contains any other value, the client MUST abort the connection, with the following added behavior: It MUST include the "encrypted_client_hello" extension with the  <ins> "retry_configs" field set to one or more ECHConfig structures with </ins> up-to-date keys.  Servers MAY supply multiple ECHConfig values of different versions.  This allows a server to support multiple versions at once.
Original text:
carrying the "HpkePublicKey" and KEM identifier corresponding to the server, clients compute an HPKE encryption context as follows: <del> Note that the HPKE algorithm identifiers are those which match the client's chosen preference from "ECHConfig.cipher_suites". </del>  The client then generates a ClientHelloInner value.  In addition to the normal values, ClientHelloInner MUST also contain:

Reviewer comments:
draft-irtf-cfrg-hpke-05 switched from Unmarshal to Deserialize. Switch ECH to match. See .
Cause I'm quite new to ECH, I'm little bit confused when reading this draft. So I want to ask some questions... Paragraph 7.1. Sending an encrypted ClientHello says... Q1. Is 'Unmarshal()' above equal to general meaning of unmarshalling -get public key from ECHConfig structure- ? Q2. I think 'hrr' in the fourth line is the abbreviation of 'HelloRetryRequest', is it correct? If so, could you add some explanation about that?
Q1: It should be defined in the HPKE draft, though it looks like the HPKE draft has since renamed it and it should probably say Deserialize now. URL Q2: hrr is HelloRetryRequest, yes. The use of the key is described later on in the HelloRetryRequest section. URL
The first line appears to be pseudocode for "interpret as a public key for the KEM algorithm identified by . IMO we should get rid of this pseudocode and say what is. NAME beat me to it!
Oh, it was Deserialize()... thanks!
Closing as resolved.

Revised text:
carrying the "HpkePublicKey" and KEM identifier corresponding to the server, clients compute an HPKE encryption context as follows:  <ins> Note that the HPKE functions Deserialize and SetupBaseS are those which match "ECHConfig.kem_id" and the client's chosen preference from "ECHConfig.cipher_suites". </ins> The client then generates a ClientHelloInner value.  In addition to the normal values, ClientHelloInner MUST also contain: