Subject: [TLS] New Key derivations for TLS1.3

From: Michael StJohns <[email-masked]>
Date: Sat, 21 Sep 2013 15:43:31 -0400

Following up on the previous discussion, I propose the following changes 
to the key derivation steps for TLS.  This adds a length field for each 
key being derived to the PRF seed value.  For the pre-master to master 
secret derivation, this is a single 32 bit length field of value 48.  
For the master to key expansion derivation, these are 6 32 bit fields 
each representing the length of one of the keys (or IVs to be derived).

By doing this, varying the length of any one of the sub keys completely 
changes the key stream.  That prevents the type of attack described by 
Juraj.

I spec'd 6 fields for the key expansion derivation instead of three to 
make this completely general - and to allow it to be used with the key 
material export RFCs.

As a side note, most of the KDFs spec'd by NIST require the key length 
to be included as part of the public information fed into the Key 
Derivation Function (KDF).

Mike

>       Computing the Master Secret
>
>
>
>     For all key exchange methods, the same algorithm is used to convert
>     the pre_master_secret into the master_secret.  The pre_master_secret
>     should be deleted from memory once the master_secret has been
>     computed.
>
>        master_secret = PRF(pre_master_secret, "master secret",
>                            ClientHello.random + ServerHello.random +
48  (expressed as 32 bit NBO)
> )
>                            [0..47];
>
>     The master secret is always exactly 48 bytes in length.  The length
>     of the premaster secret will vary depending on key exchange method.

Key Calculation
> When keys and MAC keys are generated, the master secret is used as an
>     entropy source.
>
>     To generate the key material, compute
>
>        key_block = PRF(SecurityParameters.master_secret,
>                        "key expansion",
>                        SecurityParameters.server_random +
>                        SecurityParameters.client_random +
SecurityParameters.mac_key_length +
SecurityParameters.mac_key_length +
SecurityParameters.enc_key_length +
SecurityParameters.enc_key_length +
SecurityParameters.fixed_iv_length +
SecurityParameters.fixed_iv_length
> );
>
>     until enough output has been generated.  Then, the key_block is
>     partitioned as follows:
>
>        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]