Subject: [TLS] Thoughts on Hardware Support

From: Watson Ladd <[email-masked]>
Date: Sat, 14 Feb 2015 11:23:30 -0800

Dear all,

A while ago I promised Michael St. Johns to think hard about his goal
of making it possible to use hardware to secure the record layer
without dirty hacks. For those unaware of the problem, the same key is
used to derive encryption keys that shouldn't go out on the wire, and
IVs that do, and so it becomes difficult to ensure that keys can't be
leaked, if you expose the IV generation.

I think the easiest way is to eliminate the IV derivation entirely,
and have the record layer send the entire nonce each time. if that's
too much a waste of bandwidth, then we can specify entirely the
portion that is in TLS 1.2 derived from the MS. I think this is in
spirit similar to his proposal, but I don't recall the exact details.

I'm sure there are disadvantages of this change I am missing, or
aspects of the problem that I'm neglecting, but I seem to recall this
being the major issue.

Sincerely,
Watson Ladd

---

From: Michael StJohns <[email-masked]>
Date: Sat, 14 Feb 2015 15:24:57 -0500

> spirit similar to his proposal, but I don't recall the exact details.

The other way of doing this is to not make IV derivation dependent on 
secret material.  Basically, I suggested that instead to use the same 
KDF function, but with a key of zero and a context of the server and 
client randoms.  That makes IV (or for most AEAD counter based thingies 
- nonce) derivation a straightforward entropy extraction from the two 
generated random numbers.  Alternately, use output of the hash of those 
two concatenated values plus a counter (so you can get more than 1 block 
of extracted data) plus a label (so you can use the same randoms for 
different expansions if you need to).

E.g.

IVDATA = {};
label = { <some number of well known bytes> };
numblocks = CEIL (numBytesNeeded/hashOutputSize);

for (i = 1; i < numblocks; i++) {
     IVDATA = IVDATA || HASH (counter(as uint32 big endian) || label || 
serverRandom || clientRandom);
}

return LTRUNC(IVDATA, numBytesNeeded);

This uses all public data and functions to produce public data (the IV 
or Nonce).

I apologize as I haven't had the cycles to do a pull request and add the 
crypto constructs changes I'm proposing.

Mike

---

From: Michael StJohns <[email-masked]>
Date: Sat, 14 Feb 2015 18:07:30 -0500

A private message indicated that it might be useful if I clarified my 
thoughts below.  The problem is the embedded use of the term "IV" in the 
TLS documents.

The master_secret expansion (section 6.3 of rfc5246) still refers to the 
last part of the data generated as IVs - but TLS1.2 eliminated the use 
of these as actual IVs (plus implicit generation of per-message IVs) for 
the existing non-AEAD, non-counter modes in favor of explicit 
per-message randomly generated IVs.

The AEAD ciphersuite documents resurrected the use of the iv data from 
the master secret expansion for use as the per-key (identical for all 
TLS messages in a session) nonce.

pure IVs (mostly - check the specific mode) require unpredictability.  
Nonces (at least for defined modes) only require uniqueness on a per-key 
basis.

Where the mode needs per-message IV unpredictablity, follow section 
6.2.3.2 of the TLS1.2 RFC.  Where you need to establish a common unique 
nonce, use an entropy expansion/extraction from client/server random 
without dependency on key material.  There shouldn't be any middle cases.

Mike

On 2/14/2015 3:24 PM, Michael StJohns wrote:
> client randoms.  That makes IV (or for most AEAD counter based 
> thingies - nonce) derivation a straightforward entropy extraction from 
> the two generated random numbers. Alternately, use output of the hash 
> of those two concatenated values plus a counter (so you can get more 
> than 1 block of extracted data) plus a label (so you can use the same 
> randoms for different expansions if you need to).
>
>
> E.g.
>
>
> IVDATA = {};
> I apologize as I haven't had the cycles to do a pull request and add 
> the crypto constructs changes I'm proposing.
>
> Mike
>
>
>

---

From: Ilari Liusvaara <[email-masked]>
Date: Sun, 15 Feb 2015 08:54:22 +0200

> leaked, if you expose the IV generation.

IVs derived from keys do not go on the wire, at least not in any AEAD
cipher defined for TLS I have seen.

The schemes I am aware have two styles here:

1) First 4 octets are fixed per connection (derived from MS), the
   remaining 8 are given for each record (too short for nondeteministic
   operation!).
2) First 4 octets are fixed per connection (derived from MS), the
   remaining 8 are taken from RSN+epoch (saves 8 octets/record).

IIRC, the problem was that by specifying garbage parameters for key
derivation, it was possible to get the key as IV.

> spirit similar to his proposal, but I don't recall the exact details.

I think his proposal was to feed the key derivation parameters (complete
with key types) to the PRF (and doing odd things with the IV).

But if one has typed keys, one can easily define a IV type and use that
for IVs (safe if the PRF is any good).

So I think the simplest fix would be to append a array of (type, length)
descriptors to the current client and server randoms in seed for the
subkeys PRF invocation (no need for length of array).

E.g.
<type byte, 0=>AEAD key, 1=>IV, others reserved>
<bit-7-mpint (shortest) length for subkey in bytes>

For AES-128-GCM:
<server random, 32 bytes>    //As currently
<client random, 32 bytes>    //As currently
00 10          //AEAD encryption subkey, 16 bytes.
00 10          //AEAD encryption subkey, 16 bytes.
01 04          //IV, 4 bytes.
01 04          //IV, 4 bytes.

(Total of 72 bytes).

For AES-256-GCM and CHACHA-POLY1305:
<server random, 32 bytes>    //As currently
<client random, 32 bytes>    //As currently
00 20          //AEAD encryption subkey, 32 bytes.
00 20          //AEAD encryption subkey, 32 bytes.
01 04          //IV, 4 bytes.
01 04          //IV, 4 bytes.

(Total of 72 bytes).

For XXX-1024-HMAC-YYY256 (128 byte keys, 32 byte IVs):
<server random, 32 bytes>    //As currently
<client random, 32 bytes>    //As currently
00 80 01        //AEAD encryption subkey, 128 bytes.
00 80 01        //AEAD encryption subkey, 128 bytes.
01 20           //IV, 32 bytes.
01 20           //IV, 32 bytes.

(Total of 74 bytes).

-Ilari