Rewritten for TLS 1.3: The New Illustrated TLS, Every Byte Explained

0
2

The server now has the information to calculate the
keys used to encrypt the rest of the handshake. It uses the following
information in this calculation:

First, the server finds the shared secret, which is the
result of the key exchange that allows the client and server
to agree on a number. The server multiplies the client’s
public key with the server’s private key using the curve25519()
algorithm. The 32-byte result is found to be:

df4a291baa1eb7cfa6934b29b474baad2697e29f1f920dcc77c8a0a088447624

I’ve provided
a tool
to perform this calculation:

$ cc -o curve25519-mult curve25519-mult.c
$ ./curve25519-mult server-ephemeral-private.key 
                    client-ephemeral-public.key | hexdump

0000000 df 4a 29 1b aa 1e b7 cf a6 93 4b 29 b4 74 ba ad
0000010 26 97 e2 9f 1f 92 0d cc 77 c8 a0 a0 88 44 76 24

We then calculate the SHA256 hash of all handshake messages
to this point (ClientHello and ServerHello). The hash does
not include the 5-byte “record” headers. This “hello_hash”
is
da75ce1139ac80dae4044da932350cf65c97ccc9e33f1e6f7d2d4b18b736ffd5.

We then feed the hash and the shared secret into a set of
key derivation operations, designed to ensure the integrity
of the handshake process and to protect against known and
possible attacks:

early_secret = HKDF-Extract(
    salt=00,
    key=00...)
empty_hash = SHA256("")
derived_secret = HKDF-Expand-Label(
    key = early_secret,
    label = "derived",
    context = empty_hash,
    len = 32)
handshake_secret = HKDF-Extract(
    salt = derived_secret,
    key = shared_secret)
client_handshake_traffic_secret = HKDF-Expand-Label(
    key = handshake_secret,
    label = "c hs traffic",
    context = hello_hash,
    len = 32)
server_handshake_traffic_secret = HKDF-Expand-Label(
    key = handshake_secret,
    label = "s hs traffic",
    context = hello_hash,
    len = 32)
client_handshake_key = HKDF-Expand-Label(
    key = client_handshake_traffic_secret,
    label = "key",
    context = "",
    len = 16)
server_handshake_key = HKDF-Expand-Label(
    key = server_handshake_traffic_secret,
    label = "key",
    context = "",
    len = 16)
client_handshake_iv = HKDF-Expand-Label(
    key = client_handshake_traffic_secret,
    label = "iv",
    context = "",
    len = 12)
server_handshake_iv = HKDF-Expand-Label(
    key = server_handshake_traffic_secret,
    label = "iv",
    context = "",
    len = 12)

This has introduced two new cryptographic methods:

  • HKDF-Extract – given a salt and some bytes of key material
    create 256 bits (32 bytes) of new key material, with the
    input key material’s entropy evenly distributed in the
    output.
  • HKDF-Expand-Label – given the inputs of key
    material, label, and context data, create a new key of the
    requested length.

I’ve created
an HKDF tool
to perform these operations on the command line.

$ hello_hash=da75ce1139ac80dae4044da932350cf65c97ccc9e33f1e6f7d2d4b18b736ffd5
$ shared_secret=df4a291baa1eb7cfa6934b29b474baad2697e29f1f920dcc77c8a0a088447624
$ zero_key=0000000000000000000000000000000000000000000000000000000000000000
$ early_secret=$(./hkdf extract 00 $zero_key)
$ empty_hash=$(openssl sha256 

From this we get the following key data:

  • handshake secret: fb9fc80689b3a5d02c33243bf69a1b1b20705588a794304a6e7120155edf149a
  • client handshake traffic secret: ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea.
  • server handshake traffic secret: a2067265e7f0652a923d5d72ab0467c46132eeb968b6a32d311c805868548814.
  • client handshake key: 7154f314e6be7dc008df2c832baa1d39
  • server handshake key: 844780a7acad9f980fa25c114e43402a
  • client handshake IV: 71abc2cae4c699d47c600268
  • server handshake IV: 4c042ddc120a38d1417fc815

Read More

This site uses Akismet to reduce spam. Learn how your comment data is processed.