Network Working Group | M. StJohns |
Internet-Draft | April 09, 2014 |
Intended status: Informational | |
Expires: October 11, 2014 |
TLS Crypto Constructs for Version 1.3
draft-stjohns-tls-tls13-crypto-infra-00
This document describes a set of replacements for the TLS cryptographic constructs for use with TLS1.3 and later. The constructs used in versions of TLS 1.2 and prior have some issues with respect to secure implementation using generic security hardware.
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."
This Internet-Draft will expire on October 11, 2014.
Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
This document describes a set of replacements for the TLS1.2 and earlier cryptographic constructs. Those constructs were based on the concept of a PRF or pseudo-random function. The new constructs still use a single core function per connection, but describe the mappings between that core function and the actual TLS usages slightly differently.
This text is meant to be contributed text or concepts for the next TLS specification version rather than a stand-alone standard. As such it's submitted primarily for publication as an internet draft but may be published as an Informational RFC depending on the timing of the TLS1.3 work. No attempt has been made to provide specific edits to the existing TLS1.2 specifications.
Although never described as such in the original TLS documents, there are three standard cryptographic constructs used for different purposes in the TLS protocol negotiation:
As defined in TLS1.2 ([RFC5246]) and before ([RFC4346] and others), these functions were based on the TLS-PRF function. Because of the way they were defined, and given the specific uses of various TLS keys, it was difficult or impossible to implement these functions securely in general purpose hardware security modules. It was trivially easy to extract session key material.
This document makes a few changes in the way keys are used and derived:
For the purposes of providing cryptographic separation of key material, each of the keys used within TLS are given a defined type. These type values are used as input to the Key Deriviation or expansion processing.
enum { masterKey (1), integrityKey(2), encryptionKey(4), aeadKey (6) } KeyType;
Note that a block cipher key (e.g. AES) can be typed as any of Integrity (e.g. CMAC), Encryption or AEAD depending on its actual use.
The following keys are derived from the premaster secret:
The master secret is always 48 bytes (384 bits) in length. The negotiation mac key is always 32 bytes (256 bits) in length. [Discussion: Alternately, the mac key is always the native length of the selected PRF to avoid the impedence match function?]
The following keys are derived from the master secret. Depending on the needs of the selected cipher suite, some of these keys may not need to derived.
The lengths of these keys vary per cipher suite. The types of the 'client write MAC key' and the 'server write MAC key' are always Integrity Key (0x02). The types of the 'client write encryption key' and 'server write encryption key' are either Encryption Key (0x04) or AEAD key (0x06).
If a key is not required for the cipher suite, it is omitted from the derivation step. There is no placeholder of a zero length key.
The negotiated (SecurityParameters.prf_algorithm) pseudo-random function or PRF is either an HMAC function or CMAC function. If unspecified, HMAC-SHA256 shall be used.
The HMAC construct is based on an underlying non-invertable hash or summary function and is formed as per [RFC2104] or [FIPS198].
The CMAC construct is based on an underlying block cipher and is formed as per [RFC4493] or [SP800-38B].
The generic CMAC construct as defined in [SP800-38B] requires a specific key size based on the underlying block cipher. Unlike the HMAC specification documents, neither of the CMAC specification documents describe a way to take a key of any length and adapt it for use it with CMAC. TLS will use the mechanism suggested in [SP800-56C] (Key Derivation through Extraction-then-Expansion), for adapting keys of any length to output a CMAC key. Using the approach in section 5 of [SP800-56C], and using an all '0's salt, convert the input key to a key of the appropriate size for the CMAC function. Process:
The key derivation function (KDF) used for TLS1.3 and later is the function described in section 5.1 of [SP800-108] (Key Derivation Using Pseudorandom Functions), - "KDF in Counter Mode". This KDF construct is able to produce any amount of key material by using an incrementing counter, a master key, and some amount of input public data (e.g. the label, client and server random, etc) to produce multiple blocks of pseudo-random data which are concatenated to produce the key data stream.
KDF (key, label, context, bitsToGenerate) ::= KDF-SP800-108-51 (key, label, context, bitsToGenerate);
The KDF construct allows the derivation of any amount of random data. It is generally used to generate additional key material. When used with the 'KeyExpansionContext' Context construct, it has the property that any change in the number, type or length of the keys to be derived completely changes the output key stream.
See Section 4.1, Premaster Secret Expansion and Section 4.2, Master Secret Expansion for the specific orders in which keys are derived for each usage. By convention, master keys are derived first, then MAC keys, and then encryption or AEAD keys. Within the type of keys, client write keys are derived before server write keys.
The general calling form for this KDF is:
Where 'K sub O' is the output key stream. The remainder of the fields are described below in Section 3.2.1.
If 'K sub I' is private data (e.g. typed as a masterSecret), then the output 'K sub O' is also private data. Otherwise, if 'K sub I' is public data (e.g. for use below at Section 3.4 in the PRDG), then the output 'K sub O' is also public data.
If the construct is being used to produce key material (e.g. with the KeyExpansionContext and a secret key), the output keys are formed by producing multiple blocks of key stream, concatenating them, and then splitting up the key stream in to key data of the appropriate lengths for each derived key. Otherwise, K sub O may be broken up as desired for the usage.
Although this construct permits the production of fractional byte (e.g. 12 bit) keys, there are no current TLS keys defined with fractional byte lengths.
Each pseudo-random key stream block 'K(i)' is produced using the function:
The values for each input variable (described in step 4.a of section 5.1 of [SP800-108]) are mapped as follows:
The specific Context construct used depends on what the KDF function is being used for. The GenericContext may be used for key exporters and other to-be-defined usages. The KeyExpansionContext is used for the expansion of keys typed as masterKey, including the pre-master secret and the expansion of the master secret. The RandomBitContext is used for the generation of public unpredictable data such as IV's.
enum { generic, expansion, randomBits } ContextTag; struct { opaque contextBytes; } GenericContext; struct { uint8 clientRandom[32]; /* ClientHello.random */ uint8 serverRandom[32]; /* ServerHello.random */ uint32 keyCount; /* Num keys to derive */ KeyType keyTypes[keycount]; uint16 keyLengths[keycount]; /* Key lengths in bits */ } KeyExpansionContext; struct { uint8 clientRandom[32]; uint8 serverRandom[32]; } RandomBitContext; struct { select (ContextTag) { /* implicit selection */ case generic: GenericContext; case expansion: KeyExpansionContext; case randomBits: RandomBitContext; }; } Context;
The clientRandom and serverRandom are the bytes provided by the ClientHello.random and ServerHello.random fields respectively. KeyCount is the number of keys being derived with this call to the KDF. KeyTypes contains the types of keys being derived, and KeyLengths the matching lengths for those keys in bits.
The output stream, K sub O, is produced by concatenating all of the K(i) outputs and then truncating to length L. There are CEIL(L/prfBlockSize) K(i) output blocks where 'prfBlockSize' is the output size of the PRF in bits:
K sub O := KDF (K sub I, Label, Context, L) := PRF (K sub I, 1 || Label || 0x00 || Context || L) PRF (K sub I, 2 || Label || 0x00 || Context || L) + PRF (K sub I, 3 || Label || 0x00 || Context || L) + ... [0..CEIL(L/8)]
If the desired output is keys, then K sub O is then broken up into the component keys. The following example assumes key that have bit lengths that are all multiples of 8.
pos := 0 Key[0] := K sub O[pos..pos+keyLength[0]/8-1] pos := pos + keyLength[0] Key[1] := K sub O[pos..pos+keyLength[1]/8-1] pos := pos + KeyLength[1] Key[2] := K sub O[pos..pos+keyLength[2]/8-1] pos := pos + KeyLength[2] ...
The keyed message authentication function (MAC) is the negotiated CMAC or HMAC PRF function used as is.
MAC (key, data) ::= PRF (key, data);
See Section 4.3, Finished Message for the how this function is used to produce the Finished message verify_data.
The pseudo-random data generator function uses the KDF construct described at Section 3.2 above, but uses a zero key.
PRDG (label, context, bytesNeeded) ::= KDF ( '0', label, context, bytesNeeded*8)
where:
See Section 4.4, IV Generation for how to use this function to produce IV material if required.
This section describes the proposed TLS 1.3 changes to key derivation, IV production and Finished message signatures.
The expansion of the pre-master secret always results in two keys: the master secret and the negotiation MAC key. The master secret has been defined since the first version of TLS (and its predecessor SSL). The derivation of the negoiation MAC key is new with this version.
KeyType keytypes[2] = { masterKey, integrityKey }; uint16 keylengths[2] = { 384, 256 }; KeyExpansionContext context = { ClientHello.random, ServerHellow.random, 2, keytypes, keylengths }; key_block = KDF (pre_master_secret, "master secret v2", context, 640); master_secret = key_block[0..47]; negotiation_mac_key = key_block[48..79];
There are three cases for master key expansion: integrity only, integrity plus encryption, and finally AEAD. Integrity only modes need 2 MAC keys, integrity plus encryption modes need 2 MAC keys plus two encryption keys for a total of 4 keys, and finally AEAD modes need 2 encryption keys.
Only the AEAD case is expanded below. N.B., if a key is not needed for a suite - such as integrity keys for AEAD, those keys are neither derived nor requested. While the general use case of this function is to generate session keys for TLS, it may be used by key exporters to generate any number of keys of any type simply by changing the request parameters.
/* Parameters for AEAD key derivation */ KeyType aeadTypes[2] = { aeadKey, aeadKey }; uint16 aeadLengths[2] = { SecurityParameters.enc_key_length * 8, SecurityParameters.enc_key_length * 8 }; uint32 aeadL = 2 * SecurityParameters.enc_key_length * 8; KeyExpansionContext aeadContext = { ClientHello.random, ServerHellow.random, 2, aeadTypes, aeadLengths }; /* Substitute the approriate context and L from above eg */ key_block = KDF (master_secret, "key expansion v2", aeadContext, aeadL); /* And then break it down into keys */ client_write_key = key_block[0..SecurityParameters.enc_key_length-1]; server_write_key = key_block[SecurityParameters.enc_key_length.. 2*SecurityParameters.enc_key_length-1];
The following replaces the definition of "verify_data" in section 7.4.9 of [RFC5246].
verify_data MAC (negotiation_mac_key, finished_label + handshake_messages) [0..verify_data_length-1];
Prior versions of TLS used a hash of the handshake messages as input to the TLS PRF. It's unclear there was any added security benefit to that approach after the PRF was changed to remove MD5. For this version, the handshake messages are input without hashing to the CMAC or HMAC function represented by the PRF.
If necessary for the cryptosuite, the IV data is produced as follows:
RandomBitContext context = { ClientHello.random, ServerHello.random }; 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];
To be provided.