jiebi/CodeConvo huggingface dataset:
Change:
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?

Discussion:
The client then generates a ClientHelloInner value.  In addition to the normal values, ClientHelloInner MUST also contain: <del> an "ech_nonce" extension </del> <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): <del> encrypted_client_hello(57), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". </del> <ins> encrypted_client_hello(0xff02), with "TLS 1.3" column values being set to "CH, EE", and "Recommended" column being set to "Yes". </ins> <del> outer_extension(58), with the "TLS 1.3" column values being set to </del> <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
Change:
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!

Discussion:
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> <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.
Change:
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!

Discussion:
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> <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
Change:
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

Discussion:
[[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> <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
Change:
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.

Discussion:
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> <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> <del> Otherwise, add 32 - (D % 32) bytes of padding.  This rounds D up to the nearest multiple of 32 bytes. </del> <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-
Change:
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.

Discussion:
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.
Change:
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!

Discussion:
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> <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. <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> <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 <del> "retry_keys" field set to one or more ECHConfig structures with </del> <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.
Change:
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.

Discussion:
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> <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:
Change:
While reading the draft, I'm confused with ClientEncryptedCH structure. Section : The "encryptedclienthello" extension says... ~ >enc : The HPKE encapsulated key, used by servers to decrypt the corresponding field. >encryptedch : The serialized and encrypted ClientHelloInner structure, encrypted using HPKE as described in {{send-ech}}. and Section : Sending an encrypted ClientHello says... >The encrypted ClientHello value is then computed as: ~ Cause output of the context.Seal() function is ciphertext output of AEAD encryption (According to draft-irtf-cfrg-hpke-05), I think encryptedch has only ciphertext value of the ClientHelloInner, not the enc value. But the same section also says... >encryptedch contains the HPKE encapsulated key (enc) and the ClientHelloInner ciphertext (encryptedchinner). Q. Does encryptedch have enc and encryptedchinner? Or it just has the ciphertext of ClientHelloInner and encryptedch_inner is just mistype?
Nice catch! should just be the AEAD ciphertext. The following text is wrong: ciphertext (encryptedch_inner). It should be: cc/ NAME
OK, there's no .. thanks!

Discussion:
enc contains the encapsulated key as output by SetupBaseS; and <del> encrypted_ch contains the HPKE encapsulated key (enc) and the ClientHelloInner ciphertext (encrypted_ch_inner). </del> <ins> encrypted_ch contains the AEAD-encrypted ClientHelloInner. </ins> The client MUST place the value of "ECHConfig.public_name" in the ClientHelloOuter "server_name" extension.  See outer-clienthello for
Change:
Section 6: implementations to track, alongside each PSK established by a previous connection, whether the connection negotiated this extension with the "echaccept" response type. If so, this is referred to as an "ECH PSK". Otherwise, it is a "non-ECH PSK". This may be implemented by adding a new field to client and server session states. "echaccept" is not defined anywhere.
I suspect "the connection negotiated this extension with the 'ech_accept' response type" is an incorrect way of saying that ECH was accepted.

Discussion:
Per client-behavior and server-behavior, implementations are required to track, alongside each PSK established by a previous connection, <del> whether the connection negotiated this extension with the "ech_accept" response type.  If so, this is referred to as an "ECH PSK".  Otherwise, it is a "non-ECH PSK".  This may be implemented by adding a new field to client and server session states. </del> <ins> whether ECH was accepted for this connection.  If so, this is referred to as an "ECH PSK".  Otherwise, it is a "non-ECH PSK".  This may be implemented by adding a new field to client and server session states. </ins> 6.1.
Change:
See
This looks good to me. Clarifying the requirements rather than specifying how to act makes more sense here. FWIW, I thought the intent of the original text was to encourage not having ESNIKeys shared between multiple hosts whenever possible. This change loses that property. But anyways, that is mentioned in the appendix. Hence my :+1: to the PR.
I suggest dropping the references to Ben's individual alt-svc in DNS draft.. it hasn't been adopted and its future is murky. actual alt-svc (the non dns kind) actually requires the use of the plaintext SNI. As those are both cachable and connections to new IP addresses (less linkable) you could consider updating it with mike bishop's URL (also an individual draft atm)
NAME also suggested that the reference might not be needed in URL so I made to actually remove it.
Regarding: Why is that a SHOULD? Does it apply to both fronting and shared mode? For reference, Cloudflare almost always sends at least two A and AAAA answers for every question. (I get that it's not a MUST, though I'd also like to understand what the reasoning is in the first place)
NAME ??
The idea was to simplify key management. If multiple A or AAAA records are returned, the server needs to ensure each server behind those addresses have all the necessary keys.
NAME I see, I'd rather the spec said that instead of trying to impose limits (I made with suggested fix).
NAME works for me :)

Discussion:
the query domain name.  That is, if a client queries example.com, the ESNI TXT Resource Record might be: <del> Servers SHOULD configure DNS such that, upon querying a domain name with ESNI support, at most one each of A, AAAA, TXT ESNI, and ALTSVC I-D.schwartz-httpbis-dns-alt-svc Resource Record is returned.  Alt- Svc records may be used to inform the client of the plaintext </del> <ins> Servers MUST ensure that, if multiple A, AAAA or ALTSVC I-D.schwartz- httpbis-dns-alt-svc records are returned for a domain with ESNI support, all the servers pointed to by those records are able to handle the keys returned as part of a ESNI TXT record for that domain. Alt-Svc records may be used to inform the client of the plaintext </ins> (fronting) SNI.  If present, clients SHOULD use its value in the SNI extension of the subsequent ClientHello.
Change:
The version check on the outer ClientHello doesn't make much sense since, when ECH is accepted, the version is based on the inner ClientHello anyway. See URL I've left a TODO since it seems weird to have a client requirement like that be so load-bearing without a corresponding server check. Not sure where we should go there.
I like this change, but it might be worth resolving the TODO.
Removed the TODO in favor of some clarifying text on the client side.

Discussion:
does a standard ClientHello, with the exception of the following rules: <del> It MUST NOT offer to negotiate TLS 1.2 or below. </del> <ins> It MUST NOT offer to negotiate TLS 1.2 or below.  Note this is necessary to ensure the backend server does not negotiate a TLS version that is incompatible with ECH. </ins> It MUST NOT offer to resume any non-ECH PSK or any session for TLS 1.2 and below.

7.1. Upon receiving an "encrypted_client_hello" extension, the client- <del> facing server MUST check that it is able to negotiate TLS 1.3 or greater.  If not, it MUST abort the connection with a "handshake_failure" alert. </del> <ins> facing server determines if it will accept ECH, prior to negotiating any other TLS parameters.  Note that successfully decrypting the extension will result in a new ClientHello to process, so even the client's TLS version preferences may have changed. </ins> The ClientECH value is said to match a known ECHConfig if there exists an ECHConfig that can be used to successfully decrypt
Change:
I think this is a more general attack and deserves a more general description of the mitigation. See URL and . NAME

Discussion:
10.10.3. <del> This attack uses resumption PSKs as an oracle for dictionary attacks against a given ClientHello's true SNI.  To begin, the attacker first interacts with a server to obtain a resumption ticket for a given test domain, such as "test.com".  Later, upon receipt of a legitimate ClientHello without a PSK binder, it computes a PSK binder using its own ticket and forwards the resulting ClientHello.  Assume the server then validates the PSK binder on the outer ClientHello and chooses connection parameters based on the inner ClientHello.  A server which then validates information in ClientHelloOuter ticket against information in ClientHelloInner, such as the SNI, introduces an oracle that can be used to test the encrypted SNI value of specific ClientHello messages. ECH mitigates against this attack by (1) prohibiting the "pre_shared_key" extension in ClientHelloOuter and (2) requiring servers ignore this extension when processing ClientHelloOuter. Thus, if the server accepts the inner ClientHello, it only validates binders in the inner ClientHello.  This means that PSKs are used within the HPKE encryption envelope. </del> <ins> This attack aims to leak information about secret parts of the encrypted ClientHello by adding attacker-controlled parameters and observing the server's response.  In particular, the compression mechanism described in outer-extensions references parts of a potentially attacker-controlled ClientHelloOuter to construct ClientHelloInner, or a buggy server may incorrectly apply parameters from ClientHelloOuter to the handshake. To begin, the attacker first interacts with a server to obtain a resumption ticket for a given test domain, such as "example.com". Later, upon receipt of a ClientHelloOuter, it modifies it such that the server will process the resumption ticket with ClientHelloInner. If the server only accepts resumption PSKs that match the server name, it will fail the PSK binder check with an alert when ClientHelloInner is for "example.com" but silently ignore the PSK and continue when ClientHelloInner is for any other name.  This introduces an oracle for testing encrypted SNI values. This attack may be generalized to any parameter which the server varies by server name, such as ALPN preferences. ECH mitigates this attack by only using ClientHelloOuter to compute ClientHelloInner and authenticating all of ClientHelloInner with the HPKE AEAD.  If any extensions are compressed as in outer-extensions, the OuterExtensions.inner_digest field authenticates the decompressed result.  If none are compressed, the entire ClientHello is encrypted and authenticated directly.  An earlier iteration of this specification only encrypted and authenticated the "server_name" extension, which left the overall ClientHello vulnerable to an analogue of this attack. </ins> 11.
Change:
I noticed there's an OPEN ISSUE to add ClientHelloOuter guidance, but there's already a section for it. Link to it and flesh it out a little more. Sadly, in doing so, I've traded one OPEN ISSUE for another OPEN ISSUE, but hopefully that'll be closed shortly.

Discussion:
The client might duplicate non-sensitive extensions in both messages. However, implementations need to take care to ensure that sensitive <del> extensions are not offered in the ClientHelloOuter.  [[OPEN ISSUE: We should provide guidance on what extensions are sensitive and suggest suitable substitutes.]] </del> <ins> extensions are not offered in the ClientHelloOuter.  See outer- clienthello for additional guidance. </ins> To encrypt EncodedClientHelloInner, the client first needs to generate the HPKE encryption context.  It computes the encapsulated

values associated with the true server name in the ClientHelloOuter. It MAY send such values in the ClientHelloInner. <ins> A client may also use different preferences in different contexts. For example, it may send a different ALPN lists to different servers or in different application contexts.  A client that treats this context as sensitive SHOULD NOT send context-specific values in ClientHelloOuter. </ins> Values which are independent of the true server name, or other information the client wishes to protect, MAY be included in <del> ClientHelloOuter and compressed as described in outer-extensions. </del> <ins> ClientHelloOuter.  If they match the corresponding ClientHelloInner, they MAY be compressed as described in outer-extensions.  However, note the payload length reveals information about which extensions are compressed, so inner extensions which only sometimes match the corresponding outer extension SHOULD NOT be compressed. [[OPEN ISSUE: In addition to the fuzzy leak from the length, there is an active attack to probe compressed extensions.  See issue #323.  We should either document this attack, or bind ClientHelloOuter.]] Clients MAY include additional extensions in ClientHelloOuter to avoid signaling unusual behavior to passive observers, provided the choice of value and value itself are not sensitive.  See do-not- stick-out. </ins> 10.6.