Original text:
As keys at a given encryption level become available to TLS, TLS indicates to QUIC that reading or writing keys at that encryption <del> level are available.  These events are not asynchronous; they always occur immediately after TLS is provided with new handshake bytes, or after TLS produces handshake bytes. </del>  TLS provides QUIC with three items as a new encryption level becomes available: A Key Derivation Function (KDF) These values are based on the values that TLS negotiates and are used <del> by QUIC to generate packet and header protection keys (see packet- protection and header-protect). </del>  If 0-RTT is possible, it is ready after the client sends a TLS ClientHello message or the server receives that message.  After The output ciphertext, C, of the AEAD is transmitted in place of P. Some AEAD functions have limits for how many packets can be encrypted <del> under the same key and IV (see for example AEBounds).  This might be lower than the packet number limit.  An endpoint MUST initiate a key update (key-update) prior to exceeding any limit set for the AEAD that is in use. </del>  5.4. 6.6. <del> Key updates MUST be initiated before usage limits on packet protection keys are exceeded.  For the cipher suites mentioned in this document, the limits in Section 5.5 of TLS13 apply.  TLS13 does not specify a limit for AEAD_AES_128_CCM, but the analysis in ccm- bounds shows that a limit of 2^23 packets can be used to obtain the same confidentiality protection as the limits specified in TLS. </del>  The usage limits defined in TLS 1.3 exist for protection against attacks on confidentiality and apply to successful applications of packet that cannot be authenticated, allowing multiple forgery attempts. <del> Endpoints MUST count the number of received packets that fail authentication for each set of keys.  If the number of packets that fail authentication with the same key exceeds a limit that is specific to the AEAD in use, the endpoint MUST stop using those keys. Endpoints MUST initiate a key update before reaching this limit.  If a key update is not possible, the endpoint MUST immediately close the connection.  Applying a limit reduces the probability that an attacker is able to successfully forge a packet; see AEBounds and ROBUST. Due to the way that header protection protects the Key Phase, packets that are discarded are likely to have an even distribution of both Key Phase values.  This means that packets that fail authentication will often use the packet protection keys from the next key phase.  It is therefore necessary to also track the number of packets that fail authentication with the next set of packet protection keys.  To avoid exhaustion of both sets of keys, it might be necessary to initiate two key updates in succession. For AEAD_AES_128_GCM, AEAD_AES_256_GCM, and AEAD_CHACHA20_POLY1305, the limit on the number of packets that fail authentication is 2^36. Note that the analysis in AEBounds supports a higher limit for the AEAD_AES_128_GCM and AEAD_AES_256_GCM, but this specification recommends a lower limit.  For AEAD_AES_128_CCM, the limit on the number of packets that fail authentication is 2^23.5; see ccm-bounds. </del>  These limits were originally calculated using assumptions about the limits on TLS record size.  The maximum size of a TLS record

Reviewer comments:
This clarifies the TLS interface by explaining that TLS only generates outputs (handshake bytes or keying material) in response to inputs. Previously, the only inputs we acknowledged were the handshake bytes, but this recognizes two more: the signal from the client to start handshaking, and - for async validation - a signal that a certificate is OK or not.
Weren't we going to say that the traffic keys might get generated asynchronously in ? I wonder how this PR interacts with . I see this PR calling out three types of events (i.e. generation of CH, input of handshake bytes, completion of certificate validation) as the "inputs," then claim that TLS provides the keys "synchronously" in relation to such events. That works as a definition, but I am not sure if it is easy to comprehend. I think my preference would be to talk about (a)synchronicity from the viewpoint of a transport. It would be easier to say that TLS might provide keys "asynchronously" from what the transport provides as input, then point out that key generation (possibly in relation to certificate verification) might take some time.
To answer both questions, I am planning on integrating the text from as well. That would cover the case where the TLS stack has to disappear for some time before it produces new outputs, however that manifests.
NAME NAME I've rebased this based on the changes in . Would you mind checking my work?
The label should be instead of .
Thanks NAME fixed.
The process for interacting with TLS does not acknowledge the possibility that progress in the handshake might depend on inputs other than CRYPTO frames. In particular, endpoints might need to perform additional checking to decide that the TLS handshake is complete. The most important example being the processing that occurs for certificate validation. This is often an asynchronous process, with OCSP and other muck, so recognizing that explicitly in the draft is worthwhile. This might help tease out one of the causes of the problem discussed in , but it doesn't lead to a solution.
Q: Does this indicate that the TLS changes involved in may be editorial? I'd like to focus on the transport and recovery changes to deal with the issue, and it'd be nice if the tls changes were separate from my perspective.
Why isn't adequate for this? Specifically, isn't it enough to change the stance from synchronous to asynchronous?
I would prefer to explain how certificate validation can take time and block availability of keys.
Should this become proposal-ready?
NAME : This is an editorial issue, so no.
Thanks looks great!

