Original text:
Conceptually, the handshake establishes three secrets which are used to derive all the keys. <del> Ephemeral Secret (ES): A secret which is derived from fresh (EC)DHE shares for this connection.  Keying material derived from ES is intended to be forward secret (with the exception of pre-shared key only modes). Static Secret (SS): A secret which may be derived from static or semi-static keying material, such as a pre-shared key or the server's semi-static (EC)DH share. Master Secret (MS): A secret derived from both the static and the ephemeral secret. There are three basic cases: In a pure (EC)DHE cipher suite, ES and SS will both be the (EC)DHE shared secret. In a pure PSK cipher suite, ES and SS will both be the PSK. In an (EC)DHE-PSK cipher suite, ES will be the (EC)DHE shared secret and SS will be the PSK. </del> tls-full below shows the basic full TLS handshake. The handshake can be thought of as having three phases, indicated in Recipients of Finished messages MUST verify that the contents are correct.  Once a side has sent its Finished message and received and validated the Finished message from its peer, it may begin to <del> send and receive application data over the connection.  This data will be protected under keys derived from the ephemeral secret (see cryptographic-computations). </del>  The key used to compute the finished message is computed from the Base key defined in authentication-messages using HKDF (see key- 7.1. <del> The TLS handshake establishes secret keying material which is then used to protect traffic.  This keying material is derived from the two input secret values: Static Secret (SS) and Ephemeral Secret (ES). </del>  <del> The exact source of each of these secrets depends on the operational mode (DHE, ECDHE, PSK, etc.) and is summarized in the table below: </del>  <del> These shared secret values are used to generate cryptographic keys as shown below. </del>  <del> The derivation process is as follows, where L denotes the length of the underlying hash function for HKDF RFC5869.  SS and ES denote the sources from the table above. </del>  <del> The traffic keys are computed from xSS, xES, and the traffic_secret as described in traffic-key-calculation below.  The traffic_secret may be updated throughout the connection as described in updating- traffic-keys. </del>  <del> Note: Although the steps above are phrased as individual HKDF-Extract and HKDF-Expand operations, because each HKDF-Expand operation is paired with an HKDF-Extract, it is possible to implement this key schedule with a black-box HKDF API, albeit at some loss of efficiency as some HKDF-Extract operations will be repeated. </del>  7.2. The next-generation traffic_secret is computed as: <del> traffic_secret_N+1 = HKDF-Expand-Label(traffic_secret_N, "traffic secret", "", L) </del>  Once traffic_secret_N+1 and its associated traffic keys have been computed, implementations SHOULD delete traffic_secret_N.  Once the The length of the key. <del> The handshake context which is used to generate the keys. </del> The keying material is computed using: The following table describes the inputs to the key calculation for construction.  The exporter interface remains the same, however the value is computed as: <del> Note: the inner HKDF-Extract is strictly unnecessary, but it maintains the invariant that HKDF Extract and Expand calls are paired. </del> 8. 8.1.

