Skip to main content

5. Key Derivation Functions

  1. Key Derivation Functions (KDFs)

Section 8.4 of [RFC9052] contains a generic description of key derivation functions. This document defines a single context structure and a single KDF. These elements are used for all of the recipient algorithms defined in this document that require a KDF process. These algorithms are defined in Sections 6.1.2, 6.3.1, and 6.4.1.

5.1. HMAC-Based Extract-and-Expand Key Derivation Function (HKDF)

The HKDF key derivation algorithm is defined in [RFC5869] and [HKDF].

The HKDF algorithm takes these inputs:

secret: A shared value that is secret. Secrets may be either previously shared or derived from operations like a Diffie-Hellman (DH) key agreement.

salt: An optional value that is used to change the generation process. The salt value can be either public or private. If the salt is public and carried in the message, then the "salt" algorithm header parameter defined in Table 9 is used. While [RFC5869] suggests that the length of the salt be the same as the length of the underlying hash value, any positive salt length will improve the security, as different key values will be generated. This parameter is protected by being included in the key computation and does not need to be separately authenticated. The salt value does not need to be unique for every message sent.

length: The number of bytes of output that need to be generated.

context information: Information that describes the context in which the resulting value will be used. Making this information specific to the context in which the material is going to be used ensures that the resulting material will always be tied to that usage. The context structure defined in Section 5.2 is used by the KDFs in this document.

PRF: The underlying pseudorandom function to be used in the HKDF algorithm. The PRF is encoded into the HKDF algorithm selection.

HKDF is defined to use HMAC as the underlying PRF. However, it is possible to use other functions in the same construct to provide a different KDF that is more appropriate in the constrained world. Specifically, one can use AES-CBC-MAC as the PRF for the expand step, but not for the extract step. When using a good random shared secret of the correct length, the extract step can be skipped. For the AES algorithm versions, the extract step is always skipped.

The extract step cannot be skipped if the secret is not uniformly random -- for example, if it is the result of an ECDH key agreement step. This implies that the AES HKDF version cannot be used with ECDH. If the extract step is skipped, the "salt" value is not used as part of the HKDF functionality.

The algorithms defined in this document are found in Table 8.

   +==============+===================+========================+
| Name | PRF | Description |
+==============+===================+========================+
| HKDF SHA-256 | HMAC with SHA-256 | HKDF using HMAC |
| | | SHA-256 as the PRF |
+--------------+-------------------+------------------------+
| HKDF SHA-512 | HMAC with SHA-512 | HKDF using HMAC |
| | | SHA-512 as the PRF |
+--------------+-------------------+------------------------+
| HKDF AES- | AES-CBC-MAC-128 | HKDF using AES-MAC as |
| MAC-128 | | the PRF w/ 128-bit key |
+--------------+-------------------+------------------------+
| HKDF AES- | AES-CBC-MAC-256 | HKDF using AES-MAC as |
| MAC-256 | | the PRF w/ 256-bit key |
+--------------+-------------------+------------------------+

Table 8: HKDF Algorithms

+======+=======+======+============================+=============+
| Name | Label | Type | Algorithm | Description |
+======+=======+======+============================+=============+
| salt | -20 | bstr | direct+HKDF-SHA-256, | Random salt |
| | | | direct+HKDF-SHA-512, | |
| | | | direct+HKDF-AES-128, | |
| | | | direct+HKDF-AES-256, ECDH- | |
| | | | ES+HKDF-256, ECDH-ES+HKDF- | |
| | | | 512, ECDH-SS+HKDF-256, | |
| | | | ECDH-SS+HKDF-512, ECDH- | |
| | | | ES+A128KW, ECDH-ES+A192KW, | |
| | | | ECDH-ES+A256KW, ECDH- | |
| | | | SS+A128KW, ECDH-SS+A192KW, | |
| | | | ECDH-SS+A256KW | |
+------+-------+------+----------------------------+-------------+

Table 9: HKDF Algorithm Parameters

5.2. Context Information Structure

The context information structure is used to ensure that the derived keying material is "bound" to the context of the transaction. The context information structure used here is based on that defined in [SP800-56A]. By using CBOR for the encoding of the context information structure, we automatically get the same type and length separation of fields that is obtained by the use of ASN.1. This means that there is no need to encode the lengths for the base elements, as it is done by the encoding used in JSON Object Signing and Encryption (JOSE) (Section 4.6.2 of [RFC7518]).

The context information structure refers to PartyU and PartyV as the two parties that are doing the key derivation. Unless the application protocol defines differently, we assign PartyU to the entity that is creating the message and PartyV to the entity that is receiving the message. By defining this association, different keys will be derived for each direction, as the context information is different in each direction.

The context structure is built from information that is known to both entities. This information can be obtained from a variety of sources:

  • Fields can be defined by the application. This is commonly used to assign fixed names to parties, but it can be used for other items such as nonces.

  • Fields can be defined by usage of the output. Examples of this are the algorithm and key size that are being generated.

  • Fields can be defined by parameters from the message. We define a set of header parameters in Table 10 that can be used to carry the values associated with the context structure. Examples of this are identities and nonce values. These header parameters are designed to be placed in the unprotected bucket of the recipient structure; they do not need to be in the protected bucket, since they are already included in the cryptographic computation by virtue of being included in the context structure.

