From f12ab67f832c277c51ae250e6e04ed783ab99d01 Mon Sep 17 00:00:00 2001 From: Finn Callies Date: Mon, 13 Jan 2025 11:56:11 +0100 Subject: [PATCH] Add support for CKM_IBM_BTC_DERIVE This adds support for the CKM_IBM_BTC_DERIVE IBM specific mechanism. Additionally this exploits the rpc_C_DeriveKey rework. --- common/constants.c | 1 + common/pkcs11x.h | 38 ++++++++++++ p11-kit/rpc-message.c | 137 ++++++++++++++++++++++++++++++++++++++++++ p11-kit/rpc-message.h | 20 ++++++ 4 files changed, 196 insertions(+) diff --git a/common/constants.c b/common/constants.c index 2cad5a64..98df2580 100644 --- a/common/constants.c +++ b/common/constants.c @@ -642,6 +642,7 @@ const p11_constant p11_constant_mechanisms[] = { CT (CKM_IBM_SHA3_512_HMAC, "ibm-sha3-512-hmac") CT (CKM_IBM_ECDSA_OTHER, "ibm-ecdsa-other") CT (CKM_IBM_ATTRIBUTEBOUND_WRAP, "ibm-attributebound-wrap") + CT (CKM_IBM_BTC_DERIVE, "ibm-btc-derive") { CKA_INVALID }, }; diff --git a/common/pkcs11x.h b/common/pkcs11x.h index c4826e0a..bd18cda4 100644 --- a/common/pkcs11x.h +++ b/common/pkcs11x.h @@ -230,12 +230,19 @@ typedef CK_ULONG CK_TRUST; #define CKM_IBM_SHA3_512_HMAC (CKM_VENDOR_DEFINED + 0x10028) #define CKM_IBM_ECDSA_OTHER (CKM_VENDOR_DEFINED + 0x10031) #define CKM_IBM_ATTRIBUTEBOUND_WRAP (CKM_VENDOR_DEFINED + 0x20004) +#define CKM_IBM_BTC_DERIVE (CKM_VENDOR_DEFINED + 0x70001) /* * If the caller is using the PKCS#11 GNU calling convention, then we cater * to that here. */ #ifdef CRYPTOKI_GNU +#define CK_BYTE_PTR unsigned char * + +#define childKeyIndex child_key_index +#define pChainCode p_chain_code +#define ulChainCodeLen ul_cahin_code_len + #define hSignVerifyKey h_sign_verify_key #endif @@ -248,6 +255,31 @@ struct ck_ibm_ecdsa_other { typedef struct ck_ibm_ecdsa_other CK_IBM_ECDSA_OTHER_PARAMS; +struct ck_ibm_btc_derive_params { + CK_ULONG type; + CK_ULONG childKeyIndex; + CK_BYTE_PTR pChainCode; + CK_ULONG ulChainCodeLen; + CK_ULONG version; +}; + +typedef struct ck_ibm_btc_derive_params CK_IBM_BTC_DERIVE_PARAMS; + +#define CK_IBM_BIP0032_HARDENED 0x80000000 // key index flag + +#define CK_IBM_BIP0032_PRV2PRV 1 +#define CK_IBM_BIP0032_PRV2PUB 2 +#define CK_IBM_BIP0032_PUB2PUB 3 +#define CK_IBM_BIP0032_MASTERK 4 +#define CK_IBM_SLIP0010_PRV2PRV 5 +#define CK_IBM_SLIP0010_PRV2PUB 6 +#define CK_IBM_SLIP0010_PUB2PUB 7 +#define CK_IBM_SLIP0010_MASTERK 8 + +#define CK_IBM_BTC_CHAINCODE_LENGTH 32 + +#define CK_IBM_BTC_DERIVE_PARAMS_VERSION_1 1 + struct ck_ibm_attributebound_wrap { CK_OBJECT_HANDLE hSignVerifyKey; }; @@ -255,6 +287,12 @@ struct ck_ibm_attributebound_wrap { typedef struct ck_ibm_attributebound_wrap CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS; #ifdef CRYPTOKI_GNU +#undef CK_BYTE_PTR + +#undef childKeyIndex +#undef pChainCode +#undef ulChainCodeLen + #undef hSignVerifyKey #endif diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c index 5f92db01..f64cfff5 100644 --- a/p11-kit/rpc-message.c +++ b/p11-kit/rpc-message.c @@ -1664,6 +1664,70 @@ p11_rpc_buffer_get_ibm_attrbound_wrap_mechanism_value (p11_buffer *buffer, return true; } +void +p11_rpc_buffer_add_ibm_btc_derive_mech_param_update (p11_buffer *buffer, + const void *value, + CK_ULONG value_length) +{ + CK_IBM_BTC_DERIVE_PARAMS params; + + if (value_length != sizeof (CK_IBM_BTC_DERIVE_PARAMS)) { + p11_buffer_fail (buffer); + return; + } + + memcpy (¶ms, value, value_length); + + if (params.pChainCode == NULL) { + p11_rpc_buffer_add_byte(buffer, 0); + p11_rpc_buffer_add_uint32(buffer, params.ulChainCodeLen); + } else { + p11_rpc_buffer_add_byte(buffer, 1); + p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pChainCode, params.ulChainCodeLen); + } +} + +bool +p11_rpc_buffer_get_ibm_btc_derive_mech_param_update (p11_buffer *buffer, + size_t *offset, + void *value, + CK_ULONG *value_length) +{ + const unsigned char *data; + unsigned char has_data; + size_t len; + uint32_t length; + + if (!p11_rpc_buffer_get_byte(buffer, offset, &has_data)) + return false; + + if (has_data == 0) { + if (!p11_rpc_buffer_get_uint32(buffer, offset, &length)) + return false; + len = length; + } else { + if (!p11_rpc_buffer_get_byte_array(buffer, offset, &data, &len)) + return false; + } + + if (value) { + CK_IBM_BTC_DERIVE_PARAMS *params = (CK_IBM_BTC_DERIVE_PARAMS *) value; + + if (params->pChainCode && params->ulChainCodeLen == len) { + memcpy(params->pChainCode, data, len); + params->ulChainCodeLen = len; + } else { + params->pChainCode = (void *) data; + params->ulChainCodeLen = len; + } + } + + if (value_length) + *value_length = sizeof (CK_IBM_BTC_DERIVE_PARAMS); + + return true; +} + void p11_rpc_buffer_add_ibm_ecdsa_other_mechanism_value (p11_buffer *buffer, const void *value, @@ -1711,6 +1775,77 @@ p11_rpc_buffer_get_ibm_ecdsa_other_mechanism_value (p11_buffer *buffer, return true; } +void +p11_rpc_buffer_add_ibm_btc_derive_mechanism_value (p11_buffer *buffer, + const void *value, + CK_ULONG value_length) +{ + CK_IBM_BTC_DERIVE_PARAMS params; + + if (value_length != sizeof (CK_IBM_BTC_DERIVE_PARAMS)) { + p11_buffer_fail (buffer); + return; + } + + memcpy (¶ms, value, value_length); + + if (params.type > UINT64_MAX) { + p11_buffer_fail (buffer); + return; + } + p11_rpc_buffer_add_uint64(buffer, params.type); + + if (params.childKeyIndex > UINT64_MAX) { + p11_buffer_fail (buffer); + return; + } + p11_rpc_buffer_add_uint64(buffer, params.childKeyIndex); + + p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pChainCode, params.ulChainCodeLen); + + if (params.version > UINT64_MAX) { + p11_buffer_fail (buffer); + return; + } + p11_rpc_buffer_add_uint64(buffer, params.version); +} + +bool +p11_rpc_buffer_get_ibm_btc_derive_mechanism_value (p11_buffer *buffer, + size_t *offset, + void *value, + CK_ULONG *value_length) +{ + uint64_t val1; + uint64_t val2; + size_t len; + const unsigned char *data; + uint64_t val3; + + if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val1) || + !p11_rpc_buffer_get_uint64 (buffer, offset, &val2) || + !p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len) || + !p11_rpc_buffer_get_uint64 (buffer, offset, &val3)) + return false; + + if (value) { + CK_IBM_BTC_DERIVE_PARAMS params; + + params.type = val1; + params.childKeyIndex = val2; + params.ulChainCodeLen = len; + params.pChainCode = (void *) data; + params.version = val3; + + memcpy (value, ¶ms, sizeof (CK_IBM_BTC_DERIVE_PARAMS)); + } + + if (value_length) + *value_length = sizeof (CK_IBM_BTC_DERIVE_PARAMS); + + return true; +} + void p11_rpc_buffer_add_aes_iv_mechanism_value (p11_buffer *buffer, const void *value, @@ -2008,10 +2143,12 @@ p11_rpc_buffer_get_dh_pkcs_derive_mechanism_value (p11_buffer *buffer, } static p11_rpc_mechanism_serializer p11_rpc_mech_param_update_serializers[] = { + { CKM_IBM_BTC_DERIVE, p11_rpc_buffer_add_ibm_btc_derive_mech_param_update, p11_rpc_buffer_get_ibm_btc_derive_mech_param_update }, }; static p11_rpc_mechanism_serializer p11_rpc_mechanism_serializers[] = { { CKM_IBM_ECDSA_OTHER, p11_rpc_buffer_add_ibm_ecdsa_other_mechanism_value, p11_rpc_buffer_get_ibm_ecdsa_other_mechanism_value }, + { CKM_IBM_BTC_DERIVE, p11_rpc_buffer_add_ibm_btc_derive_mechanism_value, p11_rpc_buffer_get_ibm_btc_derive_mechanism_value }, { CKM_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value }, { CKM_SHA1_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value }, { CKM_SHA224_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value }, diff --git a/p11-kit/rpc-message.h b/p11-kit/rpc-message.h index 6c91efb3..107f5ca9 100644 --- a/p11-kit/rpc-message.h +++ b/p11-kit/rpc-message.h @@ -517,6 +517,15 @@ bool p11_rpc_buffer_get_mechanism (p11_buffer *buffer, size_t *offset, CK_MECHANISM *mech); +void p11_rpc_buffer_add_ibm_btc_derive_mech_param_update (p11_buffer *buffer, + const void *value, + CK_ULONG value_length); + +bool p11_rpc_buffer_get_ibm_btc_derive_mech_param_update (p11_buffer *buffer, + size_t *offset, + void *value, + CK_ULONG *value_length); + void p11_rpc_buffer_add_mech_param_update (p11_buffer *buffer, const CK_MECHANISM *mech); @@ -574,6 +583,17 @@ void p11_rpc_buffer_add_ibm_ecdsa_other_mechanism_value CK_ULONG value_length); bool p11_rpc_buffer_get_ibm_ecdsa_other_mechanism_value + (p11_buffer *buffer, + size_t *offset, + void *value, + CK_ULONG *value_length); + +void p11_rpc_buffer_add_ibm_btc_derive_mechanism_value + (p11_buffer *buffer, + const void *value, + CK_ULONG value_length); + +bool p11_rpc_buffer_get_ibm_btc_derive_mechanism_value (p11_buffer *buffer, size_t *offset, void *value,