Reviewer comments:
First cut at a new, more linear key schedule. WIP so possible I missed something serious. NAME NAME comments, please? Does this seem more straightforward
After this change, the keys used to encrypt the handshake traffic are derived from both ES and SS. (As before, they were derived only from ES) Does this bring any advantages security-wise? In the current version, the Finished keys contain the handshake context up to CertificateVeryServer, by being transitively derived from mES and mSS. Now these keys don't contain handshake context any more. What is the reasoning behind this change?
, svince EMAIL wrote: In the current version, the Finished keys contain the handshake context up
This is pretty good. The simplification is dramatic, which is the number one thing. Well, the number two thing, given that number one is sign-off from the cryptographers; my limited knowledge of this says that we are using the same basic source of keying material for all the important decisions. Critically, exporters and resumption branch after the client Finished. I think that you can revert the bracketing changes by changing the description of each instead. The fact that there are different keys for different phases is quite important to have in people's faces, I think.
Note that I had some concerns with clarity of the PR: formatting, the description of and a few things. I think that those are pretty important and probably need a little attention before landing this.
I'm currently modeling the handshake using the Tamarin Prover. Now i need to decide how to model key generation. Should I rather already use the new key generation, or use the current one? How likely will this pull request be merged in the next time?
I expect to have this resolved and in (though perhaps not identical to this) by this time next week. , svince EMAIL wrote:
The traffic key is derived by applying HKDF-Extract to the traffic_secret, which in turn is derived by applying HKDF-Extract to the master secret. There is no intermediate HKDF-Extract stage. Is this intended? Should there be an intermediate Extract stage? Could the traffic key maybe be derived directly from the master secret, of course together with the correct handshake hash?
Sorry, which line are talking about? The traffic keys are derived by applying HKDF-Expand-Label to the current traffic secret: URL key = HKDF-Expand-Label(Secret, phase + ", " + purpose, handshakecontext, keylength)
According to [URL], the traffic key is computed like this: key = HKDF-Expand-Label(Secret, phase + ", " + purpose, handshakecontext, keylength), where Secret = trafficsecret According to [URL], the trafficsecret is computed as follows: trafficsecret0 = HKDF-Expand-Label(mastersecret, "traffic secret", handshakehash, L) The note at the end of 7.1 declares "each HKDF-Expand operation is paired with an HKDF-Extract". But this is not the case for the traffic key, as there is no HKDF-Extract operation performed on trafficsecret. Is this intended? If so, why? Wouldn't it be the same (security wise) as directly using the mastersecret to derive the traffic key?
Yes, that's an oversight. We are currently reworking the key schedule a bit (see URL) and that will have parity between extract and expand. We could derive the traffic keys from MS, but then we would have to either precompute trafficsecret1 (which is a bit odd) or keep MS around (which threatens PFS for resumed connections). So we did it this way.
Okay thank you for the information. This helped.

Revised text:
Conceptually, the handshake establishes three secrets which are used to derive all the keys.  tls-full below shows the basic full TLS handshake. The handshake can be thought of as having three phases, indicated in Recipients of Finished messages MUST verify that the contents are correct.  Once a side has sent its Finished message and received and validated the Finished message from its peer, it may begin to  <ins> send and receive application data over the connection. </ins> The key used to compute the finished message is computed from the Base key defined in authentication-messages using HKDF (see key- 7.1.  <ins> The TLS handshake establishes one or more input secrets which are combined to create the actual working keying material, as detailed below.  The key derivation process makes use of the following functions, based on HKDF RFC5869: Given a set of n InputSecrets, the final "master secret" is computed by iteratively invoking Add-Secret with InputSecret_1, InputSecret_2, etc.  The initial secret is simply a string of 0s as long as the size of the Hash that is the basis for the HKDF.  Concretely, for the present version of TLS 1.3, secrets are added in the following order: PSK </ins>  <ins> (EC)DHE shared secret </ins>  <ins> This produces a full key derivation schedule shown in the diagram below.  In this diagram, the following formatting conventions apply: </ins>  <ins> HKDF-Extract is drawn as taking the Salt argument from the top and the IKM argument from the left. </ins>  <ins> HKDF's PRK argument is indicated by the arrow coming in from the left.  For instance, the Early Secret is the PRK for generating the early_traffic-secret. </ins>  <ins> The general pattern here is that the secrets shown down the left side of the diagram are just raw entropy without context, whereas the secrets down the right side include handshake context and therefore can be used to derive working keys without additional context.  Note that the different calls to HKDF-Expand-Label may take different Context arguments, even with the same secret.  In a 0-RTT exchange, HKDF-Expand-Label is called with four distinct transcripts; in a 1-RTT only exchange with three distinct transcripts. If a given secret is not available, then the 0-value consisting of a string of L 0s is used. </ins> 7.2. The next-generation traffic_secret is computed as:  <ins> traffic_secret_N+1 = HKDF-Expand-Label(traffic_secret_N, "application traffic secret", "", L) </ins> Once traffic_secret_N+1 and its associated traffic keys have been computed, implementations SHOULD delete traffic_secret_N.  Once the The length of the key.  The keying material is computed using: The following table describes the inputs to the key calculation for construction.  The exporter interface remains the same, however the value is computed as:  8. 8.1.