Original text:
A QUIC server starts the process by providing TLS with the client's handshake bytes. <del> At any given time, the TLS stack at an endpoint will have a current sending encryption level and receiving encryption level.  Each encryption level is associated with a different flow of bytes, which is reliably transmitted to the peer in CRYPTO frames.  When TLS provides handshake bytes to be sent, they are appended to the current flow and any packet that includes the CRYPTO frame is protected using keys from the corresponding encryption level. </del>  QUIC takes the unprotected content of TLS handshake records as the content of CRYPTO frames.  TLS record protection is not used by QUIC. QUIC assembles CRYPTO frames into QUIC packets, which are protected using QUIC packet protection.  When an endpoint receives a QUIC packet containing a CRYPTO frame from the network, it proceeds as follows: 4.3. <del> QUIC requires that the first Initial packet from a client contain an entire cryptographic handshake message, which for TLS is the ClientHello.  Though a packet larger than 1200 bytes might be supported by the path, a client improves the likelihood that a packet is accepted if it ensures that the first ClientHello message is small enough to stay within this limit. </del>  QUIC packet and framing add at least 36 bytes of overhead to the ClientHello message.  That overhead increases if the client chooses a For servers, in addition to connection IDs and tokens, the size of TLS session tickets can have an effect on a client's ability to <del> connect.  Minimizing the size of these values increases the probability that they can be successfully used by a client. A client is not required to fit the ClientHello that it sends in response to a HelloRetryRequest message into a single UDP datagram. </del>  The TLS implementation does not need to ensure that the ClientHello is sufficiently large.  QUIC PADDING frames are added to increase the 4.5. <del> In order to be usable for 0-RTT, TLS MUST provide a NewSessionTicket message that contains the "early_data" extension with a max_early_data_size of 0xffffffff; the amount of data which the client can send in 0-RTT is controlled by the "initial_max_data" transport parameter supplied by the server.  A client MUST treat receipt of a NewSessionTicket that contains an "early_data" extension with any other value as a connection error of type PROTOCOL_VIOLATION. </del>  A client that wishes to send 0-RTT packets uses the "early_data" extension in the ClientHello message of a subsequent handshake (see Section 4.2.10 of TLS13).  It then sends the application data in 0-RTT packets. <del> Early data within the TLS connection MUST NOT be used.  As it is for other TLS application data, a server MUST treat receiving early data on the TLS connection as a connection error of type PROTOCOL_VIOLATION. </del> 4.6. A server accepts 0-RTT by sending an early_data extension in the 9.3. <del> Header protection relies on the packet protection AEAD being a pseudorandom function (PRF), which is not a property that AEAD algorithms guarantee.  Therefore, no strong assurances about the general security of this mechanism can be shown in the general case. The AEAD algorithms described in this document are assumed to be PRFs. The header protection algorithms defined in this document take the form: This construction is secure against chosen plaintext attacks (IND- CPA) IMC. </del>  Use of the same key and ciphertext sample more than once risks compromising header protection.  Protecting two different headers

Reviewer comments:
The restriction for ClientHello to fit in a single UDP datagram was added back when the retry mechanism was more tightly coupled to the TLS crypto. At this point, the restriction doesn't get us much, and is preventing us from running some post-quantum experiments.
This proposed changes imposes some new, nontrivial requirements on the server side. As a server, would I be required to support multi-packet client initials? Do we really need this in V1?
I share NAME concern: The pain in the ass would be quite real. Is post-quantum crypto in scope?
NAME I'd point out that endpoints are already required to support muti-packet client Initials when the TLS handshake uses HRR. Therefore, IMO the PR does not add new threats.
HRR is not stateless (at the QUIC layer) though, correct? The client's first packet still must completely contain ALPN and (optionally) SNI. That information is used by WinQuic to decide initially if the connection should be accepted and more server resources commit to processing the connection. Adding another point to the QUIC layer to decide if Retry is needed is additional work.
NAME I might argue that this PR does not prevent you from using the ALPN and SNI in the first packet as a way to "skip" Retry. In that hack, the difference between the status quo and this PR is that an incomplete CH in the first packet becomes a signal to send a Retry rather than an error. I do not think it adds complexity. Considering the fact that we can remove other complexities due to the 1-packet restriction, this PR is a good simplification.
I'm not arguing that this PR would require loads more code, but I definitely don't agree that it's a "good simplification" of the current design. This adds additional attack surfaces that must be analyzed and implementations ensure they have adequate defense. Again, I ask is this absolutely required for V1? What chartered requirements for QUIC deem this change necessary for V1?
At the moment, a QUIC stack is required to indicate to the TLS stack that the CH should be constructed in a way that invokes HRR (by omitting the keyshare extension), if the CH is otherwise going to not fit in one packet. This requirement is not only complex but also imposes one additional roundtrip (when the rule is invoked). Regarding the charter, we are tasked to create a protocol that minimizes connection establishment latency, while having "security and privacy properties that are at least as good as a stack composed of TLS 1.3 using TCP." We already have post-quantum extensions proposed for TLS 1.3, it is my understanding that Chrome is already doing experiments. They require use of CH that do not fit in single packet, which, without resolving this issue, imposes complexity and one extra round-trip. Considering these aspects, I might argue that we are encouraged_ by the charter to resolve the problem :-)
Regardless of post-quantum and HRR, I agree with NAME that it is problematic to commit multiple packets before any kind of validation. If that is already the case due to HRR, I hope there is a way to avoid that without relying on client generated content. Otherwise the server is wide open to slow loris connection attacks. As to post-quantum - fine to have an experimental setting - in a real post-quantum world, perhaps min MTU can be larger?
draft-ietf-quic-tls says "QUIC requires that the first Initial packet from a client contain an entire cryptographic handshake message, which for TLS is the ClientHello." My (possibly incorrect) understanding is this was needed so the server can, in the old QUIC/TLS embedding, statelessly send a HelloRetryRequest without having to statefully assemble a ClientHello out of multiple packets. In the new QUIC/TLS embedding, this concern no longer applies because the stateless rejects are entirely external to TLS. Thus, should we simply delete most of the #clienthello-size section? This avoids a number of awkward pitfalls because the ClientHello size is a function of many factors, with both client and server considerations that change over time. Perhaps we add a new TLS extension or key share type and some SNIs work but larger SNIs were closer to the limit and this brings them over. Or perhaps the server's NewSessionTicket is large[] and breaks subsequent connections from some client. Perhaps that server tested it against one client, but another client has a larger baseline ClientHello and then it breaks. Finally, post-quantum key exchange candidates tend to come with . The current text prevents QUIC from experimenting with or deploying such schemes. This is particularly fun because QUIC clients typically also speak TLS over TCP, so the security of connections to a server is bound by the weaker of TLS over QUIC and TCP. [] Client certificates are often inserted into the ticket, so now we have a client-specific limit being influenced by a server-specific implementation decision which is, in turn, dependent on client/CA-controlled size of client certificate. Additionally, draft-ietf-quic-transport#zerortt-parameters implies servers may wish to remember QUIC transport parameters in the ticket.
This seems like a reasonable change to me. I don't anticipate this creating any new issues with recovery/etc, though it might exacerbate some of the existing ones.
I believe a main motivation for a single packet is that it avoids binding a lot of state on the server which can be a significant DoS vector. If anything we can expect certificates to get smaller with more widespread use of EC25519. As to post quantum, lets make another QUIC version in about 30-60 years or so.
As NAME says, I believe there was a concern about state at the server for connections that have not yet been established, if it receives only part of a ClientHello. I don't think this is a debilitating concern however. I would like to air this for a little while though ... I remember us using the assumption that the ClientHello is a single packet a few times, and I'm not sure if we did document them all.
I agree we should not hurry on this. From a text perspective, it's a simple change. I'd like the chairs(NAME NAME ) to briefly bring this up at the next QUIC session to ensure we can be aware of any potential pitfalls before making this change.
Could you elaborate on this? There are other client messages than the initial ClientHello, which would all require state at the server for unestablished connections. There is certainly a need to statelessly do something with unestablished connections, but there's a point where the server transitions to being stateful. In the old TLS/QUIC embedding, yes, that point was at the first ClientHello and you needed the entire ClientHello to produce a HelloRetryRequest+cookie, which was the mechanism for statelessly bouncing a connection. That's no longer the case in the new embedding, as far as I can tell. The retry packets don't actually depend on the full ClientHello or interact with the TLS handshake at all. It should work equally well if that initial packet has a full ClientHello or half of one. This time estimate is not consistent with what people are already doing in this space. URL
I'm not sufficiently deep into the handshake to detail this - but you are correct that there is less dependency on the TLS engine than what went before. I'm not sure when ClientCerts land in this process - I know they can't always fit in one piece but all else being equal, it simplifies bad content defence a lot to have a consistent starting point.
If we did allow for multiple packets for the ClientHello, I'd still want to retain the ability to decide whether or not to accept the incoming connection from every one of those initial packets. This would mean things like ALPN and SNI would need to be duplicated in each packet. I wouldn't want to accept a design where an attacker forces the server to buffer packets while it wait for the necessary information just to decided if it can accept the connection. IMO, this sounds like a v2 feature. Does this prevent us from shipping v1?
So if a client is forced to split the ClientHello into two datagrams, you can use Retry. I don't think that this is crazy. The only thing we know to be true is that the restriction is annoying.
My mistake: late stage process means that only chairs mark things as design. This is a design change.
I agree with NAME . We should remove the restrictions and add text explaining that servers can either buffer or send retry. I can write the PR if it helps.
Thanks David. We'll probably want to raise this on the list, but I'd greatly appreciate a PR. It should be mostly deleting text, but some advice about how to handle multi-packet startups is probably wise, because it isn't a great situation to be dealing with.
I observed that the size of ticket OpenSSL issues if client certificate is used becomes quite large and it does not fit into a single QUIC packet.
NSS does the same because it puts the entire certificate (if not the certification path) into the ticket.
BoringSSL as well.
If we do a change like that, how do we test it?
Discussed in Cupertino. PR exists . NAME assigned.
NAME to add a test to the interop matrix
I just defined the test matrix option Q for Quantum Readiness.
The text of this PR looks good. I share the concern about whether we want to support multi-packet ClientHello messages, though the discussion (which should be on the issue, not the PR) seems fairly convincing that we'll need to do this at some point if we don't do it now.LGTM