+==========+=======+======+===========================+=============+ | Name | Label | Type | Algorithm | Description | +==========+=======+======+===========================+=============+ | PartyU | -21 | bstr | direct+HKDF-SHA-256, | PartyU | | identity | | | direct+HKDF-SHA-512, | identity | | | | | direct+HKDF-AES-128, | information | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyU | -22 | bstr | direct+HKDF-SHA-256, | PartyU | | nonce | | / | direct+HKDF-SHA-512, | provided | | | | int | direct+HKDF-AES-128, | nonce | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyU | -23 | bstr | direct+HKDF-SHA-256, | PartyU | | other | | | direct+HKDF-SHA-512, | other | | | | | direct+HKDF-AES-128, | provided | | | | | direct+HKDF-AES-256, | information | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -24 | bstr | direct+HKDF-SHA-256, | PartyV | | identity | | | direct+HKDF-SHA-512, | identity | | | | | direct+HKDF-AES-128, | information | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -25 | bstr | direct+HKDF-SHA-256, | PartyV | | nonce | | / | direct+HKDF-SHA-512, | provided | | | | int | direct+HKDF-AES-128, | nonce | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -26 | bstr | direct+HKDF-SHA-256, | PartyV | | other | | | direct+HKDF-SHA-512, | other | | | | | direct+HKDF-AES-128, | provided | | | | | direct+HKDF-AES-256, | information | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+

               Table 10: Context Algorithm Parameters

We define a CBOR object to hold the context information. This object is referred to as COSE_KDF_Context. The object is based on a CBOR array type. The fields in the array are:

AlgorithmID: This field indicates the algorithm for which the key material will be used. This normally is either a key wrap algorithm identifier or a content encryption algorithm identifier. The values are from the "COSE Algorithms" registry. This field is required to be present. The field exists in the context information so that a different key is generated for each algorithm even if all of the other context information is the same. In practice, this means if algorithm A is broken and thus finding the key is relatively easy, the key derived for algorithm B will not be the same as the key derived for algorithm A.

PartyUInfo: This field holds information about PartyU. The PartyUInfo is encoded as a CBOR array. The elements of PartyUInfo are encoded in the order presented below. The elements of the PartyUInfo array are:

  identity:  This contains the identity information for PartyU.  The
identities can be assigned in one of two manners. First, a
protocol can assign identities based on roles. For example,
the roles of "client" and "server" may be assigned to different
entities in the protocol. Each entity would then use the
correct label for the data it sends or receives. The second
way for a protocol to assign identities is to use a name based
on a naming system (i.e., DNS or X.509 names).

We define an algorithm parameter, "PartyU identity", that can
be used to carry identity information in the message. However,
identity information is often known as part of the protocol and
can thus be inferred rather than made explicit. If identity
information is carried in the message, applications SHOULD have
a way of validating the supplied identity information. The
identity information does not need to be specified and is set
to nil in that case.

nonce: This contains a nonce value. The nonce can be either
implicit from the protocol or carried as a value in the
unprotected header bucket.

We define an algorithm parameter, "PartyU nonce", that can be
used to carry this value in the message; however, the nonce
value could be determined by the application and its value
obtained in a different manner.

This option does not need to be specified; if not needed, it is
set to nil.

other: This contains other information that is defined by the
protocol. This option does not need to be specified; if not
needed, it is set to nil.

PartyVInfo: This field holds information about PartyV. The content of the structure is the same as for the PartyUInfo but for PartyV.

SuppPubInfo: This field contains public information that is mutually known to both parties, and is encoded as a CBOR array.

  keyDataLength:  This is set to the number of bits of the desired
output value. This practice means if algorithm A can use two
different key lengths, the key derived for the longer key size
will not contain the key for the shorter key size as a prefix.

protected: This field contains the protected parameter field. If
there are no elements in the "protected" field, then use a
zero-length bstr.

other: This field is for free-form data defined by the
application. For example, an application could define two
different byte strings to be placed here to generate different
keys for a data stream versus a control stream. This field is
optional and will only be present if the application defines a
structure for this information. Applications that define this
SHOULD use CBOR to encode the data so that types and lengths
are correctly included.

SuppPrivInfo: This field contains private information that is mutually known private information. An example of this information would be a pre-existing shared secret. (This could, for example, be used in combination with an ECDH key agreement to provide a secondary proof of identity.) The field is optional and will only be present if the application defines a structure for this information. Applications that define this SHOULD use CBOR to encode the data so that types and lengths are correctly included.

The following CDDL fragment corresponds to the text above.

PartyInfo = ( identity : bstr / nil, nonce : bstr / int / nil, other : bstr / nil )

COSE_KDF_Context = [ AlgorithmID : int / tstr, PartyUInfo : [ PartyInfo ], PartyVInfo : [ PartyInfo ], SuppPubInfo : [ keyDataLength : uint, protected : empty_or_serialized_map, ? other : bstr ], ? SuppPrivInfo : bstr ]