[Author's note: This got triggered by the discussion on Doran's key wrapping mechanism using EC as the outer mechanism. This fixes the existing ECDH mechanisms (and makes moot the 2.30 fixes for CKM_ECDH1_DERIVE et al), expands the set of mechanisms to allow the multi-key versions of ECDH. It also provides a standard template and structure for KDFs in the future.]

1  Elliptic Curve Key Agreement Mechanisms

¨  CK_ECDH_STANDARD_DERIVE_PARAMS, CK_ECDH_STANDARD_DERIVE_PARAMS_PTR

CK_ECDH_STANDARD_DERIVE_PARAMS is a structure that provides the parameters for various ECDH key derivation mechanisms, where each party contributes one or two key pairs. The structure is defined as follows:

typedef struct CK_ECDH_STANDARD_DERIVE_PARAMS {

CK_MECHANISM_PTR pKdf;

CK_ULONG ulOtherPublicKeyLen;

CK_BYTE_PTR pOtherPublicKey;

CK_OBJECT_HANDLE hEphemeralPrivateKey;

CK_ULONG ulOtherPublicKey2Len;

CK_BYTE_PTR pOtherPublicKey2;

} CK_ECDH_STANDARD_DERIVE_PARAMS;

The fields of the structure have the following meanings:

pKdf a pointer to the mechanism structure describing the key derivation function to be applied on the output of the ECDH raw function. NULL_PTR if the output should be taken directly as key data. Note that unlike CK_ECDH1_DERIVE_PARAMS, the shared public data is provided as part of the KDF mechanism structure.

ulOtherPublicLeyLen the length in bytes of the other party’s EC public key

pOtherPublicKey pointer to other party’s EC public key value. This is formatted as an X9.62 public key. E.g. 1 byte of format and 2*N or N+1 (depending on the format) bytes of public key where N is the degree of the public key in bytes (including leading zeroes if necessary for each of the two components of the public key). The public key MUST share the curve of the private key specified by C_DeriveKey. The calling application is responsible for converting the offered public key to the compressed or uncompressed forms of the X9.62 encoding if the token does not support the offered form.

hEphemeralPrivateKey the handle to the second private key used for this mechanism, if any. This is ignored if the mechanism doesn't use a second local key pair. Set this field to CK_INVALID_HANDLE in that case.

ulOtherPublicKeyLen2 the length in bytes of the other party’s second EC public key. Generally, this is the public key from an ephemeral key pair.

pOtherPublicKeyLen2 pointer to other party’s second EC public key value. This has the identical format and restrictions as the key pointed to by pOtherPublicKey. This is NULL_PTR if not used by the mechanism.

CK_ECDH_STANDARD_DERIVE_PARAMS_PTR is a pointer to a CK_ECDH_STANDARD_DERIVE_PARAMS.

/ Functions /
Mechanism / Encrypt
Decrypt / Sign
Verify / SR
VR1 / Digest / Gen.
Key/
Key
Pair / Wrap
Unwrap / Derive /
CKM_ECDH_X9_63 / ü
CKM_ECDH_X9_63_COFACTOR / ü
CKM_ECDH_SP800_56B_C22 / ü
CKM_ECDH_SP800_56B_C12 / ü
CKM_ECDH_SP800_56B_C02 / ü

The mechanisms specified below replace and extend CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE which are now deprecated. Both of these were underspecified in 2.20 with respect to the format of the public key provided by the other party. That under-specification was corrected in 2.30, but possibly at the cost of some incompatibilities. This section replaces those mechanisms, adds the related mechanisms from [SP800-56B] and aligns the parameter structures with additional key derivation function definitions.

The mechanisms are specified in pairs with the second mechanism of the pair having "_SENSITIVE" added to the base mechanism name. The rules for the _SENSITIVE mechanisms prevent a key from being derived that has less protections that the base key or the ephemeral key (if used). The base mechanisms retain the same rules for setting CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ALWAYS_SENSITIVE and CKA_NEVER_EXTRACTABLE as were specified for CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE.

Note that the shared public data used with the key derivation functions needs to be provided as part of the KDF mechanism data, rather than in the ECDH parameter structure as it was for the deprecated mechanisms. In general, these ECDH mechanisms should be used with one of the CKM_KDF_X9_63 and CKM_KDF_SP800_56B_* key derivation mechanisms, but this is not necessarily enforced by the token.

