6

I'm trying to deeply understand the steps during a TLS handshake.

I've read this answer (which is btw pretty complete), but I still got a question about the utilization of the MasterSecret, in the frame of a ECDHE-RSA-AES-GCM-SHA TLS handshake.

At the end of the handshake, we have used SHA as PRF to generate the Mastersecret (from the pre-MS and the random numbers). We expand it to create key and MAC key. The key is used to cipher the messages, and the MAC key to compute the hash (on the ciphered message if GCM mode). OK.

I have 2 questions about the expansion of the MasterSecret :

  1. In section 8:3, they say that we create 2 MAC keys and 2 keys. Isn't that enough safe if the client and the server use the same key and MAC key ? (given that these key are generated from no less than a MasterSecret). I kind of think that it seem a bit overprotected..

  2. When you have the MasterSecret, how do you expand it to create MAC keys and keys ? I doubt that we just take the first N bytes for the key and the rest for the MAC key...

    Moreover, the phrase When keys and MAC keys are generated, the master secret is used as an entropy source. (section 8:3) bothers me. Is it why I'm not able to understand how expanding the keys ?

4

Q1. Why two sets of key material?

In section 8:3, they say that we create 2 MAC keys and 2 keys. Isn't that enough safe if the client and the server use the same key and MAC key ? (given that these key are generated from no less than a MasterSecret). I kind of think that it seem a bit overprotected..

No. This is done for a serious reason. This makes it actually harder to attack. There is a class of attack, where you just reflect what one side said back to itself. This is called a Reflection Attack. And by having direction fixed keys, you make that class of attack impossible.

Q2. How to chop up the key block?

When you have the MasterSecret, how do you expand it to create MAC keys and keys ? I doubt that we just take the first N bytes for the key and the rest for the MAC key

Sorry to disappoint you, but that's it actually. There is not much magic here.

You have the key block which is a long octet string. And then you simply chop it up into 6 smaller parts.

RFC

Here's the section in the TLS 1.2 RFC:

  client_write_MAC_key[SecurityParameters.mac_key_length]
  server_write_MAC_key[SecurityParameters.mac_key_length]
  client_write_key[SecurityParameters.enc_key_length]
  server_write_key[SecurityParameters.enc_key_length]
  client_write_IV[SecurityParameters.fixed_iv_length]
  server_write_IV[SecurityParameters.fixed_iv_length]

So that's six parts. And in that exact order. Odd entries (1, 3, 5) are for the client_write direction. Even entries (2, 4, 6) are for the server_write direction.

OpenSSL

Here's the chopping bit in OpenSSL:

  • p is the key block.

This gets chopped up into:

  • ms, MAC secret
  • key, bulk encryption key
  • iv, initialization vector

Source code from OpenSSL's t1_enc.c:

if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
    (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
    ms = &(p[0]);
    n = i + i;
    key = &(p[n]);
    n += j + j;
    iv = &(p[n]);
    n += k + k;
    exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
    exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
    client_write = 1;
} else {
    n = i;
    ms = &(p[n]);
    n += i + j;
    key = &(p[n]);
    n += j + k;
    iv = &(p[n]);
    n += k;
    exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
    exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
    client_write = 0;
}

I don't speak C too well. So I don't really get it.

  • I don't understand the indexing into p.
  • I don't understand why they only select one half of the keys. Each end needs both sets. One set to write to the other end. And one set read what the other end said. -- I guess that chopping happens elsewhere.
  • 1
    tls1_change_cipher_state (or the ssl3 version) is called twice at each end. When the client sends CCS it sets its sending key(s) and when the server receives CCS it sets its receiving key(s). When the server sends CCS it sets its sending key(s) and when the client receives CCS it sets its receiving key(s). (In all cases also IV for CBC in SSL3 and TLS1.0, before that design flaw was fixed.) C programming isn't on-topic here, but trust me to a C programmer it is reasonably clear, plus if it was wrong all OpenSSL apps would fail on almost every use, and people would have noticed that. – dave_thompson_085 Sep 5 '15 at 6:29
  • Thanks ! I have a MasterSecret of 32 bytes (SHA256). How could I make him generate the 2 128bit-keys and the 2 128bit-MACs ? Should I run it 2 times, or use SHA512 instead ? – EisenHeim Sep 11 '15 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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