Revised text:
A QUIC server starts the process by providing TLS with the client's handshake bytes.  <ins> At any time, the TLS stack at an endpoint will have a current sending encryption level and receiving encryption level.  Each encryption level is associated with a different flow of bytes, which is reliably transmitted to the peer in CRYPTO frames.  When TLS provides handshake bytes to be sent, they are appended to the current flow and any packet that includes the CRYPTO frame is protected using keys from the corresponding encryption level. </ins> QUIC takes the unprotected content of TLS handshake records as the content of CRYPTO frames.  TLS record protection is not used by QUIC. QUIC assembles CRYPTO frames into QUIC packets, which are protected using QUIC packet protection. <ins> QUIC is only capable of conveying TLS handshake records in CRYPTO frames.  TLS alerts are turned into QUIC CONNECTION_CLOSE error codes; see tls-errors.  TLS application data and other message types cannot be carried by QUIC at any encryption level and is an error if they are received from the TLS stack. </ins> When an endpoint receives a QUIC packet containing a CRYPTO frame from the network, it proceeds as follows: 4.3.  <ins> The first Initial packet from a client contains the start or all of its first cryptographic handshake message, which for TLS is the ClientHello.  Servers might need to parse the entire ClientHello (e.g., to access extensions such as Server Name Identification (SNI) or Application Layer Protocol Negotiation (ALPN)) in order to decide whether to accept the new incoming QUIC connection.  If the ClientHello spans multiple Initial packets, such servers would need to buffer the first received fragments, which could consume excessive resources if the client's address has not yet been validated.  To avoid this, servers MAY use the Retry feature (see Section 8.1 of QUIC-TRANSPORT) to only buffer partial ClientHello messages from clients with a validated address. </ins> QUIC packet and framing add at least 36 bytes of overhead to the ClientHello message.  That overhead increases if the client chooses a For servers, in addition to connection IDs and tokens, the size of TLS session tickets can have an effect on a client's ability to  <ins> connect efficiently.  Minimizing the size of these values increases the probability that clients can use them and still fit their ClientHello message in their first Initial packet. </ins> The TLS implementation does not need to ensure that the ClientHello is sufficiently large.  QUIC PADDING frames are added to increase the 4.5.  <ins> To communicate their willingness to process 0-RTT data, servers send a NewSessionTicket message that contains the "early_data" extension with a max_early_data_size of 0xffffffff; the amount of data which the client can send in 0-RTT is controlled by the "initial_max_data" transport parameter supplied by the server.  Servers MUST NOT send the "early_data" extension with a max_early_data_size set to any value other than 0xffffffff.  A client MUST treat receipt of a NewSessionTicket that contains an "early_data" extension with any other value as a connection error of type PROTOCOL_VIOLATION. </ins> A client that wishes to send 0-RTT packets uses the "early_data" extension in the ClientHello message of a subsequent handshake (see Section 4.2.10 of TLS13).  It then sends the application data in 0-RTT packets.  4.6. A server accepts 0-RTT by sending an early_data extension in the 9.3.  <ins> NAN analyzes authenticated encryption algorithms which provide nonce privacy, referred to as "Hide Nonce" (HN) transforms.  The general header protection construction in this document is one of those algorithms (HN1).  Header protection uses the output of the packet protection AEAD to derive "sample", and then encrypts the header field using a pseudorandom function (PRF) as follows: The header protection variants in this document use a pseudorandom permutation (PRP) in place of a generic PRF.  However, since all PRPs are also PRFs IMC, these variants do not deviate from the HN1 construction. As "hp_key" is distinct from the packet protection key, it follows that header protection achieves AE2 security as defined in NAN and therefore guarantees privacy of "field", the protected packet header. Future header protection variants based on this construction MUST use a PRF to ensure equivalent security guarantees. </ins> Use of the same key and ciphertext sample more than once risks compromising header protection.  Protecting two different headers