If a mechanism uses an ephemeral private key (designated by pEphemeralPrivateKey in CK_ECDH_STANDARD_DERIVE_PARAMS), that key MUST share the same curve as the private key specified by C_DeriveKey.

All of these mechanisms derive a shared secret value of a particular length. The full shared secret (left padded if necessary with zero bytes to the nominal length of the derivation which is the degree of the curve) is the key value input to the specified KDF function. The KDF function describes how the shared secret is used to derive keying material for the specified keys.

If the KDF mechanism is omitted (set to NULL_PTR), the raw shared secret bytes from the ECDH derivation are used to form the key material, with the left-most or most significant bytes used first. An ECDH derivation produces a shared secret of a fixed length. If the key specified in the template requires more key material than that fixed length, the C_DeriveKey should fail with CKR_KEY_SIZE_RANGE.

.

These mechanisms share the following rules about key sensitivity and extractability:

·  The CKA_SENSITIVE and CKA_EXTRACTABLE attributes in the template for a new key can both be specified to be either CK_TRUE or CK_FALSE. If omitted, these attributes each take on the most restrictive value of the same attribute of the base key or the ephemeral private key if specified.

derivedKey.sensitive = template.sensitive.present ? template.sensitive : baseKey.sensitive | ephemeralKey.sensitive
derivedKey.extractable = template.extractable.present ? template.extractable : baseKey.extractable & ephemeralKey.extractable

·  If the base key OR the ephemeral private key has its CKA_ALWAYS_SENSITIVE attribute set to CK_FALSE, then the derived key will as well. If the base key AND the ephemeral private key have their CKA_ALWAYS_SENSITIVE attribute set to CK_TRUE, then the derived key has its CKA_ALWAYS_SENSITIVE attribute set to the same value as its CKA_SENSITIVE attribute.

derivedKey.alwaysSensitive = (baseKey.alwaysSensitive & ephemeralKey.alwaysSensitive) ? derivedKey.sensitive : CKA_FALSE

·  Similarly, if the base key OR the ephemeral private key has its CKA_NEVER_EXTRACTABLE attribute set to CK_FALSE, then the derived key will, too. If the base key AND the ephemeral private key have their CKA_NEVER_EXTRACTABLE attribute set to CK_TRUE, then the derived key has its CKA_NEVER_EXTRACTABLE attribute set to the opposite value from its CKA_EXTRACTABLE attribute.

dervivedKey.neverExtractable = (baseKey.neverExtractable & ephemeralKey.neverExtractable) ? ^derivedKey.extractable : CKA_FALSE;

These sensitivity rules apply to the final key produced (in the case where no KDF is used), or to the intermediate derived shared secret produced prior to its use as input to the KDF.

For these mechanisms, the ulMinKeySize and ulMaxKeySize fields of the CK_MECHANISM_INFO structure specify the minimum and maximum supported number of bits in the field sizes, respectively. For example, if a Cryptoki library supports only EC using a field of characteristic 2 which has between 2200 and 2300 elements, then ulMinKeySize = 201 and ulMaxKeySize = 301 (when written in binary notation, the number 2200 consists of a 1 bit followed by 200 0 bits. It is therefore a 201-bit number. Similarly, 2300 is a 301-bit number).

1.1 CKM_ECDH_X9_63

This is the ECDH mechanism defined in ANSI X9.63, section 6.3 without cofactor multiplication of the result (primitive of section 5.4.1). It replaces CKM_ECDH1_DERIVE. It has a parameter, a CK_ECDH_STANDARD_DERIVE_PARAMS. It uses only a single key pair from each party so pOtherPublicKey2 should be set to CK_NULL and hEphemeralPrivateKey should be set to CK_INVALID_HANDLE. Note that for curves with a co-factor of '1', this is equivalent to CKM_ECHD_X9_63_COFACTOR.

1.2 CKM_ECDH_X9_63_COFACTOR