Revised text:
As keys at a given encryption level become available to TLS, TLS indicates to QUIC that reading or writing keys at that encryption  <ins> level are available. The availability of new keys is always a result of providing inputs to TLS.  TLS only provides new keys after being initialized (by a client) or when provided with new handshake data. However, a TLS implementation could perform some of its processing asynchronously.  In particular, the process of validating a certificate can take some time.  While waiting for TLS processing to complete, an endpoint SHOULD buffer received packets if they might be processed using keys that aren't yet available.  These packets can be processed once keys are provided by TLS.  An endpoint SHOULD continue to respond to packets that can be processed during this time. After processing inputs, TLS might produce handshake bytes, keys for new encryption levels, or both. </ins> TLS provides QUIC with three items as a new encryption level becomes available: A Key Derivation Function (KDF) These values are based on the values that TLS negotiates and are used  <ins> by QUIC to generate packet and header protection keys; see packet- protection and header-protect. </ins> If 0-RTT is possible, it is ready after the client sends a TLS ClientHello message or the server receives that message.  After The output ciphertext, C, of the AEAD is transmitted in place of P. Some AEAD functions have limits for how many packets can be encrypted  <ins> under the same key and IV; see aead-limits.  This might be lower than the packet number limit.  An endpoint MUST initiate a key update (key-update) prior to exceeding any limit set for the AEAD that is in use. </ins> 5.4. 6.6.  <ins> This document sets usage limits for AEAD algorithms to ensure that overuse does not give an adversary a disproportionate advantage in attacking the confidentiality and integrity of communications when using QUIC. </ins> The usage limits defined in TLS 1.3 exist for protection against attacks on confidentiality and apply to successful applications of packet that cannot be authenticated, allowing multiple forgery attempts.  <ins> QUIC accounts for AEAD confidentiality and integrity limits separately.  The confidentiality limit applies to the number of packets encrypted with a given key.  The integrity limit applies to the number of packets decrypted within a given connection.  Details on enforcing these limits for each AEAD algorithm follow below. Endpoints MUST count the number of encrypted packets for each set of keys.  If the total number of encrypted packets with the same key exceeds the confidentiality limit for the selected AEAD, the endpoint MUST stop using those keys.  Endpoints MUST initiate a key update before sending more protected packets than the confidentiality limit for the selected AEAD permits.  If a key update is not possible or integrity limits are reached, the endpoint MUST stop using the connection and only send stateless resets in response to receiving packets.  It is RECOMMENDED that endpoints immediately close the connection with a connection error of type AEAD_LIMIT_REACHED before reaching a state where key updates are not possible. For AEAD_AES_128_GCM and AEAD_AES_256_GCM, the confidentiality limit is 2^25 encrypted packets; see gcm-bounds.  For AEAD_CHACHA20_POLY1305, the confidentiality limit is greater than the number of possible packets (2^62) and so can be disregarded.  For AEAD_AES_128_CCM, the confidentiality limit is 2^23.5 encrypted packets; see ccm-bounds.  Applying a limit reduces the probability that an attacker can distinguish the AEAD in use from a random permutation; see AEBounds, ROBUST, and GCM-MU. In addition to counting packets sent, endpoints MUST count the number of received packets that fail authentication during the lifetime of a connection.  If the total number of received packets that fail authentication within the connection, across all keys, exceeds the integrity limit for the selected AEAD, the endpoint MUST immediately close the connection with a connection error of type AEAD_LIMIT_REACHED and not process any more packets. For AEAD_AES_128_GCM and AEAD_AES_256_GCM, the integrity limit is 2^54 invalid packets; see gcm-bounds.  For AEAD_CHACHA20_POLY1305, the integrity limit is 2^36 invalid packets; see AEBounds.  For AEAD_AES_128_CCM, the integrity limit is 2^23.5 invalid packets; see ccm-bounds.  Applying this limit reduces the probability that an attacker can successfully forge a packet; see AEBounds, ROBUST, and GCM-MU. Future analyses and specifications MAY relax confidentiality or integrity limits for an AEAD. </ins> These limits were originally calculated using assumptions about the limits on TLS record size.  The maximum size of a TLS record