The TLS 1.3 RFC, section 7.1 lists this as the last part of the key schedule:


   0 -> HKDF-Extract = Master Secret
             +-----> Derive-Secret(., "c ap traffic",
             |                     ClientHello...server Finished)
             |                     = client_application_traffic_secret_0
             +-----> Derive-Secret(., "s ap traffic",
             |                     ClientHello...server Finished)
             |                     = server_application_traffic_secret_0
             +-----> Derive-Secret(., "exp master",
             |                     ClientHello...server Finished)
             |                     = exporter_master_secret
             +-----> Derive-Secret(., "res master",
                                   ClientHello...client Finished)
                                   = resumption_master_secret

The first three calculations take the Master Secret, combines them with the labelS "c ap traffic" / "s ap traffic" / "exp master" (respectively), and a handshake transcript hash of the Client Hello through Server Finished. The result of each of these is three keys: client_application_traffic_secret_0, server_application_traffic_secret_0, exporter_master_secret.

The last calculation takes the Master Secret, combines it with the label "res master", and a handshake transcript hash of the Client Hello through Client Finished. The result of this is resumption_master_secret.

My question:

What is the rational behind using Client Hello through Client Finished instead of Client Hello through Server Finished when calculating the Resumption Master Secret?


1 Answer 1


Actually that's an interesting question, and I can not tell you 100% for sure, but my thoughts on this are: Once the Server has sent its "Finished" message, it can already begin to send Application Data (even though the Client has not sent its Finished message yet). Thus it makes sense that the server_application_traffic_secret involves ClientHello....ServerFinished.

Regarding the resumption_master_secret, I would argue that since it is used for resumption of a session, the point of involving ClientHello...ClientFinished is to have the whole handshake involved into this secret. Even more, if the server asks for certificate authentication of the client, then this would also be part of the transcript of the handshake.

As far as I know, the specification does not justify all of the design decisions, but I personally think this makes sense, since (as you can see in the handshake protocol below), having ClientHello...ClientFinished involves the whole handshake.

       Client                                           Server

Key  ^ ClientHello
Exch | + key_share*
     | + signature_algorithms*
     | + psk_key_exchange_modes*
     v + pre_shared_key*       -------->
                                                  ServerHello  ^ Key
                                                 + key_share*  | Exch
                                            + pre_shared_key*  v
                                        {EncryptedExtensions}  ^  Server
                                        {CertificateRequest*}  v  Params
                                               {Certificate*}  ^
                                         {CertificateVerify*}  | Auth
                                                   {Finished}  v
                               <--------  [Application Data*]
     ^ {Certificate*}
Auth | {CertificateVerify*}
     v {Finished}              -------->
       [Application Data]      <------->  [Application Data]
  • $\begingroup$ Thanks for the answer. It makes perfect sense of why include "both sides" of the handshake. But I guess my main concern was why not also include Server Finished in the resumption key calculation? Why did the three keys before include Server Finished, but the resumption key only includes up to Client Finished. Why make that key different from the ones prior? $\endgroup$
    – Eddie
    Jul 16, 2021 at 18:13
  • $\begingroup$ Err wait... in responding to you, I think I now understand your response better. The Server Finished is the full handshake at the time that the Server means to start using the C/S application traffic keys. But at that moment, the server has no use for having a resumption key, so is content to wait until the next message from the client to calculate it -- therefore having the resumption key include "more" information from the original handshake. $\endgroup$
    – Eddie
    Jul 16, 2021 at 18:16
  • $\begingroup$ I'm giving you the check mark. Seeing what goes in to the keys compared to the handshake made it clear why the resumption key has the opportunity to include more handshake transcript in the key generation than the application traffic keys. Thanks Reppiz! $\endgroup$
    – Eddie
    Jul 20, 2021 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.