This is the ECDH mechanism defined in ANSI X9.63, section 6.3 with cofactor multiplication of result (primitive of section 5.4.2). This is equivalent to CKM_ECDH_SP800_56A_C02. It replaces CKM_ECDH1_COFACTOR_DERIVE. It has a parameter, a CK_ECDH_STANDARD_DERIVE_PARAMS. It uses only a single key pair from each party so pOtherPublicKey2 should be set to CK_NULL and hEphemeralPrivateKey should be set to CK_INVALID_HANDLE.

1.3 CKM_ECDH_SP800_56A_C22

This is the ECDH mechanism defined in NIST SP800-56B, section 6.1.1.2. It has a parameter, a CK_ECDH_STANDARD_DERIVE_PARAMS. Both parties have two EC key pairs so all fields shall be filled in appropriately.

1.4 CKM_ECDH_SP800_56A_C12

This is the ECDH mechanism defined in NIST SP800-56B, section 6.2.1.2. This is identical to the "One-Pass Unified Model" scheme from X9.63. It has a parameter, a CK_ECDH_STANDARD_DERIVE_PARAMS. The fields to be set depend on whether this token represents the initiator or responder:

·  For the initiator (Party U), pOtherPublicKey2 must be set to CK_NULL and hEphemeralPrivateKey must be set to the handle of the initiator's second key pair private key.

·  For the responder (Party V), pOtherPublicKey2 must point to the public key data of the initiator's second key pair, and hEphemeralPrivateKey must be set to CK_INVALID_HANDLE.

1.5 CKM_ECDH_SP800_56A_C02

This is the ECDH mechanism defined in NIST SP800-56B, section 6.3.2. This is functionally identical to the mechanisms described in section 6.1.2.2 and 6.2.2.2 except for the designation of keys as static or ephemeral. It has a parameter, a CK_ECDH_STANDARD_DERIVE_PARAMS. It uses only a single key pair from each party, so pOtherPublicKey2 should be set to null and hEphemeralPrivateKey should be set to CK_INVALID_HANDLE.

2  Key Derivation

¨  CK_KDF_STANDARD_PARAMS, CK_KDF_STANDARD_PARAMS_PTR

CK_KDF_STANDARD_PARAMS is a structure that provides the parameters for various key derivation mechanisms. The structure is defined as follows:

typedef struct CK_KDF_STANDARD _PARAMS {

CK_MECHANISM_TYPE prfMechanism

CK_ULONG ulSharedPublicDataLen;

CK_BYTE_PTR pSharedPublicData;

} CK_KDF_STANDARD_PARAMS;

The fields of the structure have the following meanings:

prfMechanism the pseudo-random function used to produce the key stream for this mechanism.

ulSharedPublicDataLen the length in bytes of the public data shared between the two parties.

pSharedPublicData the public data shared between the two parties. The actual format of this data may be proscribed by the KDF mechanism.

/ Functions /
Mechanism / Encrypt
Decrypt / Sign
Verify / SR
VR1 / Digest / Gen.
Key/
Key
Pair / Wrap
Unwrap / Derive /
CKM_KDF_X9_63 / ü
CKM_KDF_SP800_56B_CONCAT / ü
CKM_KDF_SP800_56B_ASN1 / ü
CKM_KDF_SP800_108_COUNTER / ü
CKM_KDF_SP800_108_PIPELINE / ü

While KDF's in general are used to derive symmetric key material, these mechanisms MAY be used to derive an elliptic curve private key. The method used is described in FIPS 186-4, B.1.1, "Key Pair Generation Using Extra Bits". Basically, generate "N + 64" bits of key material from the KDF and take that value as an integer MOD(p) of the curve to derive a private key where N is LEN(p) in bits (and also the length of the output private key) and where 'p' is the prime of the curve. That value is contributed as the CKA_VALUE of the derived private key.

All of these KDF mechanisms share the following rules about key sensitivity and extractability:

·  If the base key has its CKA_SENSITIVE attribute set to CKA_TRUE or the template has CKA_SENSITIVE set to CKA_TRUE, then the derived key will have CKA_SENSITIVE set to CKA_TRUE, otherwise it will be set to CKA_FALSE;

derivedKey.sensitive = baseKey.sensitive | template.sensitive

·  If the base key has its CKA_EXTRACTABLE attribute set to CKA_TRUE AND the template has CKA_EXTRACTABLE set to CKA_TRUE or is omitted, then the derived key will have CKA_EXTRACTABLE set to CKA_TRUE, otherwise it will be set to CKA_FALSE;

