Subject: [TLS] IV generation

From: Daniel Migault <[email-masked]>
Date: Wed, 27 Aug 2014 13:11:03 +0200

Hi,

draft-stjohns-tls-tls13-crypto-infra-00 [1] provides TLS crypto
construction. I found the document interesting and well written, so thank
you for doing so.

However, I have a question related to the IV  generation, and I would be
happy to get some feed backs. In section 4.4 it recommends to generate the
IV as follows:

"""
 iv_data = PRDG ("clientAndServerIV", context,
                   2* SecurityParameters.fixed_iv_length * 8);

   Then, iv_data is partitioned as follows:

   client_write_IV[SecurityParameters.fixed_iv_length];
   server_write_IV[SecurityParameters.fixed_iv_length];
"""

I am considering assymetric connectivity where one peer sends all the data,
whereas the other only receives. (In my use case I use IPsec.)

In this case, this scheme seems to present the following drawbacks:
    1) It seems unnecessary to generate the receivers' IVs.
    2) More over it seems like a potential attack vector for memory/CPU
exhaustion. If I suppose IVs are used in the order they are generated, then
the receiver uses rIV[1], while the sender uses sIV[1]...., sIV[N]. If the
receiver is likely to use rIV2 at the end of the download, then the sender
needs to keep the values of r[IV[2], ..., rIV[N], or to re-compute them
when used by the receiver.
    3) rIV and sIV may be seen as to distinct function, and thus use
different keys.

As a result, it seems preferable to use something like 1) generating a
server_iv_key and a client_iv_key 2) using that key to generate client_iv
and server_iv separately.
## this would be a key derive from the master for example
key_iv_client_server = KDF( key_iv, "clientAndServerIV", context, 2 *
SecurityParameters.fixed_iv_length * 8)

## the iv key is used to derive the two subkeys
key_iv_client = key_iv_client_server[:SecurityParameters.fixed_iv_length]
key_iv_server = key_iv_client_server[SecurityParameters.fixed_iv_length:]
client_iv = KDF(key_iv_client, "clientIV", context,

SecurityParameters.fixed_iv_length * 8)

server_iv = KDF(key_iv_server, "clientIV", context,

SecurityParameters.fixed_iv_length * 8)

This would be an alternative, but maybe it might be easier to use PRDG
instead of KDF and using key_iv_client (resp. key_iv_client) as context.
Both keys may also directly derived from the master.

[1]
http://trac.tools.ietf.org/id/draft-stjohns-tls-tls13-crypto-infra-00.txt

-- 
Daniel Migault
Orange Labs -- Security
+33 6 70 72 69 58

---

From: Michael StJohns <[email-masked]>
Date: Wed, 27 Aug 2014 14:50:55 -0400

See in line

On 8/27/2014 7:11 AM, Daniel Migault wrote:
> construction. I found the document interesting and well written, so 
> thank you for doing so.
>
> However, I have a question related to the IV  generation, and I would 
> be happy to get some feed backs. In section 4.4 it recommends to 
> generate the IV as follows:
>
> """
> I am considering assymetric connectivity where one peer sends all the 
> data, whereas the other only receives. (In my use case I use IPsec.)
>
>     2) More over it seems like a potential attack vector for 
> memory/CPU exhaustion. If I suppose IVs are used in the order they are 
> generated, then the receiver uses rIV[1], while the sender uses 
> sIV[1]...., sIV[N]. If the receiver is likely to use rIV2 at the end 
> of the download, then the sender needs to keep the values of r[IV[2], 
> ..., rIV[N], or to re-compute them when used by the receiver.

I didn't understand what you were getting at until this point.  TLS uses 
the term "IV" in a way that isn't always consistent with cryptographic 
usage.  If the TLS crypto is a stream crypto, then the IV really is an 
IV for the stream cipher: it's used when you initialize the stream 
cipher before sending the first record; the state of the stream cipher 
persists from record to record.  If it's an AEAD cipher, its a nonce or 
the fixed part of a per-message IV; there's a new crypto context with 
each message each initialized with a unique IV.   In the block cipher 
mode for say CBC it *was* the IV for the first message; second and 
subsequent messages took their IV from the last block of the previous 
message; that changed for TLS1.2.

So for TLS there are only ever the two 'session' "IV's" even though 
there are many 'message' IVs built from the session IV.

Note to self: figure out how to fix the language in the TLS document.

[Longer winded discussion for the CCM AEAD mode:  The TLS IV is used to 
provide part of the fixed part of a counter block.   The per message 
nonce (see appendix A of SP800-38C) consists of the concatenation of the 
TLS generated IV (32 bits worth) and the message sequence number for a 
total of 96 bits.  The counter part of the counter block is the 128 
minus 96 right most bits initialized to 1 and counting up per message 
block.  There are other variations, but they are all similar constructs]

> server_iv_key and a client_iv_key 2) using that key to generate 
> client_iv and server_iv separately.
> instead of KDF and using key_iv_client (resp. key_iv_client) as 
> context. Both keys may also directly derived from the master.
>
>
> [1] 
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

---

From: Peter Dettman <[email-masked]>
Date: Thu, 28 Aug 2014 09:18:17 +0700

On 28/08/2014 1:50 am, Michael StJohns wrote:
> If the TLS crypto is a stream crypto, then the IV really is an IV for 
> the stream cipher: it's used when you initialize the stream cipher 
> before sending the first record; the state of the stream cipher 
> persists from record to record.
While RC4 does not use an IV, and is stateful across records, e.g. 
http://tools.ietf.org/html/draft-josefsson-salsa20-tls-04 proposes 
Salsa20 as a stream cipher using a per-record nonce; so statefulness is 
not an inherent property of a TLS stream cipher and I wouldn't expect to 
see new ones proposed with that limitation (which prevents use in DTLS) 
either.

> In the block cipher mode for say CBC it *was* the IV for the first 
> message; second and subsequent messages took their IV from the last 
> block of the previous message; that changed for TLS1.2.
That changed for TLS 1.1, with the introduction of an explicit 
per-record IV for block ciphers.

Pete

---

From: Yoav Nir <[email-masked]>
Date: Thu, 28 Aug 2014 08:06:47 +0300

On Aug 28, 2014, at 5:18 AM, Peter Dettman <[email-masked]> wrote:

>> If the TLS crypto is a stream crypto, then the IV really is an IV for the stream cipher: it's used when you initialize the stream cipher before sending the first record; the state of the stream cipher persists from record to record.
> While RC4 does not use an IV, and is stateful across records, e.g. http://tools.ietf.org/html/draft-josefsson-salsa20-tls-04 proposes Salsa20 as a stream cipher using a per-record nonce; so statefulness is not an inherent property of a TLS stream cipher and I wouldn't expect to see new ones proposed with that limitation (which prevents use in DTLS) either.

Salsa20 (and ChaCha) are more like counter-mode block ciphers than real streams. That may be splitting hairs, but the important property here is that real stream ciphers don’t accept a nonce input.

Yoav