Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IBM specific mechanisms #669

Merged
merged 5 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions common/attrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,9 +779,13 @@ attribute_is_sensitive (const CK_ATTRIBUTE *attr,
X (CKA_IBM_PROTKEY_EXTRACTABLE)
X (CKA_IBM_PROTKEY_NEVER_EXTRACTABLE)
X (CKA_IBM_OPAQUE_PKEY)
X (CKA_IBM_DILITHIUM_MODE)
X (CKA_IBM_DILITHIUM_KEYFORM)
X (CKA_IBM_DILITHIUM_RHO)
X (CKA_IBM_DILITHIUM_T1)
X (CKA_IBM_KYBER_MODE)
X (CKA_IBM_KYBER_PK)
X (CKA_IBM_KYBER_KEYFORM)
case CKA_VALUE:
return (klass != CKO_CERTIFICATE &&
klass != CKO_X_CERTIFICATE_EXTENSION);
Expand Down
11 changes: 11 additions & 0 deletions common/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ const p11_constant p11_constant_types[] = {
CT (CKA_UNWRAP_TEMPLATE, "unwrap-template")
CT (CKA_ALLOWED_MECHANISMS, "allowed-mechanisms")
CT (CKA_IBM_OPAQUE, "ibm-opaque")
CT (CKA_IBM_OPAQUE_REENC, "ibm-opaque-reenc")
CT (CKA_IBM_OPAQUE_OLD, "ibm-opaque-old")
CT (CKA_IBM_KYBER_MODE, "ibm-kyber-mode")
CT (CKA_IBM_DILITHIUM_MODE, "ibm-dilithium-mode")
CT (CKA_IBM_RESTRICTABLE, "ibm-restrictable")
CT (CKA_IBM_NEVER_MODIFIABLE, "ibm-never-modifiable")
CT (CKA_IBM_RETAINKEY, "ibm-retainkey")
Expand All @@ -165,7 +169,11 @@ const p11_constant p11_constant_types[] = {
CT (CKA_IBM_DILITHIUM_S2, "ibm-dilithium-s2")
CT (CKA_IBM_DILITHIUM_T0, "ibm-dilithium-t0")
CT (CKA_IBM_DILITHIUM_T1, "ibm-dilithium-t1")
CT (CKA_IBM_KYBER_KEYFORM, "ibm-kyber-keyform")
CT (CKA_IBM_KYBER_PK, "ibm-kyber-pk")
CT (CKA_IBM_KYBER_SK, "ibm-kyber-sk")
CT (CKA_IBM_OPAQUE_PKEY, "ibm-opaque-pkey")
CT (CKA_IBM_CCA_AES_KEY_MODE, "ibm-cca-aes-key-mode")
CT (CKA_NSS_URL, "nss-url")
CT (CKA_NSS_EMAIL, "nss-email")
CT (CKA_NSS_SMIME_INFO, "nss-smime-constant")
Expand Down Expand Up @@ -632,11 +640,14 @@ const p11_constant p11_constant_mechanisms[] = {
CT (CKM_IBM_EC_X448, "ibm-ec-x448")
CT (CKM_IBM_ED448_SHA3, "ibm-ed448-sha3")
CT (CKM_IBM_DILITHIUM, "ibm-dilithium")
CT (CKM_IBM_KYBER, "ibm-kyber")
CT (CKM_IBM_SHA3_224_HMAC, "ibm-sha3-224-hmac")
CT (CKM_IBM_SHA3_256_HMAC, "ibm-sha3-256-hmac")
CT (CKM_IBM_SHA3_384_HMAC, "ibm-sha3-384-hmac")
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 },
};

Expand Down
108 changes: 108 additions & 0 deletions common/pkcs11x.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,19 @@ typedef CK_ULONG CK_TRUST;

#define CKK_IBM_PQC_DILITHIUM CKK_VENDOR_DEFINED + 0x10023

/* Secure key tokens store the secure key blob in attribute CKA_IBM_OPAQUE
in their key object. During an HSM master key change, the secure key blob
is being re-enciphered with the new master key. This re-enciphered secure
key blob is stored in attribute CKA_IBM_OPAQUE_REENC while the HSM master
key change operation is active.

When a HSM master key change operation is finalized, the secure key blob
enciphered with the old master key is backed up into attribute CKA_IBM_OPAQUE_OLD,
and the re-enciphered secure key blob from CKA_IBM_OPAQUE_REENC becomes
the current one in CKA_IBM_OPAQUE. */
#define CKA_IBM_OPAQUE (CKA_VENDOR_DEFINED + 1)
#define CKA_IBM_OPAQUE_REENC (CKA_VENDOR_DEFINED + 3)
#define CKA_IBM_OPAQUE_OLD (CKA_VENDOR_DEFINED + 4)
#define CKA_IBM_RESTRICTABLE (CKA_VENDOR_DEFINED + 0x10001)
#define CKA_IBM_NEVER_MODIFIABLE (CKA_VENDOR_DEFINED + 0x10002)
#define CKA_IBM_RETAINKEY (CKA_VENDOR_DEFINED + 0x10003)
Expand All @@ -208,7 +220,13 @@ typedef CK_ULONG CK_TRUST;
#define CKA_IBM_DILITHIUM_S2 (CKA_VENDOR_DEFINED + 0xd0006)
#define CKA_IBM_DILITHIUM_T0 (CKA_VENDOR_DEFINED + 0xd0007)
#define CKA_IBM_DILITHIUM_T1 (CKA_VENDOR_DEFINED + 0xd0008)
#define CKA_IBM_DILITHIUM_MODE (CKA_VENDOR_DEFINED + 0x00010)
#define CKA_IBM_CCA_AES_KEY_MODE (CKA_VENDOR_DEFINED + 0xd0101)
#define CKA_IBM_OPAQUE_PKEY (CKA_VENDOR_DEFINED + 0xd0100)
#define CKA_IBM_KYBER_MODE (CKA_VENDOR_DEFINED + 0x0000E)
#define CKA_IBM_KYBER_KEYFORM (CKA_VENDOR_DEFINED + 0xd0009)
#define CKA_IBM_KYBER_PK (CKA_VENDOR_DEFINED + 0xd000A)
#define CKA_IBM_KYBER_SK (CKA_VENDOR_DEFINED + 0xd000B)

#define CKM_IBM_SHA3_224 (CKM_VENDOR_DEFINED + 0x10001)
#define CKM_IBM_SHA3_256 (CKM_VENDOR_DEFINED + 0x10002)
Expand All @@ -220,27 +238,117 @@ typedef CK_ULONG CK_TRUST;
#define CKM_IBM_EC_X448 (CKM_VENDOR_DEFINED + 0x1001e)
#define CKM_IBM_ED448_SHA3 (CKM_VENDOR_DEFINED + 0x1001f)
#define CKM_IBM_DILITHIUM (CKM_VENDOR_DEFINED + 0x10023)
#define CKM_IBM_KYBER (CKM_VENDOR_DEFINED + 0x10024)
#define CKM_IBM_SHA3_224_HMAC (CKM_VENDOR_DEFINED + 0x10025)
#define CKM_IBM_SHA3_256_HMAC (CKM_VENDOR_DEFINED + 0x10026)
#define CKM_IBM_SHA3_384_HMAC (CKM_VENDOR_DEFINED + 0x10027)
#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 CK_BYTE unsigned char

#define childKeyIndex child_key_index
#define pChainCode p_chain_code
#define ulChainCodeLen ul_cahin_code_len

#define ulVersion ul_version
#define bPrepend b_prepend
#define pCipher p_cipher
#define ulCipherLen ul_cipher_len
#define pSharedData p_shared_data
#define hSecret h_secret

#define hSignVerifyKey h_sign_verify_key
#endif

#define CKM_IBM_ECSDSA_RAND 3
#define CKM_IBM_ECSDSA_COMPR_MULTI 5

struct ck_ibm_ecdsa_other {
CK_ULONG submechanism;
};

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

#define CK_IBM_KYBER_KEYFORM_ROUND2_768 1
#define CK_IBM_KYBER_KEYFORM_ROUND2_1024 2

#define CK_IBM_KYBER_KEM_VERSION 0

typedef CK_ULONG CK_IBM_KYBER_KDF_TYPE;
typedef CK_ULONG CK_IBM_KYBER_KEM_MODE;

#define CK_IBM_KYBER_KEM_ENCAPSULATE 1
#define CK_IBM_KYBER_KEM_DECAPSULATE 2

struct ck_ibm_kyber_params {
CK_ULONG ulVersion;
CK_IBM_KYBER_KEM_MODE mode;
CK_IBM_KYBER_KDF_TYPE kdf;
CK_BBOOL bPrepend;
CK_BYTE *pCipher;
CK_ULONG ulCipherLen;
CK_BYTE *pSharedData;
CK_ULONG ulSharedDataLen;
CK_OBJECT_HANDLE hSecret;
};

typedef struct ck_ibm_kyber_params CK_IBM_KYBER_PARAMS;

struct ck_ibm_attributebound_wrap {
CK_OBJECT_HANDLE hSignVerifyKey;
};

typedef struct ck_ibm_attributebound_wrap CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS;

#ifdef CRYPTOKI_GNU
#undef CK_BYTE_PTR
#undef CK_BYTE

#undef childKeyIndex
#undef pChainCode
#undef ulChainCodeLen

#undef ulVersion
#undef bPrepend
#undef pCipher
#undef ulCipherLen
#undef pSharedData
#undef hSecret

#undef hSignVerifyKey
#endif

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ P11KIT_AGE=4
# ------------------------------------------------------------------------------
# p11-kit RPC protocol versions
P11KIT_RPC_MIN=0
P11KIT_RPC_MAX=1
P11KIT_RPC_MAX=2

# ------------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,5 @@ option('rpc_min', type : 'integer',
description : 'Minimum RPC protocol version we support')

option('rpc_max', type : 'integer',
min : 0, max : 1, value : 1,
min : 0, max : 2, value : 2,
description : 'Maximum RPC protocol version we support')
124 changes: 117 additions & 7 deletions p11-kit/rpc-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,55 @@ proto_write_mechanism (p11_rpc_message *msg,
return p11_buffer_failed (msg->output) ? CKR_HOST_MEMORY : CKR_OK;
}

static CK_RV
proto_read_error (p11_rpc_message *msg, CK_RV *error)
{
if (!p11_rpc_message_read_ulong(msg, error))
return PARSE_ERROR;

return CKR_OK;
}

static CK_RV
proto_read_mech_param_update (p11_rpc_message *msg,
CK_MECHANISM_PTR *mech)
{
size_t offset;
CK_MECHANISM temp;

assert (msg != NULL);
assert (mech != NULL);
assert (msg->input != NULL);

/* Make sure this is in the right order */
assert (!msg->signature || p11_rpc_message_verify_part (msg, "P"));

/* Check the length needed to store the parameter */
memset (&temp, 0, sizeof (temp));
temp.mechanism = (*mech)->mechanism;
offset = msg->parsed;
if (!p11_rpc_buffer_get_mech_param_update (msg->input, &offset, &temp)) {
msg->parsed = offset;
return PARSE_ERROR;
}

/* The mechanism doesn't require parameter */
if (temp.ulParameterLen == 0) {
msg->parsed = offset;
return CKR_OK;
}

/* Actually retrieve the parameter */
if ((*mech)->ulParameterLen != temp.ulParameterLen)
return CKR_MECHANISM_PARAM_INVALID;
if (!p11_rpc_buffer_get_mech_param_update (msg->input, &msg->parsed, *mech))
return PARSE_ERROR;

assert (msg->parsed == offset);

return CKR_OK;
}

static CK_RV
proto_read_info (p11_rpc_message *msg,
CK_INFO_PTR info)
Expand Down Expand Up @@ -652,6 +701,16 @@ proto_read_sesssion_info (p11_rpc_message *msg,
if (_ret == CKR_OK && !p11_rpc_message_read_ulong (&_msg, val)) \
_ret = PARSE_ERROR;

#define OUT_MECH_PARAM_UPDATE(mech) \
if (_ret != CKR_OK) goto _cleanup; \
_ret = proto_read_mech_param_update (&_msg, &mech); \
if (_ret != CKR_OK) goto _cleanup;

#define OUT_ERROR(err) \
if (_ret != CKR_OK) goto _cleanup; \
_ret = proto_read_error (&_msg, &err);


#define OUT_BYTE_ARRAY(arr, len) \
if (len == NULL) \
_ret = CKR_ARGUMENTS_BAD; \
Expand Down Expand Up @@ -706,6 +765,17 @@ proto_read_sesssion_info (p11_rpc_message *msg,
if (_ret == CKR_OK) \
_ret = proto_read_mechanism_info (&_msg, info);

// EARLY_EXIT_ON_FAIL
#define PREP_EEOF \
CK_RV err;

#define PROCESS_CALL_NO_CHECK \
_ret = call_run (_mod, &_msg);

#define CHECK_EEOF \
if(err != CKR_OK) \
_ret = err;


/* -------------------------------------------------------------------
* INITIALIZATION and 'GLOBAL' CALLS
Expand Down Expand Up @@ -1874,13 +1944,13 @@ rpc_C_UnwrapKey (CK_X_FUNCTION_LIST *self,
}

static CK_RV
rpc_C_DeriveKey (CK_X_FUNCTION_LIST *self,
CK_SESSION_HANDLE session,
CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE base_key,
CK_ATTRIBUTE_PTR template,
CK_ULONG count,
CK_OBJECT_HANDLE_PTR key)
C_DeriveKey1 (CK_X_FUNCTION_LIST *self,
CK_SESSION_HANDLE session,
CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE base_key,
CK_ATTRIBUTE_PTR template,
CK_ULONG count,
CK_OBJECT_HANDLE_PTR key)
{
BEGIN_CALL_OR (C_DeriveKey, self, CKR_SESSION_HANDLE_INVALID);
IN_ULONG (session);
Expand All @@ -1892,6 +1962,46 @@ rpc_C_DeriveKey (CK_X_FUNCTION_LIST *self,
END_CALL;
}

static CK_RV
C_DeriveKey2 (CK_X_FUNCTION_LIST *self,
CK_SESSION_HANDLE session,
CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE base_key,
CK_ATTRIBUTE_PTR template,
CK_ULONG count,
CK_OBJECT_HANDLE_PTR key)
{
PREP_EEOF;
BEGIN_CALL_OR (C_DeriveKey2, self, CKR_SESSION_HANDLE_INVALID);
IN_ULONG (session);
IN_MECHANISM (mechanism);
IN_ULONG (base_key);
IN_ATTRIBUTE_ARRAY (template, count);
PROCESS_CALL_NO_CHECK;
OUT_ERROR (err);
OUT_MECH_PARAM_UPDATE (mechanism);
CHECK_EEOF;
OUT_ULONG (key);
END_CALL;
}

static CK_RV
rpc_C_DeriveKey (CK_X_FUNCTION_LIST *self,
CK_SESSION_HANDLE session,
CK_MECHANISM_PTR mechanism,
CK_OBJECT_HANDLE base_key,
CK_ATTRIBUTE_PTR template,
CK_ULONG count,
CK_OBJECT_HANDLE_PTR key)
{
uint8_t version = RPC_VERSION;

if (version <= 1)
return C_DeriveKey1 (self, session, mechanism, base_key, template, count, key);
else
return C_DeriveKey2 (self, session, mechanism, base_key, template, count, key);
}

static CK_RV
rpc_C_SeedRandom (CK_X_FUNCTION_LIST *self,
CK_SESSION_HANDLE session,
Expand Down
Loading
Loading