derivedKey.extractable = baseKey.extractable & template.extractable

·  If the base key has its CKA_ALWAYS_SENSITIVE attribute set to CK_FALSE, then the derived key will as well. If the base key have its CKA_ALWAYS_SENSITIVE attribute set to CK_TRUE, then the derived key has its CKA_ALWAYS_SENSITIVE attribute set to the same value as its CKA_SENSITIVE attribute.

derivedKey.alwaysSensitive = baseKey.alwaysSensitive & derivedKey.sensitive

·  Similarly, if the base key has its CKA_NEVER_EXTRACTABLE attribute set to CK_FALSE, then the derived key will, too. If the base key has its CKA_NEVER_EXTRACTABLE attribute set to CK_TRUE, then the derived key has its CKA_NEVER_EXTRACTABLE attribute set to the opposite value from its CKA_EXTRACTABLE attribute.

derivedKey.neverExtractable = baseKey.neverExtractable & ^derivedKey.extractable

When used in conjunction with any of the ECDH mechanisms that take a pointer to a KDF mechanism structure, the base key for the purpose of sensitivity calculations is the shared secret output of the ECDH stage.

2.1 KDFs for Key Agreement Mechanisms

2.1.1 CKM_KDF_X9_63

This is the key derivation function defined in X9.63, section 5.6.3. This has a parameter, a CK_KDF_STANDARD_PARAMS structure. The prfMechanism is any ANSI approved hash function, generally CKM_SHA1, CKM_SHA224, CKM_SHA256, CKM_SHA384 or CKM_SHA512.

2.1.2 CKM_KDF_SP800_56B_CONCAT

This is the key derivation function defined in NIST SP800-56A, section 5.8.1. This has a parameter, a CK_KDF_STANDARD_PARAMS structure. The prfMechanism is any NIST approved hash function, generally CKM_SHA1, CKM_SHA224, CKM_SHA256, CKM_SHA384 or CKM_SHA512.

2.1.3 CKM_KDF_SP800_56B_ASN1

This is the key derivation function defined in NIST SP800-56A, section 5.8.2. This has a parameter, a CK_KDF_STANDARD_PARAMS structure. The prfMechanism is any NIST approved hash function, generally CKM_SHA1, CKM_SHA224, CKM_SHA256, CKM_SHA384 or CKM_SHA512.

The public data (pSharedPublicData) provided to this mechanism MUST be a well-formed ASN1 DER encoded SEQUENCE. There is no requirement for the token to enforce any particular content for that sequence though. Other than this restriction, this mechanism is identical to CKM_KDF_SP800_56B_CONCAT.

2.2 KDFs for Key Hierarchies

These functions use either a keyed HMAC or keyed CMAC mechanism to provide a stream of pseudo-random bits derived from a master secret. Because the master secret is used as the key for the CMAC or HMAC, and because CMAC and HMAC functions generally output public data, the following restrictions apply to both of these functions to prevent the leaking of private key material:

·  These mechanisms may only be used with a CKK_GENERIC_SECRET key.

·  That generic key MUST have CKA_DERIVE = CK_TRUE, and all other key use attributes CK_FALSE.

2.2.1 CKM_KDF_SP800_108_COUNTER

This is the key derivation function defined in NIST SP800-108, section 5.1. This has a parameter, a CK_KDF_STANDARD_PARAMS structure. The prfMechanism is any NIST approved HMAC function or CMAC function, generally CKM_SHA_1_HMAC, CKM_SHA224_HMAC, CKM_SHA256_HMAC, CKM_SHA384_HMAC, CKM_SHA512_HMAC or CKM_AES_CMAC.

2.2.2 CKM_KDF_SP800_108_PIPELINE

This is the key derivation function defined in NIST SP800-108, section 5.3. This has a parameter, a CK_KDF_STANDARD_PARAMS structure. The prfMechanism is any NIST approved hash function, generally CKM_SHA1, CKM_SHA224, CKM_SHA256, CKM_SHA384 or CKM_SHA512 or CKM_AES_CMAC.

2.3 Elliptic curve Diffie-Hellman key derivation

CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE are deprecated.