Exporter values – Secrets and Keys in TLS 1.3
12.5.1 Exporter values
Exporter values are computed using the Derive-Secret DS and the HKDF-Expand-Label HEL functions as shown in Figure 12.15. The input secret can be either early˙exporter˙master˙secret or exporter˙master˙secret. Bob and Alice use early˙exporter˙master˙secret when they need an exporter for 0-RTT data. For all other cases, the TLS 1.3 standard requires them to use exporter˙master˙secret.
Figure 12.15: Generation of TLS exporter values
If the TLS endpoint does not provide a context, a zero-length context˙value is used, which yields the same result as an empty context.
12.5.2 Generation of TLS keys
In TLS 1.3, cryptographic keys are generated using the HKDF-Expand-Label function. Alice and Bob derive the keys either from a pre-shared secret key PSK they know in advance, or from a DHE- or ECDHE-based secret they establish during the TLS handshake.
The PSK can be established out of band. For example, if Alice is a device provisioning service and Bob is a smart home device from the same manufacturer, the PSK can be distributed in the manufacturing phase in the plant environment, which the company would typically consider secure.
Alternatively, the PSK can be derived from the resumption˙master˙secret secret that Alice and Bob established in one of their previous TLS sessions.
If Alice and Bob use the Diffie-Hellman key exchange protocol, they exchange information about the group they want to use for it: either the multiplicative group in a finite field (DHE) or an elliptic curve (ECDHE). After that, they agree either on finite field Diffie-Hellman parameters (for DHE) or elliptic curve Diffie-Hellman parameters (for ECDHE).
For the moment, we can ignore the details of the underlying cryptography. We will come back to this topic and cover public-key cryptography, Diffie-Hellman key exchange, and elliptic curve cryptography in Chapter 7, Public-Key Cryptography, and Chapter 8, Elliptic Curves.
Every TLS traffic key actually consists of the key itself and a so-called initialization vector. The initialization vector is an input needed when using certain block cipher modes of operation. We will cover initialization vectors and the requirements they have to fulfill in more detail in Chapter 14, Block Ciphers and Their Modes of Operation. For the time being, you can simply view the initialization vector as additional (public) input to the encryption function.
TLS traffic keys and their corresponding initialization vectors are generated using the HKDF-Expand-Label function with the following input values:
- One of the derived TLS secrets
- A value indicating the purpose of the key to be generated, for example, a label or context information
- The length of the key to be generated
In the TLS 1.3 specification in RFC 8446, all keys used by Alice to encrypt handshake or application traffic are referred to as server˙write˙key. The corresponding initialization vectors are called server˙write˙iv. By analogy, Bob’s traffic keys are called client˙write˙key and the corresponding initialization vectors client˙write˙iv.
What makes each traffic key – and its associated initialization vector – unique is the TLS secret used as input to the HKDF-Expand-Label function. For example, Alice’s key for encrypting data during TLS handshake is computed as follows:
server_write_key = HKDF-Expand-Label(server_handshake_traffic_secret, “key”, “”, key_length)
But Alice’s application traffic key for encrypting application data right after the TLS handshake is computed as follows:
server_write_key = HKDF-Expand-Label(server_application_traffic_secret_0, “key”, “”, key_length)
Note how the string input ”key” is used to indicate that the output of the HKDF-Expand-Label function is a cryptographic key, not the initialization vector. This is a good example of how different keying material can be generated using the same function and the same secret, but different labels.
Table 12.2 shows which TLS secrets and labels are used to generate the different TLS keys. No additional context information is used for generating the keys because the different TLS secrets already carry the relevant context thanks to the labels and transcripts that were used as inputs to function DS to derive these TLS secrets.
Type | TLS key | TLS Secret | Label |
0 | kB | client_early_traffic_secret | “key” |
0 | ivB | client_early_traffic_secret | “iv” |
H | kA | server_handshake_traffic_secret | “key” |
H | ivA | server_handshake_traffic_secret | “iv” |
H | kB | client_handshake_traffic_secret | “key” |
H | ivB | client_handshake_traffic_secret | “iv” |
A | kA | server_application_traffic_secret_N | “key” |
A | ivA | server_application_traffic_secret_N | “iv” |
A | kB | client_application_traffic_secret_N | “key” |
A | ivB | client_application_traffic_secret_N | “iv” |
Table 12.2: TLS secrets and labels used for the TLS key calculation
TLS 1.3 has three different types of cryptographic keys used in different contexts: encryption of 0-RTT application data, encryption of TLS handshake messages, and application of the bulk application data transmitted in a TLS session.
The types of the keys for these contexts is denoted by 0, H, and A, respectively. Bob’s key – denoted as client_write_key in RFC 8446 – is kB in Table 12.2. Bob’s initialization vector is denoted as ivB. Similarly, Alice’s key – specified as server_write_key in RFC 8446 – is denoted by kA and Alice’s initialization vector as ivA.