Archives December 2021

The CertificateVerify message – Hash Functions and Message Authentication Codes

11.7.3 Hash functions in authentication-related messages

In the previous chapters, we discussed that TLS uses the following messages uniformly, that is, as a common set, for authentication, key confirmation, and handshake integrity:

  • Certificate
  • CertificateVerify
  • Finished

Server Alice and client Bob always send these three messages as the last messages of the TLS handshake.

Recall that server Alice and client Bob compute their TLS authentication messages all uniformly by taking the following inputs:

  • Their digital certificate and their private key to be used for signing
  • The so-called Handshake Context that contains all handshake messages to be included in the transcript hash
  • The BaseKey used to compute a MAC key

Based on the preceding inputs, the authentication messages contain the following data:

  • The Certificate to be used for authentication, including any supporting certificates in the certificate chain
  • The CertificateVerify signature over the value of Transcript-Hash(Handshake Context, Certificate)
  • The MAC Finished, computed using the MAC key derived from from BaseKey, over the value of

Transcript-Hash(Handshake Context, Certificate, CertificateVerify)

The CertificateVerify message

Recall that Alice and Bob use the CertificateVerify message to explicitly prove that they indeed possess the private key corresponding to the public key in their certificate. In addition, CertificateVerify is used to ensure the TLS handshake’s integrity up to this point. The structure of CertificateVerify is shown in Listing 11.5.

The signature field contains the digital signature, and the algorithm field contains the signature algorithm that was used to generate the signature. Hash output of the Transcript-Hash(Handshake Context, Certificate) function is the data covered by the digital signature.

Listing 11.5: TLS 1.3 CertificateVerify message

struct {
   SignatureScheme algorithm;
   opaque signature<0..2^16-1>;
} CertificateVerify;

The Finished message

Recall that Finished is the last handshake message in the authentication block, and that this message provides authentication of the TLS handshake and authentication of the keys computed by server Alice and client Bob. The structure of the message is shown in Listing 11.6.

Listing 11.6: Structure of Finished message in TLS 1.3

struct {
   opaque verify_data[Hash.length];
} Finished;

To generate a correct Finished message, Alice and Bob use a secret key derived from the BaseKey using the HKDF-Expand-Label function:
finished_key = HKDF-Expand-Label(BaseKey, “finished”, “”, Hash.length)

Both Alice and Bob must verify the correctness of the Finished message they receive and immediately terminate the TLS session if Finished is corrupted. The verify˙data field is computed as follows:
verify_data = HMAC(finished_key, Transcript-Hash)

The Transcript-Hash is a hash value computed over c—Handshake Context—, Certificate, and CertificateVerify. The values for Certificate and CertificateVerify are included in verify˙data computation only if they were present in the TLS handshake, that is, if either server Alice or client Bob have used digital certificates to prove their identity. Now we are going to explain how Transcript-Hash is computed in detail.