diff --git a/libckteec/include/pkcs11.h b/libckteec/include/pkcs11.h index 6d7a0f77..fc2f2a58 100644 --- a/libckteec/include/pkcs11.h +++ b/libckteec/include/pkcs11.h @@ -375,6 +375,7 @@ typedef CK_MECHANISM_TYPE *CK_MECHANISM_TYPE_PTR; #define CKM_AES_CBC_ENCRYPT_DATA 0x01105 #define CKM_AES_KEY_WRAP 0x02109 #define CKM_AES_KEY_WRAP_PAD 0x0210a +#define CKM_HKDF_DERIVE 0x0402a typedef struct CK_MECHANISM_INFO CK_MECHANISM_INFO; typedef struct CK_MECHANISM_INFO *CK_MECHANISM_INFO_PTR; @@ -526,6 +527,26 @@ struct CK_KEY_DERIVATION_STRING_DATA { CK_ULONG ulLen; }; +/* HKDF (PKCS#11 v3.0) salt source selectors */ +#define CKF_HKDF_SALT_NULL 0x00000001UL +#define CKF_HKDF_SALT_DATA 0x00000002UL +#define CKF_HKDF_SALT_KEY 0x00000004UL + +typedef struct CK_HKDF_PARAMS CK_HKDF_PARAMS; +typedef struct CK_HKDF_PARAMS *CK_HKDF_PARAMS_PTR; + +struct CK_HKDF_PARAMS { + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; +}; + /* Parameters for CKM_RSA_PKCS_PSS */ typedef struct CK_RSA_PKCS_PSS_PARAMS CK_RSA_PKCS_PSS_PARAMS; typedef struct CK_RSA_PKCS_PSS_PARAMS *CK_RSA_PKCS_PSS_PARAMS_PTR; diff --git a/libckteec/include/pkcs11_ta.h b/libckteec/include/pkcs11_ta.h index 063198b9..c90898af 100644 --- a/libckteec/include/pkcs11_ta.h +++ b/libckteec/include/pkcs11_ta.h @@ -1301,6 +1301,7 @@ enum pkcs11_mechanism_id { PKCS11_CKM_AES_CBC_ENCRYPT_DATA = 0x01105, PKCS11_CKM_AES_KEY_WRAP = 0x02109, PKCS11_CKM_AES_KEY_WRAP_PAD = 0x0210a, + PKCS11_CKM_HKDF_DERIVE = 0x0402a, /* * Vendor extensions below. * PKCS11 added IDs for operation not related to a CK mechanism ID @@ -1309,6 +1310,16 @@ enum pkcs11_mechanism_id { PKCS11_CKM_UNDEFINED_ID = PKCS11_UNDEFINED_ID, }; +/* + * Valid values for HKDF source selectors + * PKCS11_CKF_HKDF_SALT_ reflects CryptoKi client API IDs CKF_HKDF_SALT_. + */ +enum pkcs11_hkdf_salt_type { + PKCS11_CKF_HKDF_SALT_NULL = 0x00000001, + PKCS11_CKF_HKDF_SALT_DATA = 0x00000002, + PKCS11_CKF_HKDF_SALT_KEY = 0x00000004, +}; + /* * Valid values MG function identifiers * PKCS11_CKG_ reflects CryptoKi client API MG function IDs CKG_. diff --git a/libckteec/src/serialize_ck.c b/libckteec/src/serialize_ck.c index f8b5bf91..2bfa3332 100644 --- a/libckteec/src/serialize_ck.c +++ b/libckteec/src/serialize_ck.c @@ -532,6 +532,77 @@ static CK_RV serialize_mecha_ecdh1_derive_param(struct serializer *obj, params->ulPublicDataLen); } +/* + * HKDF parameter wire format (matches what the TA parses): + * u32 bExtract + * u32 bExpand + * u32 prfHashMechanism + * u32 ulSaltType + * u32 ulSaltLen + * bytes salt[ulSaltLen] + * u32 hSaltKey + * u32 ulInfoLen + * bytes info[ulInfoLen] + */ +static CK_RV serialize_mecha_hkdf_derive_param(struct serializer *obj, + CK_MECHANISM_PTR mecha) +{ + CK_HKDF_PARAMS_PTR params = mecha->pParameter; + CK_RV rv = CKR_GENERAL_ERROR; + size_t params_size = 0; + + if (params->ulSaltLen > UINT32_MAX || + params->ulInfoLen > UINT32_MAX || + params->ulSaltLen > + UINT32_MAX - params->ulInfoLen - 7 * sizeof(uint32_t)) + return CKR_ARGUMENTS_BAD; + + params_size = 7 * sizeof(uint32_t) + params->ulSaltLen + + params->ulInfoLen; + + rv = serialize_32b(obj, obj->type); + if (rv) + return rv; + + rv = serialize_32b(obj, params_size); + if (rv) + return rv; + + rv = serialize_32b(obj, params->bExtract); + if (rv) + return rv; + + rv = serialize_32b(obj, params->bExpand); + if (rv) + return rv; + + rv = serialize_32b(obj, params->prfHashMechanism); + if (rv) + return rv; + + rv = serialize_32b(obj, params->ulSaltType); + if (rv) + return rv; + + rv = serialize_32b(obj, params->ulSaltLen); + if (rv) + return rv; + + rv = serialize_buffer(obj, params->pSalt, params->ulSaltLen); + if (rv) + return rv; + + rv = serialize_32b(obj, params->hSaltKey); + if (rv) + return rv; + + rv = serialize_32b(obj, params->ulInfoLen); + if (rv) + return rv; + + return serialize_buffer(obj, params->pInfo, params->ulInfoLen); +} + static CK_RV serialize_mecha_aes_cbc_encrypt_data(struct serializer *obj, CK_MECHANISM_PTR mecha) { @@ -828,6 +899,9 @@ CK_RV serialize_ck_mecha_params(struct serializer *obj, case CKM_ECDH1_COFACTOR_DERIVE: return serialize_mecha_ecdh1_derive_param(obj, &mecha); + case CKM_HKDF_DERIVE: + return serialize_mecha_hkdf_derive_param(obj, &mecha); + case CKM_RSA_PKCS_PSS: case CKM_SHA1_RSA_PKCS_PSS: case CKM_SHA256_RSA_PKCS_PSS: