PR: https://github.com/tlswg/tls13-spec/pull/454
I have uploaded a PR [technically two PRs, but one builds on the other, so easier to just read the composition] which resolves two out of the three significant remaining crypto issues (the remaining one is the long-running discussion of post-handshake keys). The following message lays out the changes, which are: - Adopt a more linear key schedule - Add a context identifier for resumption KEY SCHEDULE We had a lot of comments that the existing key schedule was too hard to understand and implement and could be simplified under the assumption that keys were available in a specific order (PSK then DH ZZ). I've been working together with Karthik, Hugo, Antoine, and others to produce something cleaner. (Note: I believe they consider this acceptable, but that doesn't mean they wouldn't have designed every piece exactly as I have.) The overall key schedule looks like this: 0 | v PSK -> HKDF-Extract | v Early Secret --> Derive-Secret(., "early traffic secret", | ClientHello) | = early_traffic_secret v (EC)DHE -> HKDF-Extract | v Handshake Secret -----> Derive-Secret(., "handshake traffic secret", | ClientHello + ServerHello) | = handshake_traffic_secret v 0 -> HKDF-Extract | v Master Secret | +---------> Derive-Secret(., "application traffic secret", | ClientHello...Server Finished) | = traffic_secret_0 | +---------> Derive-Secret(., "exporter master secret", | ClientHello...Client Finished) | = exporter_secret | +---------> Derive-Secret(., "resumption master secret", ClientHello...Client Finished) = resumption_secret Derive-Secret(Secret, Label, Messages) = HKDF-Expand-Label(Secret, Label, Hash(Messages) + resumption_context, L)) Derive-Secret is just a wrapper around HKDF-Expand-Label, for reasons indicated below. If a key is missing you just use 0s. 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. All the working keys (both encryption keys and finished keys) are generated using HKDF-Expand-Label off of the traffic secrets. This design is motivated by the following principles: - Separate out adding entropy from adding context. - Incorporate the transcript once and then derive from there. - Have a narrow, consistent interface for generating the leaf keys so they can just start with a base key. - Derive from keys as soon as practical so that you can destroy them (thus the final call to Add-Secret, which isolates the Finished keys from the MS). An additional nice point about this design is that it easily accomodates additional keys. For instance, if we had some post-quantum key exchange method, we could easily add its key in the final Add-Secret or add an extra Add-Secret stage before HS. Similarly, if we had a long-term DH key as in OPTLSv1, it could replace the 0 in the final Add-Secret. One thing I want to call out explicitly is that we are using HKDF-Expand-Label with the output of HKDF-Expand-Label. This is cryptographically fine, but means that you need an implementation of the individual HKDF Expand/Extract primitives. As far as I can tell, this isn't a hardship for anyone, but please speak up if it is. The advantage of this is that you remove unnecessary crypto operations. CONTEXT IDENTIFIER PR: https://github.com/tlswg/tls13-spec/pull/454 Hugo and Karthik both independently suggested that it would be nice to have some identity/context bound into the PSK handshake. The second PR accomodates that by deriving two values from the RMS: resumption_psk = HKDF-Expand-Label(resumption_secret, "resumption psk", "", L) resumption_context = HKDF-Expand-Label(resumption_secret, "resumption context", "", L) The resumption_psk is then used as the PSK for resumption and the resumption_context is added to the hash of the handshake messages whenever you use them, currently just by appending to the hash, as in: Hash(handshake messages) +resumption_context This is used *both* to derive the keys and for the input to the CertificateVerify/Finished. For convenience, I've Note: the reason for separately deriving RMS and then computing the context and PSK from RMS is to allow the server to just store RMS in the ticket. If we used MS the server would need to store MS in the ticket and then compromise of the ticket key would threaten the original handshake. One nit question, would it be better to hash twice, as in: Hash(Hash(handshake messages) + resumption_context) I can't see a reason to, but maybe I've missed something. Comments welcome. In the interest of not having too many outstanding changes, I'll probably merge this tomorrow unless someone strongly objects or we find something really egregious (which is always possible because there's a lot of text here). Best, -Ekr
_______________________________________________ TLS mailing list TLS@ietf.org https://www.ietf.org/mailman/listinfo/tls