Compare commits

...

3 Commits
c8 ... a8

52 changed files with 2771 additions and 19606 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/opencryptoki-3.19.0.tar.gz
SOURCES/opencryptoki-3.21.0.tar.gz

View File

@ -1 +1 @@
39acf63d03978b2827340394fe6f732a6f0c0526 SOURCES/opencryptoki-3.19.0.tar.gz
4a0f2ed8f965a948057ab833f1fafabf58929d3f SOURCES/opencryptoki-3.21.0.tar.gz

View File

@ -1,809 +0,0 @@
From 27088567f4375578e39c5b75b4ceae9dff231962 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 11 Oct 2022 13:46:08 +0200
Subject: [PATCH 01/34] EP11: Unify key-pair generation functions
Unify the DSA and DH key-pair generation functions with those for
RSA, EC and Dilithium. Make sure that the attribute handling is done
in the same sequence for all those functions.
Also remove obsolete parameters for all the key-pair generation functions.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 494 ++++++++++++++-----------------------
1 file changed, 187 insertions(+), 307 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index a6a33719..5d7c5607 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -5374,15 +5374,10 @@ error:
-static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
- SESSION * sess,
+static CK_RV dh_generate_keypair(STDLL_TokData_t *tokdata,
+ SESSION *sess,
CK_MECHANISM_PTR pMechanism,
- TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_SESSION_HANDLE h)
+ TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
{
CK_RV rc;
CK_BYTE publblob[MAX_BLOBSIZE];
@@ -5399,9 +5394,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
CK_ULONG dh_ulPublicKeyAttributeCount = 0;
CK_ATTRIBUTE_PTR dh_pPrivateKeyTemplate = NULL;
CK_ULONG dh_ulPrivateKeyAttributeCount = 0;
- size_t p_len = 0, g_len = 0;
- int new_public_attr;
- CK_ULONG i;
CK_ULONG data_len;
CK_ULONG field_len;
CK_BYTE *data;
@@ -5421,149 +5413,122 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
unsigned char *pg;
} dh_pgs;
- UNUSED(h);
-
memset(&dh_pgs, 0, sizeof(dh_pgs));
memset(publblob, 0, sizeof(publblob));
memset(privblob, 0, sizeof(privblob));
- /* card does not want CKA_PRIME/CKA_BASE in template but in dh_pgs */
- pPublicKeyTemplate_new =
- (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) *
- ulPublicKeyAttributeCount);
- if (!pPublicKeyTemplate_new) {
- TRACE_ERROR("%s Memory allocation failed\n", __func__);
- return CKR_HOST_MEMORY;
- }
- memset(pPublicKeyTemplate_new, 0,
- sizeof(CK_ATTRIBUTE) * ulPublicKeyAttributeCount);
-
- for (i = 0, new_public_attr = 0; i < ulPublicKeyAttributeCount; i++) {
- /* filter out CKA_PRIME/CKA_BASE,
- * but remember where they can be found
- */
- switch (pPublicKeyTemplate[i].type) {
- case CKA_PRIME:
- prime_attr = &(pPublicKeyTemplate[i]);
- p_len = pPublicKeyTemplate[i].ulValueLen;
- break;
- case CKA_BASE:
- base_attr = &(pPublicKeyTemplate[i]);
- g_len = pPublicKeyTemplate[i].ulValueLen;
- break;
- default:
- /* copy all other attributes */
- memcpy(&pPublicKeyTemplate_new[new_public_attr],
- &(pPublicKeyTemplate[i]), sizeof(CK_ATTRIBUTE));
- new_public_attr++;
- }
+ rc = build_ep11_attrs(tokdata, publ_tmpl, &dh_pPublicKeyTemplate,
+ &dh_ulPublicKeyAttributeCount,
+ CKK_DH, CKO_PUBLIC_KEY, -1, pMechanism);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
+ goto dh_generate_keypair_end;
}
- if (prime_attr == NULL || base_attr == NULL) {
- TRACE_ERROR("%s Incomplete template prime_attr=%p base_attr=%p\n",
- __func__, (void *)prime_attr, (void *)base_attr);
- rc = CKR_TEMPLATE_INCOMPLETE;
+ rc = build_ep11_attrs(tokdata, priv_tmpl, &dh_pPrivateKeyTemplate,
+ &dh_ulPrivateKeyAttributeCount,
+ CKK_DH, CKO_PRIVATE_KEY, -1, pMechanism);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
goto dh_generate_keypair_end;
}
- /* copy CKA_PRIME/CKA_BASE to private template */
- rc = build_attribute(CKA_PRIME, prime_attr->pValue,
- prime_attr->ulValueLen, &attr);
+ rc = check_key_attributes(tokdata, CKK_DH, CKO_PUBLIC_KEY,
+ dh_pPublicKeyTemplate,
+ dh_ulPublicKeyAttributeCount,
+ &new_publ_attrs, &new_publ_attrs_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s DH check public key attributes failed with "
+ "rc=0x%lx\n", __func__, rc);
goto dh_generate_keypair_end;
}
- rc = template_update_attribute(priv_tmpl, attr);
+
+ rc = check_key_attributes(tokdata, CKK_DH, CKO_PRIVATE_KEY,
+ dh_pPrivateKeyTemplate,
+ dh_ulPrivateKeyAttributeCount,
+ &new_priv_attrs, &new_priv_attrs_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s DH check private key attributes failed with "
+ "rc=0x%lx\n", __func__, rc);
goto dh_generate_keypair_end;
}
- rc = build_attribute(CKA_BASE, base_attr->pValue,
- base_attr->ulValueLen, &attr);
+
+ /* card does not want CKA_PRIME/CKA_BASE in template but in dh_pgs */
+ rc = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME,
+ &prime_attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s DH No CKA_PRIME attribute found\n", __func__);
goto dh_generate_keypair_end;
}
- rc = template_update_attribute(priv_tmpl, attr);
+
+ rc = template_attribute_get_non_empty(publ_tmpl, CKA_BASE,
+ &base_attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s DH No CKA_BASE attribute found\n", __func__);
goto dh_generate_keypair_end;
}
- /* copy CKA_PRIME/CKA_BASE values */
- dh_pgs.pg = malloc(p_len * 2);
+ dh_pgs.pg = malloc(prime_attr->ulValueLen * 2);
if (!dh_pgs.pg) {
TRACE_ERROR("%s Memory allocation failed\n", __func__);
rc = CKR_HOST_MEMORY;
goto dh_generate_keypair_end;
}
- memset(dh_pgs.pg, 0, p_len * 2);
- memcpy(dh_pgs.pg, prime_attr->pValue, p_len); /* copy CKA_PRIME value */
+
+ memset(dh_pgs.pg, 0, prime_attr->ulValueLen * 2);
+ /* copy CKA_PRIME value */
+ memcpy(dh_pgs.pg, prime_attr->pValue, prime_attr->ulValueLen);
/* copy CKA_BASE value, it must have leading zeros
* if it is shorter than CKA_PRIME
*/
- memcpy(dh_pgs.pg + p_len + (p_len - g_len), base_attr->pValue, g_len);
- dh_pgs.pg_bytes = p_len * 2;
+ memcpy(dh_pgs.pg + prime_attr->ulValueLen +
+ (prime_attr->ulValueLen - base_attr->ulValueLen),
+ base_attr->pValue, base_attr->ulValueLen);
+ dh_pgs.pg_bytes = prime_attr->ulValueLen * 2;
#ifdef DEBUG
TRACE_DEBUG("%s P:\n", __func__);
- TRACE_DEBUG_DUMP(" ", &dh_pgs.pg[0], p_len);
+ TRACE_DEBUG_DUMP(" ", &dh_pgs.pg[0], prime_attr->ulValueLen);
TRACE_DEBUG("%s G:\n", __func__);
- TRACE_DEBUG_DUMP(" ", &dh_pgs.pg[p_len], p_len);
+ TRACE_DEBUG_DUMP(" ", &dh_pgs.pg[prime_attr->ulValueLen],
+ prime_attr->ulValueLen);
#endif
- /* add special attribute, do not add it to ock's pPublicKeyTemplate */
- CK_ATTRIBUTE pgs[] = { {CKA_IBM_STRUCT_PARAMS, (CK_VOID_PTR) dh_pgs.pg,
- dh_pgs.pg_bytes}
- };
- memcpy(&(pPublicKeyTemplate_new[new_public_attr]),
- &(pgs[0]), sizeof(CK_ATTRIBUTE));
-
- rc = check_key_attributes(tokdata, CKK_DH, CKO_PUBLIC_KEY,
- pPublicKeyTemplate_new, new_public_attr + 1,
- &dh_pPublicKeyTemplate,
- &dh_ulPublicKeyAttributeCount, -1);
+ rc = add_to_attribute_array(&new_publ_attrs, &new_publ_attrs_len,
+ CKA_IBM_STRUCT_PARAMS, dh_pgs.pg,
+ dh_pgs.pg_bytes);
if (rc != CKR_OK) {
- TRACE_ERROR("%s DH check public key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
+ __func__, rc);
goto dh_generate_keypair_end;
}
- rc = check_key_attributes(tokdata, CKK_DH, CKO_PRIVATE_KEY,
- pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
- &dh_pPrivateKeyTemplate,
- &dh_ulPrivateKeyAttributeCount, -1);
+ /* copy CKA_PRIME/CKA_BASE to private template */
+ rc = build_attribute(CKA_PRIME, prime_attr->pValue,
+ prime_attr->ulValueLen, &attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s DH check private key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
goto dh_generate_keypair_end;
}
-
- rc = build_ep11_attrs(tokdata, publ_tmpl,
- &new_publ_attrs, &new_publ_attrs_len,
- CKK_DH, CKO_PUBLIC_KEY, -1, pMechanism);
+ rc = template_update_attribute(priv_tmpl, attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
goto dh_generate_keypair_end;
}
- rc = add_to_attribute_array(&new_publ_attrs, &new_publ_attrs_len,
- CKA_IBM_STRUCT_PARAMS, (CK_VOID_PTR) dh_pgs.pg,
- dh_pgs.pg_bytes);
+ rc = build_attribute(CKA_BASE, base_attr->pValue,
+ base_attr->ulValueLen, &attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
goto dh_generate_keypair_end;
}
-
- rc = build_ep11_attrs(tokdata, priv_tmpl,
- &new_priv_attrs, &new_priv_attrs_len,
- CKK_DH, CKO_PRIVATE_KEY, -1, pMechanism);
+ rc = template_update_attribute(priv_tmpl, attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
goto dh_generate_keypair_end;
}
@@ -5573,10 +5538,10 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
new_priv_attrs, new_priv_attrs_len);
ep11_get_pin_blob(ep11_session,
- (ep11_is_session_object
- (pPublicKeyTemplate, ulPublicKeyAttributeCount)
- || ep11_is_session_object(pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount)),
+ (ep11_is_session_object(new_publ_attrs,
+ new_publ_attrs_len) ||
+ ep11_is_session_object(new_priv_attrs,
+ new_priv_attrs_len)),
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
@@ -5595,7 +5560,7 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
}
TRACE_INFO("%s rc=0x%lx plen=%zd publblobsize=0x%zx privblobsize=0x%zx\n",
- __func__, rc, p_len, publblobsize, privblobsize);
+ __func__, rc, prime_attr->ulValueLen, publblobsize, privblobsize);
if (check_expected_mkvp(tokdata, privblob, privblobsize) != CKR_OK) {
TRACE_ERROR("%s\n", ock_err(ERR_DEVICE_ERROR));
@@ -5700,15 +5665,10 @@ dh_generate_keypair_end:
return rc;
}
-static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
- SESSION * sess,
+static CK_RV dsa_generate_keypair(STDLL_TokData_t *tokdata,
+ SESSION *sess,
CK_MECHANISM_PTR pMechanism,
- TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_SESSION_HANDLE h)
+ TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
{
CK_RV rc;
CK_BYTE publblob[MAX_BLOBSIZE];
@@ -5721,9 +5681,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
CK_ATTRIBUTE *opaque_attr = NULL;
CK_ATTRIBUTE *value_attr = NULL;
CK_ATTRIBUTE *attr = NULL;
- size_t p_len = 0, q_len = 0, g_len = 0;
- int new_public_attr;
- CK_ULONG i;
CK_ATTRIBUTE *pPublicKeyTemplate_new = NULL;
CK_BYTE *key;
CK_BYTE *data, *oid, *parm;
@@ -5737,8 +5694,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
CK_ATTRIBUTE *new_publ_attrs = NULL, *new_priv_attrs = NULL;
CK_ULONG new_publ_attrs_len = 0, new_priv_attrs_len = 0;
- CK_ATTRIBUTE *new_publ_attrs2 = NULL, *new_priv_attrs2 = NULL;
- CK_ULONG new_publ_attrs2_len = 0, new_priv_attrs2_len = 0;
/* ep11 accepts CKA_PRIME,CKA_SUBPRIME,CKA_BASE only in this format */
struct {
@@ -5746,95 +5701,68 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
unsigned char *pqg;
} dsa_pqgs;
- UNUSED(h);
-
memset(&dsa_pqgs, 0, sizeof(dsa_pqgs));
memset(publblob, 0, sizeof(publblob));
memset(privblob, 0, sizeof(privblob));
- /* card does not want CKA_PRIME/CKA_BASE/CKA_SUBPRIME
- * in template but in dsa_pqgs
- */
- pPublicKeyTemplate_new =
- (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) *
- ulPublicKeyAttributeCount);
- if (!pPublicKeyTemplate_new) {
- TRACE_ERROR("%s Memory allocation failed\n", __func__);
- return CKR_HOST_MEMORY;
- }
- memset(pPublicKeyTemplate_new, 0,
- sizeof(CK_ATTRIBUTE) * ulPublicKeyAttributeCount);
-
- for (i = 0, new_public_attr = 0; i < ulPublicKeyAttributeCount; i++) {
- switch (pPublicKeyTemplate[i].type) {
- case CKA_PRIME:
- prime_attr = &(pPublicKeyTemplate[i]);
- p_len = pPublicKeyTemplate[i].ulValueLen;
- break;
- case CKA_SUBPRIME:
- sub_prime_attr = &(pPublicKeyTemplate[i]);
- q_len = pPublicKeyTemplate[i].ulValueLen;
- break;
- case CKA_BASE:
- base_attr = &(pPublicKeyTemplate[i]);
- g_len = pPublicKeyTemplate[i].ulValueLen;
- break;
- default:
- /* copy all other attributes */
- memcpy(&pPublicKeyTemplate_new[new_public_attr],
- &(pPublicKeyTemplate[i]), sizeof(CK_ATTRIBUTE));
- new_public_attr++;
- }
- }
-
- if (prime_attr == NULL || sub_prime_attr == NULL || base_attr == NULL) {
- rc = CKR_TEMPLATE_INCOMPLETE;
+ rc = build_ep11_attrs(tokdata, publ_tmpl, &dsa_pPublicKeyTemplate,
+ &dsa_ulPublicKeyAttributeCount,
+ CKK_DSA, CKO_PUBLIC_KEY, -1, pMechanism);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
goto dsa_generate_keypair_end;
}
- /* copy CKA_PRIME/CKA_BASE/CKA_SUBPRIME to private template */
- rc = build_attribute(CKA_PRIME, prime_attr->pValue,
- prime_attr->ulValueLen, &attr);
+ rc = build_ep11_attrs(tokdata, priv_tmpl, &dsa_pPrivateKeyTemplate,
+ &dsa_ulPrivateKeyAttributeCount,
+ CKK_DSA, CKO_PRIVATE_KEY, -1, pMechanism);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
goto dsa_generate_keypair_end;
}
- rc = template_update_attribute(priv_tmpl, attr);
+ rc = check_key_attributes(tokdata, CKK_DSA, CKO_PUBLIC_KEY,
+ dsa_pPublicKeyTemplate,
+ dsa_ulPublicKeyAttributeCount,
+ &new_publ_attrs, &new_publ_attrs_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s DSA check public key attributes failed with "
+ "rc=0x%lx\n", __func__, rc);
goto dsa_generate_keypair_end;
}
- rc = build_attribute(CKA_BASE, base_attr->pValue,
- base_attr->ulValueLen, &attr);
+ rc = check_key_attributes(tokdata, CKK_DSA, CKO_PRIVATE_KEY,
+ dsa_pPrivateKeyTemplate,
+ dsa_ulPrivateKeyAttributeCount,
+ &new_priv_attrs, &new_priv_attrs_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s DSA check private key attributes failed with "
+ "rc=0x%lx\n", __func__, rc);
goto dsa_generate_keypair_end;
}
- rc = template_update_attribute(priv_tmpl, attr);
+ /*
+ * card does not want CKA_PRIME/CKA_BASE/CKA_SUBPRIME in template but in
+ * dsa_pqgs
+ */
+ rc = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME,
+ &prime_attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s DSA No CKA_PRIME attribute found\n", __func__);
goto dsa_generate_keypair_end;
}
- rc = build_attribute(CKA_SUBPRIME, sub_prime_attr->pValue,
- sub_prime_attr->ulValueLen, &attr);
+ rc = template_attribute_get_non_empty(publ_tmpl, CKA_SUBPRIME,
+ &sub_prime_attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s DSA No CKA_SUBPRIME attribute found\n", __func__);
goto dsa_generate_keypair_end;
}
- rc = template_update_attribute(priv_tmpl, attr);
+ rc = template_attribute_get_non_empty(publ_tmpl, CKA_BASE,
+ &base_attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s DSA No CKA_BASE attribute found\n", __func__);
goto dsa_generate_keypair_end;
}
@@ -5842,95 +5770,102 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
* then they are extented by leading zeros till they have
* the size of CKA_PRIME
*/
- dsa_pqgs.pqg = malloc(p_len * 3);
+ dsa_pqgs.pqg = malloc(prime_attr->ulValueLen * 3);
if (!dsa_pqgs.pqg) {
TRACE_ERROR("%s Memory allocation failed\n", __func__);
rc = CKR_HOST_MEMORY;
goto dsa_generate_keypair_end;
}
- memset(dsa_pqgs.pqg, 0, p_len * 3);
- memcpy(dsa_pqgs.pqg, prime_attr->pValue, p_len);
- memcpy(dsa_pqgs.pqg + p_len + (p_len - q_len),
- sub_prime_attr->pValue, q_len);
- memcpy(dsa_pqgs.pqg + 2 * p_len + (p_len - g_len),
- base_attr->pValue, g_len);
- dsa_pqgs.pqg_bytes = p_len * 3;
+
+ memset(dsa_pqgs.pqg, 0, prime_attr->ulValueLen * 3);
+ memcpy(dsa_pqgs.pqg, prime_attr->pValue, prime_attr->ulValueLen);
+ memcpy(dsa_pqgs.pqg + prime_attr->ulValueLen +
+ (prime_attr->ulValueLen - sub_prime_attr->ulValueLen),
+ sub_prime_attr->pValue, sub_prime_attr->ulValueLen);
+ memcpy(dsa_pqgs.pqg + 2 * prime_attr->ulValueLen +
+ (prime_attr->ulValueLen - base_attr->ulValueLen),
+ base_attr->pValue, base_attr->ulValueLen);
+ dsa_pqgs.pqg_bytes = prime_attr->ulValueLen * 3;
#ifdef DEBUG
TRACE_DEBUG("%s P:\n", __func__);
- TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[0], p_len);
+ TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[0], prime_attr->ulValueLen);
TRACE_DEBUG("%s Q:\n", __func__);
- TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[p_len], p_len);
+ TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[prime_attr->ulValueLen],
+ prime_attr->ulValueLen);
TRACE_DEBUG("%s G:\n", __func__);
- TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[2 * p_len], p_len);
+ TRACE_DEBUG_DUMP(" ", &dsa_pqgs.pqg[2 * prime_attr->ulValueLen],
+ prime_attr->ulValueLen);
#endif
- CK_ATTRIBUTE pqgs[] = { {CKA_IBM_STRUCT_PARAMS,
- (CK_VOID_PTR) dsa_pqgs.pqg, dsa_pqgs.pqg_bytes}
- };
-
- /* add special attribute, do not add it to ock's pPublicKeyTemplate */
- memcpy(&(pPublicKeyTemplate_new[new_public_attr]),
- &(pqgs[0]), sizeof(CK_ATTRIBUTE));
-
- rc = build_ep11_attrs(tokdata, publ_tmpl,
- &new_publ_attrs, &new_publ_attrs_len,
- CKK_DSA, CKO_PUBLIC_KEY, -1, pMechanism);
+ rc = add_to_attribute_array(&new_publ_attrs, &new_publ_attrs_len,
+ CKA_IBM_STRUCT_PARAMS, dsa_pqgs.pqg,
+ dsa_pqgs.pqg_bytes);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
+ __func__, rc);
goto dsa_generate_keypair_end;
}
- rc = check_key_attributes(tokdata, CKK_DSA, CKO_PUBLIC_KEY,
- new_publ_attrs, new_publ_attrs_len,
- &new_publ_attrs2, &new_publ_attrs2_len, -1);
+ /* copy CKA_PRIME/CKA_BASE/CKA_SUBPRIME to private template */
+ rc = build_attribute(CKA_PRIME, prime_attr->pValue,
+ prime_attr->ulValueLen, &attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s DSA check public key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
goto dsa_generate_keypair_end;
}
-
- rc = add_to_attribute_array(&new_publ_attrs2, &new_publ_attrs2_len,
- CKA_IBM_STRUCT_PARAMS, (CK_VOID_PTR) dsa_pqgs.pqg,
- dsa_pqgs.pqg_bytes);
+ rc = template_update_attribute(priv_tmpl, attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
goto dsa_generate_keypair_end;
}
- rc = build_ep11_attrs(tokdata, priv_tmpl,
- &new_priv_attrs, &new_priv_attrs_len,
- CKK_DSA, CKO_PRIVATE_KEY, -1, pMechanism);
+ rc = build_attribute(CKA_SUBPRIME, sub_prime_attr->pValue,
+ sub_prime_attr->ulValueLen, &attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s build_ep11_attrs failed with rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ goto dsa_generate_keypair_end;
+ }
+ rc = template_update_attribute(priv_tmpl, attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
goto dsa_generate_keypair_end;
}
- rc = check_key_attributes(tokdata, CKK_DSA, CKO_PRIVATE_KEY,
- new_priv_attrs, new_priv_attrs_len,
- &new_priv_attrs2, &new_priv_attrs2_len, -1);
+ rc = build_attribute(CKA_BASE, base_attr->pValue,
+ base_attr->ulValueLen, &attr);
if (rc != CKR_OK) {
- TRACE_ERROR("%s DSA check private key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
+ goto dsa_generate_keypair_end;
+ }
+ rc = template_update_attribute(priv_tmpl, attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
goto dsa_generate_keypair_end;
}
trace_attributes(__func__, "DSA public key attributes:",
- new_publ_attrs2, new_publ_attrs2_len);
+ new_publ_attrs, new_publ_attrs_len);
trace_attributes(__func__, "DSA private key attributes:",
- new_priv_attrs2, new_priv_attrs2_len);
+ new_priv_attrs, new_priv_attrs_len);
ep11_get_pin_blob(ep11_session,
- (ep11_is_session_object
- (pPublicKeyTemplate, ulPublicKeyAttributeCount)
- || ep11_is_session_object(pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount)),
+ (ep11_is_session_object(new_publ_attrs,
+ new_publ_attrs_len) ||
+ ep11_is_session_object(new_priv_attrs,
+ new_priv_attrs_len)),
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
rc = dll_m_GenerateKeyPair(pMechanism,
- new_publ_attrs2, new_publ_attrs2_len,
- new_priv_attrs2, new_priv_attrs2_len,
+ new_publ_attrs, new_publ_attrs_len,
+ new_priv_attrs, new_priv_attrs_len,
ep11_pin_blob, ep11_pin_blob_len, privblob,
&privblobsize, publblob, &publblobsize,
target_info->target);
@@ -5943,10 +5878,8 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
goto dsa_generate_keypair_end;
}
- TRACE_INFO("%s rc=0x%lx p_len=%zd publblobsize=0x%zx privblobsize=0x%zx "
- "npattr=0x%x\n",
- __func__, rc, p_len, publblobsize, privblobsize,
- new_public_attr + 1);
+ TRACE_INFO("%s rc=0x%lx plen=%zd publblobsize=0x%zx privblobsize=0x%zx\n",
+ __func__, rc, prime_attr->ulValueLen, publblobsize, privblobsize);
if (check_expected_mkvp(tokdata, privblob, privblobsize) != CKR_OK) {
TRACE_ERROR("%s\n", ock_err(ERR_DEVICE_ERROR));
@@ -6030,22 +5963,13 @@ dsa_generate_keypair_end:
free_attribute_array(new_publ_attrs, new_publ_attrs_len);
if (new_priv_attrs)
free_attribute_array(new_priv_attrs, new_priv_attrs_len);
- if (new_publ_attrs2)
- free_attribute_array(new_publ_attrs2, new_publ_attrs2_len);
- if (new_priv_attrs)
- free_attribute_array(new_priv_attrs2, new_priv_attrs2_len);
return rc;
}
-static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
- SESSION * sess,
+static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
+ SESSION *sess,
CK_MECHANISM_PTR pMechanism,
- TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_SESSION_HANDLE h)
+ TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
{
CK_RV rc;
CK_ATTRIBUTE *attr = NULL;
@@ -6054,7 +5978,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
size_t privkey_blob_len = sizeof(privkey_blob);
unsigned char spki[MAX_BLOBSIZE];
size_t spki_len = sizeof(spki);
- CK_ULONG i;
CK_ULONG bit_str_len;
CK_BYTE *key;
CK_BYTE *data, *oid, *parm;
@@ -6074,8 +5997,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
CK_ULONG new_publ_attrs2_len = 0, new_priv_attrs2_len = 0;
const struct _ec *curve = NULL;
- UNUSED(h);
-
if (pMechanism->mechanism == CKM_EC_KEY_PAIR_GEN) {
ktype = CKK_EC;
} else if ((pMechanism->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN) ||
@@ -6132,24 +6053,16 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
goto error;
}
- /* debug */
- for (i = 0; i < new_ulPrivateKeyAttributeCount; i++) {
- TRACE_INFO("%s gen priv attr type=0x%lx valuelen=0x%lx attrcnt=0x%lx\n",
- __func__, new_pPrivateKeyTemplate[i].type,
- new_pPrivateKeyTemplate[i].ulValueLen,
- new_ulPrivateKeyAttributeCount);
- }
-
trace_attributes(__func__, "RSA/EC public key attributes:",
new_publ_attrs2, new_publ_attrs2_len);
trace_attributes(__func__, "RSA/EC private key attributes:",
new_priv_attrs2, new_priv_attrs2_len);
ep11_get_pin_blob(ep11_session,
- (ep11_is_session_object
- (pPublicKeyTemplate, ulPublicKeyAttributeCount)
- || ep11_is_session_object(pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount)),
+ (ep11_is_session_object(new_publ_attrs2,
+ new_publ_attrs2_len) ||
+ ep11_is_session_object(new_priv_attrs2,
+ new_priv_attrs2_len)),
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
@@ -6406,15 +6319,10 @@ error:
return rc;
}
-static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
- SESSION * sess,
+static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
+ SESSION *sess,
CK_MECHANISM_PTR pMechanism,
- TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_SESSION_HANDLE h)
+ TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
{
CK_RV rc;
CK_ATTRIBUTE *attr = NULL;
@@ -6422,7 +6330,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
size_t privkey_blob_len = sizeof(privkey_blob);
unsigned char spki[MAX_BLOBSIZE];
size_t spki_len = sizeof(spki);
- CK_ULONG i;
CK_ULONG bit_str_len;
CK_BYTE *key;
CK_BYTE *data, *oid, *parm;
@@ -6444,8 +6351,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
const CK_BYTE dilithium_oid[] = { 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01,
0x02, 0x82, 0x0b, 0x01, 0x06, 0x05 };
- UNUSED(h);
-
if (pMechanism->mechanism != CKM_IBM_DILITHIUM) {
TRACE_ERROR("Invalid mechanism provided for %s\n ", __func__);
return CKR_MECHANISM_INVALID;
@@ -6503,24 +6408,16 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
goto error;
}
- /* debug */
- for (i = 0; i < new_ulPrivateKeyAttributeCount; i++) {
- TRACE_INFO("%s gen priv attr type=0x%lx valuelen=0x%lx attrcnt=0x%lx\n",
- __func__, new_pPrivateKeyTemplate[i].type,
- new_pPrivateKeyTemplate[i].ulValueLen,
- new_ulPrivateKeyAttributeCount);
- }
-
trace_attributes(__func__, "Dilithium public key attributes:",
new_publ_attrs2, new_publ_attrs2_len);
trace_attributes(__func__, "Dilithium private key attributes:",
new_priv_attrs2, new_priv_attrs2_len);
ep11_get_pin_blob(ep11_session,
- (ep11_is_session_object
- (pPublicKeyTemplate, ulPublicKeyAttributeCount)
- || ep11_is_session_object(pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount)),
+ (ep11_is_session_object(new_publ_attrs2,
+ new_publ_attrs2_len) ||
+ ep11_is_session_object(new_priv_attrs2,
+ new_priv_attrs2_len)),
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
@@ -6763,42 +6660,25 @@ CK_RV ep11tok_generate_key_pair(STDLL_TokData_t * tokdata, SESSION * sess,
case CKM_DH_PKCS_KEY_PAIR_GEN:
rc = dh_generate_keypair(tokdata, sess, pMechanism,
public_key_obj->template,
- private_key_obj->template,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount, sess->handle);
+ private_key_obj->template);
break;
case CKM_EC_KEY_PAIR_GEN: /* takes same parameters as RSA */
case CKM_RSA_PKCS_KEY_PAIR_GEN:
case CKM_RSA_X9_31_KEY_PAIR_GEN:
rc = rsa_ec_generate_keypair(tokdata, sess, pMechanism,
public_key_obj->template,
- private_key_obj->template,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount, sess->handle);
+ private_key_obj->template);
break;
case CKM_DSA_PARAMETER_GEN:
case CKM_DSA_KEY_PAIR_GEN:
rc = dsa_generate_keypair(tokdata, sess, pMechanism,
public_key_obj->template,
- private_key_obj->template,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount, sess->handle);
+ private_key_obj->template);
break;
case CKM_IBM_DILITHIUM:
rc = ibm_dilithium_generate_keypair(tokdata, sess, pMechanism,
public_key_obj->template,
- private_key_obj->template,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount,
- sess->handle);
+ private_key_obj->template);
break;
default:
TRACE_ERROR("%s invalid mech %s\n", __func__,
--
2.16.2.windows.1

View File

@ -1,43 +0,0 @@
From 8310482e5c46d6a15894c4d3ebf8156264175282 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 12 Oct 2022 09:00:51 +0200
Subject: [PATCH 02/34] EP11: Do not report DSA/DH parameter generation as
being supported
Mechanisms CKM_DSA_PARAMETER_GEN and CKM_DH_PKCS_PARAMETER_GEN were
reported to be supported in the mechanism list of the EP11 token, but
they never were really supported in the code.
Remove them from the mechanism list.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 5d7c5607..737b373b 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -6669,7 +6669,6 @@ CK_RV ep11tok_generate_key_pair(STDLL_TokData_t * tokdata, SESSION * sess,
public_key_obj->template,
private_key_obj->template);
break;
- case CKM_DSA_PARAMETER_GEN:
case CKM_DSA_KEY_PAIR_GEN:
rc = dsa_generate_keypair(tokdata, sess, pMechanism,
public_key_obj->template,
@@ -9042,10 +9041,8 @@ static const CK_MECHANISM_TYPE ep11_supported_mech_list[] = {
CKM_DES3_KEY_GEN,
CKM_DH_PKCS_DERIVE,
CKM_DH_PKCS_KEY_PAIR_GEN,
- CKM_DH_PKCS_PARAMETER_GEN,
CKM_DSA,
CKM_DSA_KEY_PAIR_GEN,
- CKM_DSA_PARAMETER_GEN,
CKM_DSA_SHA1,
CKM_EC_KEY_PAIR_GEN,
CKM_ECDH1_DERIVE,
--
2.16.2.windows.1

View File

@ -1,34 +0,0 @@
From 993274f7b968caa908bdc3bf560ece55e40c875a Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 21 Oct 2022 10:03:40 +0200
Subject: [PATCH 03/34] EP11: Do not pass empty CKA_PUBLIC_KEY_INFO to EP11
host library
Newer EP11 host library versions do not like empty (zero length)
attributes of type CKA_PUBLIC_KEY_INFO. Filter them out when building
the attribute list passed to the EP11 host library
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 737b373b..d3688c56 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1968,6 +1968,11 @@ static CK_RV build_ep11_attrs(STDLL_TokData_t * tokdata, TEMPLATE *template,
case CKA_NEVER_EXTRACTABLE:
case CKA_LOCAL:
break;
+ /* EP11 does not like empty (zero length) attributes of that types */
+ case CKA_PUBLIC_KEY_INFO:
+ if (attr->ulValueLen == 0)
+ break;
+ /* Fallthrough */
default:
if (attr->ulValueLen > 0 && attr->pValue == NULL)
return CKR_ATTRIBUTE_VALUE_INVALID;
--
2.16.2.windows.1

View File

@ -1,29 +0,0 @@
From 3b8f82b2aaf34fa67901aa27f85ae7973d5553d0 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 21 Oct 2022 10:10:36 +0200
Subject: [PATCH 04/34] Mechtable: CKM_IBM_DILITHIUM can also be used for key
generation
Currently this is not used anywhere, but let's correct it anyway.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/api/mechtable.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/usr/lib/api/mechtable.inc b/usr/lib/api/mechtable.inc
index 4a28192c..f74e08b7 100644
--- a/usr/lib/api/mechtable.inc
+++ b/usr/lib/api/mechtable.inc
@@ -78,7 +78,7 @@ const struct mechrow mechtable_rows[] =
{ "CKM_IBM_ATTRIBUTEBOUND_WRAP", CKM_IBM_ATTRIBUTEBOUND_WRAP, 0, MC_INFORMATION_UNAVAILABLE, MCF_WRAPUNWRAP | MCF_NEEDSPARAM },
{ "CKM_IBM_BTC_DERIVE", CKM_IBM_BTC_DERIVE, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE | MCF_NEEDSPARAM },
{ "CKM_IBM_CMAC", CKM_IBM_CMAC, 0, MC_KEY_DEPENDENT, MCF_SIGNVERIFY },
- { "CKM_IBM_DILITHIUM", CKM_IBM_DILITHIUM, 0, 3366, MCF_SIGNVERIFY },/* Size unknown */
+ { "CKM_IBM_DILITHIUM", CKM_IBM_DILITHIUM, 0, 3366, MCF_KEYGEN | MCF_SIGNVERIFY },
{ "CKM_IBM_ECDSA_OTHER", CKM_IBM_ECDSA_OTHER, 0, MC_KEY_DEPENDENT, MCF_SIGNVERIFY | MCF_NEEDSPARAM },
{ "CKM_IBM_EC_X25519", CKM_IBM_EC_X25519, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE },
{ "CKM_IBM_EC_X448", CKM_IBM_EC_X448, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE },
--
2.16.2.windows.1

View File

@ -1,63 +0,0 @@
From 7b4b5ef263aaa202667f318f4dcb09b01d3f025a Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 24 Oct 2022 12:58:16 +0200
Subject: [PATCH 05/34] EP11: Remove DSA/DH parameter generation mechanisms
from CP filter
Commit 836f2a25b928127c3bfb8f94a57cc16aa76a84c3 removed the DSA/DH
parameter generation mechanisms CKM_DSA_PARAMETER_GEN and
CKM_DH_PKCS_PARAMETER_GEN from the EP11 token code. Also remove
them from the CP filter config file and from a comment in the code.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 3 +--
usr/lib/ep11_stdll/ep11cpfilter.conf | 8 ++++----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index d3688c56..432790f1 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -1720,8 +1720,7 @@ static CK_RV check_key_attributes(STDLL_TokData_t * tokdata,
check_types = &check_types_pub[0];
attr_cnt = sizeof(check_types_pub) / sizeof(CK_ULONG);
}
- /* do nothing for CKM_DH_PKCS_KEY_PAIR_GEN
- and CKM_DH_PKCS_PARAMETER_GEN and CKK_IBM_PQC_DILITHIUM */
+ /* do nothing for CKM_DH_PKCS_KEY_PAIR_GEN and CKK_IBM_PQC_DILITHIUM */
break;
case CKO_PRIVATE_KEY:
if ((kt == CKK_EC) || (kt == CKK_ECDSA) || (kt == CKK_DSA)) {
diff --git a/usr/lib/ep11_stdll/ep11cpfilter.conf b/usr/lib/ep11_stdll/ep11cpfilter.conf
index 6d979053..0d3a6b3f 100644
--- a/usr/lib/ep11_stdll/ep11cpfilter.conf
+++ b/usr/lib/ep11_stdll/ep11cpfilter.conf
@@ -48,20 +48,20 @@ XCP_CPB_UNWRAP_SYMM: CKM_AES_CBC, CKM_AES_CBC_PAD, CKM_DES3_CBC, CKM_DES3_CBC_PA
# generate asymmetric keypairs
XCP_CPB_KEYGEN_ASYMM: CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_EC_KEY_PAIR_GEN, CKM_DSA_KEY_PAIR_GEN, CKM_DH_PKCS_KEY_PAIR_GEN
-# generate or derive symmetric keys, including DSA parameters
-XCP_CPB_KEYGEN_SYMM: CKM_AES_KEY_GEN, CKM_DES2_KEY_GEN, CKM_DES3_KEY_GEN, CKM_DSA_PARAMETER_GEN, CKM_DH_PKCS_PARAMETER_GEN, CKM_PBE_SHA1_DES3_EDE_CBC, CKM_DES_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN
+# generate or derive symmetric keys
+XCP_CPB_KEYGEN_SYMM: CKM_AES_KEY_GEN, CKM_DES2_KEY_GEN, CKM_DES3_KEY_GEN, CKM_PBE_SHA1_DES3_EDE_CBC, CKM_DES_KEY_GEN, CKM_GENERIC_SECRET_KEY_GEN
# RSA private-key or key-encrypt use
XCP_CPB_ALG_RSA: CKM_RSA_PKCS, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_PKCS_PSS, CKM_SHA1_RSA_X9_31, CKM_SHA1_RSA_PKCS, CKM_SHA1_RSA_PKCS_PSS, CKM_SHA256_RSA_PKCS, CKM_SHA256_RSA_PKCS_PSS, CKM_SHA224_RSA_PKCS, CKM_SHA224_RSA_PKCS_PSS, CKM_SHA384_RSA_PKCS, CKM_SHA384_RSA_PKCS_PSS, CKM_SHA512_RSA_PKCS, CKM_SHA512_RSA_PKCS_PSS, CKM_RSA_X9_31
# DSA private-key use
-XCP_CPB_ALG_DSA: CKM_DSA_PARAMETER_GEN, CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1
+XCP_CPB_ALG_DSA: CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1
# EC private-key use
XCP_CPB_ALG_EC: CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE, CKM_ECDSA, CKM_ECDSA_SHA224, CKM_ECDSA_SHA256, CKM_ECDSA_SHA384, CKM_ECDSA_SHA512
# Diffie-Hellman use (private keys)
-XCP_CPB_ALG_DH: CKM_ECDH1_DERIVE, CKM_DH_PKCS_PARAMETER_GEN, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE
+XCP_CPB_ALG_DH: CKM_ECDH1_DERIVE, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE
# allow key derivation (symmetric+EC/DH)
XCP_CPB_DERIVE: CKM_SHA1_KEY_DERIVATION, CKM_SHA256_KEY_DERIVATION, CKM_SHA384_KEY_DERIVATION, CKM_SHA512_KEY_DERIVATION, CKM_SHA224_KEY_DERIVATION, CKM_ECDH1_DERIVE, CKM_DH_PKCS_DERIVE
--
2.16.2.windows.1

View File

@ -1,68 +0,0 @@
From c6d6be8b7c1c1fa346af420daada56e28da5af6d Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 4 Nov 2022 09:44:35 +0100
Subject: [PATCH 06/34] EP11: Pass back chain code for CKM_IBM_BTC_DERIVE
When deriving a key using CKM_IBM_BTC_DERIVE, the resulting chain code
must be passed back in the buffer supplied by the caller in the
mechanism parameter (field pChainCode in CK_IBM_BTC_DERIVE_PARAMS).
This chain code can then be used to derive further keys from the just
derived key.
Note that field ulChainCodeLen must be zero for any BTC master key
derivation, but pChainCode must still point to a buffer of 32 bytes
(CK_IBM_BTC_CHAINCODE_LENGTH) to receive the resulting chain code.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 432790f1..a56b5b82 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -4988,6 +4988,7 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
CK_ULONG used_firmware_API_version;
CK_MECHANISM_PTR mech_orig = mech;
CK_ATTRIBUTE *ec_params;
+ CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
memset(newblob, 0, sizeof(newblob));
@@ -5106,6 +5107,18 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
}
+ if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
+ if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
+ mech->pParameter == NULL) {
+ TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
+ __func__, ep11_get_ckm(tokdata, mech->mechanism),
+ mech->ulParameterLen);
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
+ }
+
rc = h_opaque_2_blob(tokdata, hBaseKey, &keyblob, &keyblobsize,
&base_key_obj, READ_LOCK);
if (rc != CKR_OK) {
@@ -5300,6 +5313,13 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
opaque_attr = NULL;
+ if (mech->mechanism == CKM_IBM_BTC_DERIVE &&
+ btc_params != NULL && btc_params->pChainCode != NULL &&
+ cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
+ memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
+ btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
+ }
+
if (mech->mechanism == CKM_IBM_BTC_DERIVE && class == CKO_PUBLIC_KEY) {
/* Derived blob is an SPKI, extract public EC key attributes */
rc = ecdsa_priv_unwrap_get_data(key_obj->template,
--
2.16.2.windows.1

View File

@ -1,70 +0,0 @@
From 63a42a9398f5ec7b2b139810ee7b5beb7ad1abc3 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 4 Nov 2022 09:31:29 +0100
Subject: [PATCH 07/34] EP11: Supply CKA_PUBLIC_KEY_INFO with
CKM_IBM_BTC_DERIVE of public key
When deriving a public EC key with the CKM_IBM_BTC_DERIVE mechanism,
also supply the SPKI in the CKA_PUBLIC_KEY_INFO attribute.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index a56b5b82..886692c4 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -4989,6 +4989,9 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
CK_MECHANISM_PTR mech_orig = mech;
CK_ATTRIBUTE *ec_params;
CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
+ CK_BYTE *spki = NULL;
+ CK_ULONG spki_length = 0;
+ CK_ATTRIBUTE *spki_attr = NULL;
memset(newblob, 0, sizeof(newblob));
@@ -5329,6 +5332,29 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
__func__, rc);
goto error;
}
+
+ /* Extract the SPKI and add CKA_PUBLIC_KEY_INFO to key */
+ rc = publ_key_get_spki(key_obj->template, ktype, FALSE,
+ &spki, &spki_length);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("publ_key_get_spki failed\n");
+ goto error;
+ }
+
+ rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spki_length, &spki_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ goto error;
+ }
+
+ rc = template_update_attribute(key_obj->template, spki_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with "
+ "rc=0x%lx\n", __func__, rc);
+ goto error;
+ }
+ spki_attr = NULL;
}
if (class == CKO_SECRET_KEY || class == CKO_PRIVATE_KEY) {
@@ -5381,6 +5407,8 @@ error:
free(opaque_attr);
if (chk_attr != NULL)
free(chk_attr);
+ if (spki_attr != NULL)
+ free(spki_attr);
if (new_attrs)
free_attribute_array(new_attrs, new_attrs_len);
if (new_attrs1)
--
2.16.2.windows.1

View File

@ -1,347 +0,0 @@
From b8bc3e183b43e9aeee8a8f23c8e48fffb6eedc35 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 4 Nov 2022 10:51:08 +0100
Subject: [PATCH 08/34] EP11: Supply CKA_PUBLIC_KEY_INFO when importing private
keys
When importing private keys, the SPKI of the corresponding public key
is returned in parameters csum/cslen of the m_UnwrapKey() EP11 host
library call. Supply this SPKI as CKA_PUBLIC_KEY_INFO to the object.
For public key import, the common code already builds the SPKI from
the clear public key attributes of the imported public key.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/common/obj_mgr.c | 5 ++
usr/lib/ep11_stdll/ep11_specific.c | 113 +++++++++++++++++++++++++------------
2 files changed, 83 insertions(+), 35 deletions(-)
diff --git a/usr/lib/common/obj_mgr.c b/usr/lib/common/obj_mgr.c
index 8e61cbd4..347ec3f3 100644
--- a/usr/lib/common/obj_mgr.c
+++ b/usr/lib/common/obj_mgr.c
@@ -123,6 +123,11 @@ CK_RV object_mgr_add(STDLL_TokData_t *tokdata,
switch(class) {
case CKO_PUBLIC_KEY:
case CKO_PRIVATE_KEY:
+ /* Skip if there is already a non-empty CKA_PUBLIC_KEY_INFO */
+ if (template_attribute_get_non_empty(o->template, CKA_PUBLIC_KEY_INFO,
+ &spki_attr) == CKR_OK)
+ break;
+
rc = template_attribute_get_ulong(o->template, CKA_KEY_TYPE, &keytype);
if (rc != CKR_OK) {
TRACE_ERROR("Could not find CKA_KEY_TYPE for the key object.\n");
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 886692c4..3b14a557 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -2745,9 +2745,10 @@ static int get_curve_type_from_template(TEMPLATE *tmpl)
* SPKIs for public imported RSA keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
- OBJECT * rsa_key_obj,
- CK_BYTE * blob, size_t * blob_size)
+static CK_RV import_RSA_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *rsa_key_obj,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -2759,8 +2760,6 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ULONG attrs_len = 0;
CK_ATTRIBUTE_PTR new_p_attrs = NULL;
CK_ULONG new_attrs_len = 0;
- CK_BYTE csum[MAX_BLOBSIZE];
- CK_ULONG cslen = sizeof(csum);
CK_OBJECT_CLASS class;
CK_BYTE *data = NULL;
CK_ULONG data_len;
@@ -2831,6 +2830,8 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
goto import_RSA_key_end;
}
+ *spki_size = 0; /* common code will extract SPKI from object */
+
} else {
/* imported private RSA key goes here */
@@ -2884,7 +2885,7 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
ep11_data->raw2key_wrap_blob_l, NULL, ~0,
ep11_pin_blob, ep11_pin_blob_len, &mech_w,
new_p_attrs, new_attrs_len, blob, blob_size,
- csum, &cslen, target_info->target);
+ spki, spki_size, target_info->target);
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
@@ -2921,9 +2922,10 @@ import_RSA_key_end:
* SPKIs for public imported EC keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
- OBJECT * ec_key_obj,
- CK_BYTE * blob, size_t * blob_size)
+static CK_RV import_EC_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *ec_key_obj,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -2935,8 +2937,6 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ULONG attrs_len = 0;
CK_ATTRIBUTE_PTR new_p_attrs = NULL;
CK_ULONG new_attrs_len = 0;
- CK_BYTE csum[MAX_BLOBSIZE];
- CK_ULONG cslen = sizeof(csum);
CK_OBJECT_CLASS class;
CK_BYTE *data = NULL;
CK_ULONG data_len;
@@ -3059,6 +3059,8 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
goto import_EC_key_end;
}
+ *spki_size = 0; /* common code will extract SPKI from object */
+
} else {
/* imported private EC key goes here */
@@ -3115,7 +3117,8 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
ep11_pin_blob,
ep11_pin_blob_len, &mech_w,
new_p_attrs, new_attrs_len, blob,
- blob_size, csum, &cslen, target_info->target);
+ blob_size, spki, spki_size,
+ target_info->target);
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
@@ -3149,9 +3152,10 @@ import_EC_key_end:
* SPKIs for public imported DSA keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
- OBJECT * dsa_key_obj,
- CK_BYTE * blob, size_t * blob_size)
+static CK_RV import_DSA_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *dsa_key_obj,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -3163,8 +3167,6 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ULONG attrs_len = 0;
CK_ATTRIBUTE_PTR new_p_attrs = NULL;
CK_ULONG new_attrs_len = 0;
- CK_BYTE csum[MAX_BLOBSIZE];
- CK_ULONG cslen = sizeof(csum);
CK_OBJECT_CLASS class;
CK_BYTE *data = NULL;
CK_ULONG data_len;
@@ -3251,6 +3253,8 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
goto import_DSA_key_end;
}
+ *spki_size = 0; /* common code will extract SPKI from object */
+
} else {
/* imported private DSA key goes here */
@@ -3307,7 +3311,8 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
ep11_pin_blob,
ep11_pin_blob_len, &mech_w,
new_p_attrs, new_attrs_len, blob,
- blob_size, csum, &cslen, target_info->target);
+ blob_size, spki, spki_size,
+ target_info->target);
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
@@ -3339,9 +3344,10 @@ import_DSA_key_end:
* SPKIs for public imported DH keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
- OBJECT * dh_key_obj,
- CK_BYTE * blob, size_t * blob_size)
+static CK_RV import_DH_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *dh_key_obj,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -3353,8 +3359,6 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ULONG attrs_len = 0;
CK_ATTRIBUTE_PTR new_p_attrs = NULL;
CK_ULONG new_attrs_len = 0;
- CK_BYTE csum[MAX_BLOBSIZE];
- CK_ULONG cslen = sizeof(csum);
CK_OBJECT_CLASS class;
CK_BYTE *data = NULL;
CK_ULONG data_len;
@@ -3433,6 +3437,8 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
goto import_DH_key_end;
}
+ *spki_size = 0; /* common code will extract SPKI from object */
+
} else {
CK_ATTRIBUTE *value;
CK_ATTRIBUTE *value_bits;
@@ -3500,7 +3506,8 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
ep11_pin_blob,
ep11_pin_blob_len, &mech_w,
new_p_attrs, new_attrs_len, blob,
- blob_size, csum, &cslen, target_info->target);
+ blob_size, spki, spki_size,
+ target_info->target);
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
@@ -3547,9 +3554,10 @@ import_DH_key_end:
* SPKIs for public imported IBM Dilithium keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
- OBJECT * dilithium_key_obj,
- CK_BYTE * blob, size_t * blob_size)
+static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *dilithium_key_obj,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -3561,8 +3569,6 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ULONG attrs_len = 0;
CK_ATTRIBUTE_PTR new_p_attrs = NULL;
CK_ULONG new_attrs_len = 0;
- CK_BYTE csum[MAX_BLOBSIZE];
- CK_ULONG cslen = sizeof(csum);
CK_OBJECT_CLASS class;
CK_BYTE *data = NULL;
CK_ULONG data_len;
@@ -3652,6 +3658,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
goto done;
}
+ *spki_size = 0; /* common code will extract SPKI from object */
+
} else {
/* imported private IBM Dilithium key goes here */
@@ -3709,7 +3717,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
ep11_pin_blob,
ep11_pin_blob_len, &mech_w,
new_p_attrs, new_attrs_len, blob,
- blob_size, csum, &cslen, target_info->target);
+ blob_size, spki, spki_size,
+ target_info->target);
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
@@ -3747,9 +3756,13 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
CK_ATTRIBUTE *attr = NULL;
CK_BYTE blob[MAX_BLOBSIZE];
size_t blobsize = sizeof(blob);
+ CK_BYTE spki[MAX_BLOBSIZE];
+ size_t spkisize = sizeof(spki);
CK_RV rc;
CK_ULONG class;
CK_BBOOL attrbound;
+ CK_BYTE *temp;
+ CK_ULONG temp_len;
/* get key type */
rc = template_attribute_get_ulong(obj->template, CKA_KEY_TYPE, &keytype);
@@ -3783,7 +3796,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
/* only these keys can be imported */
switch (keytype) {
case CKK_RSA:
- rc = import_RSA_key(tokdata, sess, obj, blob, &blobsize);
+ rc = import_RSA_key(tokdata, sess, obj, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
TRACE_ERROR("%s import RSA key rc=0x%lx blobsize=0x%zx\n",
__func__, rc, blobsize);
@@ -3793,7 +3807,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
__func__, rc, blobsize);
break;
case CKK_EC:
- rc = import_EC_key(tokdata, sess, obj, blob, &blobsize);
+ rc = import_EC_key(tokdata, sess, obj, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
TRACE_ERROR("%s import EC key rc=0x%lx blobsize=0x%zx\n",
__func__, rc, blobsize);
@@ -3803,7 +3818,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
__func__, rc, blobsize);
break;
case CKK_DSA:
- rc = import_DSA_key(tokdata, sess, obj, blob, &blobsize);
+ rc = import_DSA_key(tokdata, sess, obj, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
TRACE_ERROR("%s import DSA key rc=0x%lx blobsize=0x%zx\n",
__func__, rc, blobsize);
@@ -3813,7 +3829,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
__func__, rc, blobsize);
break;
case CKK_DH:
- rc = import_DH_key(tokdata, sess, obj, blob, &blobsize);
+ rc = import_DH_key(tokdata, sess, obj, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
TRACE_ERROR("%s import DH key rc=0x%lx blobsize=0x%zx\n",
__func__, rc, blobsize);
@@ -3823,7 +3840,8 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
__func__, rc, blobsize);
break;
case CKK_IBM_PQC_DILITHIUM:
- rc = import_IBM_Dilithium_key(tokdata, sess, obj, blob, &blobsize);
+ rc = import_IBM_Dilithium_key(tokdata, sess, obj, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
TRACE_ERROR("%s import IBM Dilithium key rc=0x%lx blobsize=0x%zx\n",
__func__, rc, blobsize);
@@ -3891,6 +3909,31 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
return rc;
}
+ if (spkisize > 0 && (class == CKO_PRIVATE_KEY || class == CKO_PUBLIC_KEY)) {
+ /* spki may be a MACed SPKI, get length of SPKI part only */
+ rc = ber_decode_SEQUENCE(spki, &temp, &temp_len, &spkisize);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ber_decode_SEQUENCE failed rc=0x%lx\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spkisize, &attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__,
+ rc);
+ return rc;
+ }
+
+ rc = template_update_attribute(obj->template, attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(attr);
+ return rc;
+ }
+ }
+
rc = update_ep11_attrs_from_blob(tokdata, sess, obj->template);
if (rc != CKR_OK) {
TRACE_ERROR("%s update_ep11_attrs_from_blob failed with rc=0x%lx\n",
--
2.16.2.windows.1

View File

@ -1,31 +0,0 @@
From b17570340533d36db1782e5aeafc9107c607b7c4 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 7 Nov 2022 14:04:01 +0100
Subject: [PATCH 09/34] EP11: Fix memory leak introduced with recent commit
Function publ_key_get_spki() allocates the SPKI buffer, so it must be freed
afterwards.
Fixes: 638fa126c8cb28ff7daf2bb383a0461c8f9fe6f8
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 3b14a557..9e320503 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -5452,6 +5452,8 @@ error:
free(chk_attr);
if (spki_attr != NULL)
free(spki_attr);
+ if (spki != NULL)
+ free(spki);
if (new_attrs)
free_attribute_array(new_attrs, new_attrs_len);
if (new_attrs1)
--
2.16.2.windows.1

View File

@ -1,34 +0,0 @@
From bea2552c40339d9013eaaa55b13491c7e36fbadf Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 8 Nov 2022 15:49:22 +0100
Subject: [PATCH 10/34] p11sak: Fix segfault when dilithium version is not
specified with generate-key
Command 'p11sak generate-key ibm-dilithium' segfaults because the dilithium
version is not specified, but the code does not check for a NULL pointer.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/sbin/p11sak/p11sak.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index b399c88a..8cfcb21d 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -1843,6 +1843,12 @@ static CK_RV check_args_gen_key(p11sak_kt *kt, CK_ULONG keylength,
case kt_3DES:
break;
case kt_IBM_DILITHIUM:
+ if (dilithium_ver == NULL) {
+ fprintf(stderr,
+ "Cipher key type [%d] supported but Dilithium version not set in arguments. Try adding argument <r2_65>\n",
+ *kt);
+ return CKR_ARGUMENTS_BAD;
+ }
if (strcasecmp(dilithium_ver, "r2_65") == 0) {
break;
} else {
--
2.16.2.windows.1

View File

@ -1,118 +0,0 @@
From ee3464dff7536c98fd64c80d87c765f703dff0f0 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 18 Nov 2022 10:44:56 +0100
Subject: [PATCH 11/34] EP11: remove dead code and unused variables
Some variables are declared and initialized to NULL, but never used or set.
The attempt to free them at the end of the function is dead code.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 28 ----------------------------
1 file changed, 28 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 9e320503..1dbfe0f5 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -3575,7 +3575,6 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
- CK_BYTE *pubkey = NULL;
memcpy(iv, "1234567812345678", AES_BLOCK_SIZE);
@@ -3734,9 +3733,6 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
}
done:
-
- if (pubkey)
- free(pubkey);
if (data) {
OPENSSL_cleanse(data, data_len);
free(data);
@@ -5486,7 +5482,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t *tokdata,
CK_ATTRIBUTE *opaque_attr = NULL;
CK_ATTRIBUTE *value_attr = NULL;
CK_ATTRIBUTE *attr = NULL;
- CK_ATTRIBUTE *pPublicKeyTemplate_new = NULL;
CK_ATTRIBUTE_PTR dh_pPublicKeyTemplate = NULL;
CK_ULONG dh_ulPublicKeyAttributeCount = 0;
CK_ATTRIBUTE_PTR dh_pPrivateKeyTemplate = NULL;
@@ -5746,7 +5741,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t *tokdata,
}
dh_generate_keypair_end:
- free(pPublicKeyTemplate_new);
if (dh_pgs.pg != NULL)
free(dh_pgs.pg);
if (dh_pPublicKeyTemplate)
@@ -5778,7 +5772,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t *tokdata,
CK_ATTRIBUTE *opaque_attr = NULL;
CK_ATTRIBUTE *value_attr = NULL;
CK_ATTRIBUTE *attr = NULL;
- CK_ATTRIBUTE *pPublicKeyTemplate_new = NULL;
CK_BYTE *key;
CK_BYTE *data, *oid, *parm;
CK_ULONG data_len, field_len, bit_str_len, oid_len, parm_len;
@@ -6047,7 +6040,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t *tokdata,
}
dsa_generate_keypair_end:
- free(pPublicKeyTemplate_new);
if (dsa_pqgs.pqg != NULL)
free(dsa_pqgs.pqg);
if (dsa_pPublicKeyTemplate)
@@ -6080,10 +6072,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
CK_BYTE *data, *oid, *parm;
CK_ULONG data_len, oid_len, parm_len;
CK_ULONG field_len;
- CK_ATTRIBUTE_PTR new_pPublicKeyTemplate = NULL;
- CK_ULONG new_ulPublicKeyAttributeCount = 0;
- CK_ATTRIBUTE_PTR new_pPrivateKeyTemplate = NULL;
- CK_ULONG new_ulPrivateKeyAttributeCount = 0;
CK_ULONG ktype;
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
@@ -6399,12 +6387,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t *tokdata,
}
error:
- if (new_pPrivateKeyTemplate)
- free_attribute_array(new_pPrivateKeyTemplate,
- new_ulPrivateKeyAttributeCount);
- if (new_pPublicKeyTemplate)
- free_attribute_array(new_pPublicKeyTemplate,
- new_ulPublicKeyAttributeCount);
if (new_publ_attrs)
free_attribute_array(new_publ_attrs, new_publ_attrs_len);
if (new_priv_attrs)
@@ -6432,10 +6414,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
CK_BYTE *data, *oid, *parm;
CK_ULONG data_len, oid_len, parm_len;
CK_ULONG field_len;
- CK_ATTRIBUTE_PTR new_pPublicKeyTemplate = NULL;
- CK_ULONG new_ulPublicKeyAttributeCount = 0;
- CK_ATTRIBUTE_PTR new_pPrivateKeyTemplate = NULL;
- CK_ULONG new_ulPrivateKeyAttributeCount = 0;
CK_ULONG ktype = CKK_IBM_PQC_DILITHIUM;
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
@@ -6679,12 +6657,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
}
error:
- if (new_pPrivateKeyTemplate)
- free_attribute_array(new_pPrivateKeyTemplate,
- new_ulPrivateKeyAttributeCount);
- if (new_pPublicKeyTemplate)
- free_attribute_array(new_pPublicKeyTemplate,
- new_ulPublicKeyAttributeCount);
if (new_publ_attrs)
free_attribute_array(new_publ_attrs, new_publ_attrs_len);
if (new_priv_attrs)
--
2.16.2.windows.1

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +0,0 @@
From 4cad40e594b916ef3416dd574304b2c60138a6fe Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 19 Sep 2022 09:01:13 +0200
Subject: [PATCH 13/34] EP11: Support EP11 host library version 4
Try to load the EP11 host library version 4 (libep11.so.4) first,
but fall back to version 3, 2, 1, or even the un-versioned shared library.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 15 ++++++++++++---
usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c | 11 +++++++++--
usr/sbin/pkcsep11_session/pkcsep11_session.c | 11 +++++++++--
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 1dbfe0f5..304989fc 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -66,6 +66,7 @@
#include "pkey_utils.h"
#define EP11SHAREDLIB_NAME "OCK_EP11_LIBRARY"
+#define EP11SHAREDLIB_V4 "libep11.so.4"
#define EP11SHAREDLIB_V3 "libep11.so.3"
#define EP11SHAREDLIB_V2 "libep11.so.2"
#define EP11SHAREDLIB_V1 "libep11.so.1"
@@ -2209,9 +2210,17 @@ static void *ep11_load_host_lib()
return lib_ep11;
}
- ep11_lib_name = EP11SHAREDLIB_V3;
+ ep11_lib_name = EP11SHAREDLIB_V4;
lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ if (lib_ep11 == NULL) {
+ TRACE_DEVEL("%s Error loading shared library '%s', trying '%s'\n",
+ __func__, EP11SHAREDLIB_V4, EP11SHAREDLIB_V3);
+ /* Try version 3 instead */
+ ep11_lib_name = EP11SHAREDLIB_V3;
+ lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ }
+
if (lib_ep11 == NULL) {
TRACE_DEVEL("%s Error loading shared library '%s', trying '%s'\n",
__func__, EP11SHAREDLIB_V3, EP11SHAREDLIB_V2);
@@ -2239,9 +2248,9 @@ static void *ep11_load_host_lib()
if (lib_ep11 == NULL) {
errstr = dlerror();
OCK_SYSLOG(LOG_ERR,
- "%s: Error loading shared library '%s[.3|.2|.1]' [%s]\n",
+ "%s: Error loading shared library '%s[.4][.3|.2|.1]' [%s]\n",
__func__, EP11SHAREDLIB, errstr);
- TRACE_ERROR("%s Error loading shared library '%s[.3|.2|.1]' [%s]\n",
+ TRACE_ERROR("%s Error loading shared library '%s[.4][.3|.2|.1]' [%s]\n",
__func__, EP11SHAREDLIB, errstr);
return NULL;
}
diff --git a/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c b/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c
index 4a42a085..f80cfa9f 100644
--- a/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c
+++ b/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c
@@ -30,6 +30,7 @@
#include "pin_prompt.h"
#define EP11SHAREDLIB_NAME "OCK_EP11_LIBRARY"
+#define EP11SHAREDLIB_V4 "libep11.so.4"
#define EP11SHAREDLIB_V3 "libep11.so.3"
#define EP11SHAREDLIB_V2 "libep11.so.2"
#define EP11SHAREDLIB_V1 "libep11.so.1"
@@ -424,9 +425,15 @@ static void *ep11_load_host_lib()
return lib_ep11;
}
- ep11_lib_name = EP11SHAREDLIB_V3;
+ ep11_lib_name = EP11SHAREDLIB_V4;
lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ if (lib_ep11 == NULL) {
+ /* Try version 3 instead */
+ ep11_lib_name = EP11SHAREDLIB_V3;
+ lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ }
+
if (lib_ep11 == NULL) {
/* Try version 2 instead */
ep11_lib_name = EP11SHAREDLIB_V2;
@@ -447,7 +454,7 @@ static void *ep11_load_host_lib()
if (lib_ep11 == NULL) {
errstr = dlerror();
- fprintf(stderr, "Error loading shared library '%s[.3|.2|.1]' [%s]\n",
+ fprintf(stderr, "Error loading shared library '%s[.4|.3|.2|.1]' [%s]\n",
EP11SHAREDLIB, errstr);
return NULL;
}
diff --git a/usr/sbin/pkcsep11_session/pkcsep11_session.c b/usr/sbin/pkcsep11_session/pkcsep11_session.c
index 0c210135..b7b9e9c4 100644
--- a/usr/sbin/pkcsep11_session/pkcsep11_session.c
+++ b/usr/sbin/pkcsep11_session/pkcsep11_session.c
@@ -35,6 +35,7 @@
#include "pin_prompt.h"
#define EP11SHAREDLIB_NAME "OCK_EP11_LIBRARY"
+#define EP11SHAREDLIB_V4 "libep11.so.4"
#define EP11SHAREDLIB_V3 "libep11.so.3"
#define EP11SHAREDLIB_V2 "libep11.so.2"
#define EP11SHAREDLIB_V1 "libep11.so.1"
@@ -1050,9 +1051,15 @@ static void *ep11_load_host_lib()
return lib_ep11;
}
- ep11_lib_name = EP11SHAREDLIB_V3;
+ ep11_lib_name = EP11SHAREDLIB_V4;
lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ if (lib_ep11 == NULL) {
+ /* Try version 3 instead */
+ ep11_lib_name = EP11SHAREDLIB_V3;
+ lib_ep11 = dlopen(ep11_lib_name, DLOPEN_FLAGS);
+ }
+
if (lib_ep11 == NULL) {
/* Try version 2 instead */
ep11_lib_name = EP11SHAREDLIB_V2;
@@ -1073,7 +1080,7 @@ static void *ep11_load_host_lib()
if (lib_ep11 == NULL) {
errstr = dlerror();
- fprintf(stderr, "Error loading shared library '%s[.3|.2|.1]' [%s]\n",
+ fprintf(stderr, "Error loading shared library '%s[.4|.3|.2|.1]' [%s]\n",
EP11SHAREDLIB, errstr);
return NULL;
}
--
2.16.2.windows.1

View File

@ -1,53 +0,0 @@
From b89b408953e9192d7bfcb31cdf8c48d6c973488a Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 10:23:29 +0100
Subject: [PATCH 14/34] EP11: Add new control points
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 7 +++++++
usr/lib/ep11_stdll/ep11cpfilter.conf | 6 ++++++
2 files changed, 13 insertions(+)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 304989fc..147ce7b2 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -10524,13 +10524,20 @@ static const_info_t ep11_cps[] = {
CONSTINFO(XCP_CPB_WRAP_WITH_RAW_SPKI),
CONSTINFO(XCP_CPB_ALG_DH),
CONSTINFO(XCP_CPB_DERIVE),
+ CONSTINFO(XCP_CPB_ALLOW_NONSESSION),
CONSTINFO(XCP_CPB_ALG_EC_25519),
+ CONSTINFO(XCP_CPB_ALG_EC_SECGCRV),
CONSTINFO(XCP_CPB_ALG_NBSI2017),
CONSTINFO(XCP_CPB_CPACF_PK),
CONSTINFO(XCP_CPB_ALG_PQC_DILITHIUM),
CONSTINFO(XCP_CPB_ALG_PQC),
CONSTINFO(XCP_CPB_BTC),
CONSTINFO(XCP_CPB_ECDSA_OTHER),
+ CONSTINFO(XCP_CPB_ALG_NFIPS2021),
+ CONSTINFO(XCP_CPB_ALG_NFIPS2024),
+ CONSTINFO(XCP_CPB_COMPAT_LEGACY_SHA3),
+ CONSTINFO(XCP_CPB_DSA_PARAMETER_GEN),
+ CONSTINFO(XCP_CPB_DERIVE_NON_AB_KEYS),
};
#ifdef DEBUG
diff --git a/usr/lib/ep11_stdll/ep11cpfilter.conf b/usr/lib/ep11_stdll/ep11cpfilter.conf
index 0d3a6b3f..9d6a2fc8 100644
--- a/usr/lib/ep11_stdll/ep11cpfilter.conf
+++ b/usr/lib/ep11_stdll/ep11cpfilter.conf
@@ -80,3 +80,9 @@ XCP_CPB_BTC: CKM_IBM_BTC_DERIVE
# enable non-ECDSA/non-EdDSA elliptic curve signature algorithms
XCP_CPB_ECDSA_OTHER: CKM_IBM_ECDSA_OTHER
+
+# allow non-FIPS-approved algs (2021)
+XCP_CPB_ALG_NFIPS2021: CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_DSA_SHA1, CKM_ECDSA_SHA1, CKM_DES_KEY_GEN, CKM_DES_ECB, CKM_DES_CBC, CKM_DES_CBC_PAD, CKM_DES2_KEY_GEN, CKM_DES3_KEY_GEN, CKM_DES3_ECB, CKM_DES3_CBC, CKM_DES3_MAC, CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_DES3_CMAC_GENERAL, CKM_DES3_CMAC, CKM_DES_OFB64, CKM_DES_CFB64, CKM_DES_CFB8, CKM_SHA_1_HMAC, CKM_SHA_1_HMAC_GENERAL, CKM_SHA1_KEY_DERIVATION
+
+# allow non-FIPS-approved algs (2024)
+XCP_CPB_ALG_NFIPS2024: CKM_RSA_PKCS, CKM_SHA1_RSA_PKCS, CKM_DSA_SHA1, CKM_ECDSA_SHA1, CKM_DES_KEY_GEN, CKM_DES_ECB, CKM_DES_CBC, CKM_DES_CBC_PAD, CKM_DES2_KEY_GEN, CKM_DES3_KEY_GEN, CKM_DES3_ECB, CKM_DES3_CBC, CKM_DES3_MAC, CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_DES3_CMAC_GENERAL, CKM_DES3_CMAC, CKM_DES_OFB64, CKM_DES_CFB64, CKM_DES_CFB8, CKM_SHA_1_HMAC, CKM_SHA_1_HMAC_GENERAL, CKM_SHA1_KEY_DERIVATION
--
2.16.2.windows.1

View File

@ -1,76 +0,0 @@
From 65cb0f2b0204183617b5d6e8e475f85faa8b789d Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 14 Feb 2022 16:35:34 +0100
Subject: [PATCH 15/34] EP11: Default unknown CPs to ON
Newer EP11 cards know additional control points that older cards do not
know. When building the combined minimum control point setting, treat
unknown control points as ON, to not disable mechanisms just because an
older card does not know a control point.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 147ce7b2..e3451163 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -10904,13 +10904,18 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
#ifdef DEBUG
TRACE_DEBUG("Control points from adapter %02X.%04X\n", adapter, domain);
TRACE_DEBUG_DUMP(" ", cp, cp_len);
+ TRACE_DEBUG("Max control point index: %lu\n", max_cp_index);
#endif
if (data->first) {
data->first_adapter = adapter;
data->first_domain = domain;
- memcpy(data->first_cp, cp, cp_len);
- memcpy(data->combined_cp, cp, cp_len);
+ /* Apply CP bits 0 to max_cp_index-1 only */
+ for (i = 0; i < max_cp_index; i++) {
+ data->combined_cp[CP_BYTE_NO(i)] &=
+ (cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
+ }
+ memcpy(data->first_cp, data->combined_cp, sizeof(data->first_cp));
data->max_cp_index = max_cp_index;
data->first = 0;
} else {
@@ -10927,8 +10932,10 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
data->first_domain);
}
- for (i = 0; i < cp_len; i++) {
- data->combined_cp[i] &= cp[i];
+ for (i = 0; i < max_cp_index; i++) {
+ /* Apply CP bits 0 to max_cp_index-1 only */
+ data->combined_cp[CP_BYTE_NO(i)] &=
+ (cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
}
if (max_cp_index != data->max_cp_index) {
@@ -10973,6 +10980,11 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
ep11_private_data_t *ep11_data = tokdata->private_data;
memset(&data, 0, sizeof(data));
+ /*
+ * Turn all CPs ON by default, so that newer control points that are unknown
+ * to older cards default to ON. CPs being OFF disable functionality.
+ */
+ memset(data.combined_cp, 0xff, sizeof(data.combined_cp));
data.first = 1;
rc = handle_all_ep11_cards(&ep11_data->target_list, control_point_handler,
&data);
@@ -10987,6 +10999,7 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
TRACE_DEBUG("Combined control points from all cards (%lu CPs):\n",
data.max_cp_index);
TRACE_DEBUG_DUMP(" ", cp, *cp_len);
+ TRACE_DEBUG("Max control point index: %lu\n", data.max_cp_index);
print_control_points(cp, *cp_len, data.max_cp_index);
#endif
--
2.16.2.windows.1

View File

@ -1,76 +0,0 @@
From 95f64e0c9f30ea8e0712e554418230659dabe1ec Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 13:44:10 +0100
Subject: [PATCH 16/34] COMMON: Add defines for Dilithium round 2 and 3
variants
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/include/pkcs11types.h | 12 ++++++++++--
usr/lib/common/p11util.c | 6 ++++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/usr/include/pkcs11types.h b/usr/include/pkcs11types.h
index bc53e672..6bf9c1fa 100644
--- a/usr/include/pkcs11types.h
+++ b/usr/include/pkcs11types.h
@@ -437,6 +437,7 @@ typedef CK_ULONG CK_KEY_TYPE;
#ifndef OCK_NO_EP11_DEFINES
#define CKK_IBM_PQC_DILITHIUM CKK_VENDOR_DEFINED + 0x10023
#endif
+#define CKK_IBM_DILITHIUM CKK_IBM_PQC_DILITHIUM
/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
* type */
@@ -594,8 +595,15 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_IBM_PROTKEY_NEVER_EXTRACTABLE (CKA_VENDOR_DEFINED +0x1000d)
#define CKA_IBM_OPAQUE_PKEY (CKA_VENDOR_DEFINED + 0xd0100)
-/* For Dilithium, oid = 1.3.6.1.4.1.2.267.1.6.5 */
-#define IBM_DILITHIUM_KEYFORM_ROUND2 1
+#define CK_IBM_DILITHIUM_KEYFORM_ROUND2_65 1
+#define CK_IBM_DILITHIUM_KEYFORM_ROUND2_87 2
+#define CK_IBM_DILITHIUM_KEYFORM_ROUND3_44 3
+#define CK_IBM_DILITHIUM_KEYFORM_ROUND3_65 4
+#define CK_IBM_DILITHIUM_KEYFORM_ROUND3_87 5
+
+#define IBM_DILITHIUM_KEYFORM_ROUND2 CK_IBM_DILITHIUM_KEYFORM_ROUND2_65
+
+#define CKA_IBM_DILITHIUM_MODE (CKA_VENDOR_DEFINED + 0x00010)
#define CKA_IBM_DILITHIUM_KEYFORM (CKA_VENDOR_DEFINED + 0xd0001)
#define CKA_IBM_DILITHIUM_RHO (CKA_VENDOR_DEFINED + 0xd0002)
diff --git a/usr/lib/common/p11util.c b/usr/lib/common/p11util.c
index 4ef33306..f3a031e3 100644
--- a/usr/lib/common/p11util.c
+++ b/usr/lib/common/p11util.c
@@ -123,6 +123,10 @@ const char *p11_get_ckr(CK_RV rc)
}
}
+#ifndef CKA_IBM_PQC_PARAMS
+#define CKA_IBM_PQC_PARAMS (CKA_VENDOR_DEFINED +0x1000e)
+#endif
+
//
// p11_get_cka - return textual interpretation of an attribute type
// only simple types - no arrays. For unknown a ptr to a static
@@ -221,6 +225,7 @@ const char *p11_get_cka(CK_ATTRIBUTE_TYPE atype)
_sym2str(CKA_IBM_PROTKEY_NEVER_EXTRACTABLE);
_sym2str(CKA_IBM_OPAQUE_PKEY);
_sym2str(CKA_IBM_DILITHIUM_KEYFORM);
+ _sym2str(CKA_IBM_DILITHIUM_MODE);
_sym2str(CKA_IBM_DILITHIUM_RHO);
_sym2str(CKA_IBM_DILITHIUM_SEED);
_sym2str(CKA_IBM_DILITHIUM_TR);
@@ -228,6 +233,7 @@ const char *p11_get_cka(CK_ATTRIBUTE_TYPE atype)
_sym2str(CKA_IBM_DILITHIUM_S2);
_sym2str(CKA_IBM_DILITHIUM_T0);
_sym2str(CKA_IBM_DILITHIUM_T1);
+ _sym2str(CKA_IBM_PQC_PARAMS);
default:
sprintf(buf, "unknown attribute type 0x%08lx", atype);
return buf;
--
2.16.2.windows.1

View File

@ -1,103 +0,0 @@
From d4bb3258779d757ce6faf5b698c70af77ab7647f Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 13:51:16 +0100
Subject: [PATCH 17/34] COMMON: Add defines for Kyber
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/include/pkcs11types.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++
usr/lib/common/p11util.c | 4 ++++
2 files changed, 53 insertions(+)
diff --git a/usr/include/pkcs11types.h b/usr/include/pkcs11types.h
index 6bf9c1fa..3d967a13 100644
--- a/usr/include/pkcs11types.h
+++ b/usr/include/pkcs11types.h
@@ -439,6 +439,11 @@ typedef CK_ULONG CK_KEY_TYPE;
#endif
#define CKK_IBM_DILITHIUM CKK_IBM_PQC_DILITHIUM
+#ifndef OCK_NO_EP11_DEFINES
+#define CKK_IBM_PQC_KYBER CKK_VENDOR_DEFINED + 0x10024
+#endif
+#define CKK_IBM_KYBER CKK_IBM_PQC_KYBER
+
/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
* type */
/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
@@ -614,6 +619,49 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_IBM_DILITHIUM_T0 (CKA_VENDOR_DEFINED + 0xd0007)
#define CKA_IBM_DILITHIUM_T1 (CKA_VENDOR_DEFINED + 0xd0008)
+#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 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_KEM_MODE;
+
+#define CK_IBM_KYBER_KEM_ENCAPSULATE 1
+#define CK_IBM_KYBER_KEM_DECAPSULATE 2
+
+typedef CK_ULONG CK_IBM_KYBER_KDF_TYPE;
+
+#if !defined(CKD_VENDOR_DEFINED)
+#define CKD_VENDOR_DEFINED 0x80000000UL
+#endif
+
+#ifndef OCK_NO_EP11_DEFINES
+#define CKD_IBM_HYBRID_NULL CKD_VENDOR_DEFINED + 0x00000001UL
+#define CKD_IBM_HYBRID_SHA1_KDF CKD_VENDOR_DEFINED + 0x00000002UL
+#define CKD_IBM_HYBRID_SHA224_KDF CKD_VENDOR_DEFINED + 0x00000003UL
+#define CKD_IBM_HYBRID_SHA256_KDF CKD_VENDOR_DEFINED + 0x00000004UL
+#define CKD_IBM_HYBRID_SHA384_KDF CKD_VENDOR_DEFINED + 0x00000005UL
+#define CKD_IBM_HYBRID_SHA512_KDF CKD_VENDOR_DEFINED + 0x00000006UL
+#endif
+
+typedef 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;
+} CK_IBM_KYBER_PARAMS;
+
/* For NSS 3.30: */
#define NSSCK_VENDOR_NSS 0x4E534350
#define CKA_NSS (CKA_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
@@ -941,6 +989,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_IBM_SHA3_512 CKM_VENDOR_DEFINED + 0x00010004
#define CKM_IBM_CMAC CKM_VENDOR_DEFINED + 0x00010007
#define CKM_IBM_DILITHIUM CKM_VENDOR_DEFINED + 0x00010023
+#define CKM_IBM_KYBER CKM_VENDOR_DEFINED + 0x00010024
#define CKM_IBM_SHA3_224_HMAC CKM_VENDOR_DEFINED + 0x00010025
#define CKM_IBM_SHA3_256_HMAC CKM_VENDOR_DEFINED + 0x00010026
#define CKM_IBM_SHA3_384_HMAC CKM_VENDOR_DEFINED + 0x00010027
diff --git a/usr/lib/common/p11util.c b/usr/lib/common/p11util.c
index f3a031e3..8b81ab42 100644
--- a/usr/lib/common/p11util.c
+++ b/usr/lib/common/p11util.c
@@ -234,6 +234,10 @@ const char *p11_get_cka(CK_ATTRIBUTE_TYPE atype)
_sym2str(CKA_IBM_DILITHIUM_T0);
_sym2str(CKA_IBM_DILITHIUM_T1);
_sym2str(CKA_IBM_PQC_PARAMS);
+ _sym2str(CKA_IBM_KYBER_KEYFORM);
+ _sym2str(CKA_IBM_KYBER_MODE);
+ _sym2str(CKA_IBM_KYBER_PK);
+ _sym2str(CKA_IBM_KYBER_SK);
default:
sprintf(buf, "unknown attribute type 0x%08lx", atype);
return buf;
--
2.16.2.windows.1

View File

@ -1,249 +0,0 @@
From 67ed25a8f7764e61647c3c31d09a1e60db38006b Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 11:20:54 +0100
Subject: [PATCH 18/34] COMMON: Add post-quantum algorithm OIDs
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/include/include.mk | 2 +-
usr/include/pqc_oids.h | 48 ++++++++++++++++++++++++++
usr/lib/common/common.mk | 3 +-
usr/lib/common/globals.c | 1 +
usr/lib/common/pqc_defs.h | 48 ++++++++++++++++++++++++++
usr/lib/common/pqc_supported.c | 78 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 178 insertions(+), 2 deletions(-)
create mode 100644 usr/include/pqc_oids.h
create mode 100644 usr/lib/common/pqc_defs.h
create mode 100644 usr/lib/common/pqc_supported.c
diff --git a/usr/include/include.mk b/usr/include/include.mk
index 79e593d7..a63e043f 100644
--- a/usr/include/include.mk
+++ b/usr/include/include.mk
@@ -3,7 +3,7 @@ opencryptokiincludedir = ${includedir}/opencryptoki
opencryptokiinclude_HEADERS = \
usr/include/apiclient.h usr/include/pkcs11types.h \
usr/include/pkcs11.h \
- usr/include/ec_curves.h
+ usr/include/ec_curves.h usr/include/pqc_oids.h
noinst_HEADERS += \
usr/include/apictl.h usr/include/local_types.h \
diff --git a/usr/include/pqc_oids.h b/usr/include/pqc_oids.h
new file mode 100644
index 00000000..0891373e
--- /dev/null
+++ b/usr/include/pqc_oids.h
@@ -0,0 +1,48 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2022
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+
+#ifndef _PQC_OIDS_H_
+#define _PQC_OIDS_H_
+
+/*
+ * OIDs and their DER encoding for the post-quantum crypto algorithms
+ * supported by OpenCryptoki:
+ */
+
+/* Dilithium Round 2 high-security (SHAKE-256): 1.3.6.1.4.1.2.267.1.6.5 */
+#define OCK_DILITHIUM_R2_65 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x01, 0x06, 0x05 }
+
+/* Dilithium Round 2 for outbound authentication: 1.3.6.1.4.1.2.267.1.8.7 */
+#define OCK_DILITHIUM_R2_87 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x01, 0x08, 0x07 }
+
+/* Dilithium Round 3 weak (SHAKE-256): 1.3.6.1.4.1.2.267.7.4.4 */
+#define OCK_DILITHIUM_R3_44 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x07, 0x04, 0x04 }
+
+/* Dilithium Round 3 recommended (SHAKE-256): 1.3.6.1.4.1.2.267.7.6.5 */
+#define OCK_DILITHIUM_R3_65 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x07, 0x06, 0x05 }
+
+/* Dilithium Round 3 high-security (SHAKE-256): 1.3.6.1.4.1.2.267.7.8.7 */
+#define OCK_DILITHIUM_R3_87 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x07, 0x08, 0x07 }
+
+/* Kyber Round 2 768 (SHAKE-128): 1.3.6.1.4.1.2.267.5.3.3 */
+#define OCK_KYBER_R2_768 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x05, 0x03, 0x03 }
+
+/* Kyber Round 2 1024 (SHAKE-128): 1.3.6.1.4.1.2.267.5.4.4 */
+#define OCK_KYBER_R2_1024 { 0x06, 0x0B, 0x2B, 0x06, 0x01, 0x04, \
+ 0x01, 0x02, 0x82, 0x0B, 0x05, 0x04, 0x04 }
+
+#endif // _PQC_OIDS_H_
diff --git a/usr/lib/common/common.mk b/usr/lib/common/common.mk
index 6341cb74..93f1e21f 100644
--- a/usr/lib/common/common.mk
+++ b/usr/lib/common/common.mk
@@ -7,4 +7,5 @@ noinst_HEADERS += \
usr/lib/common/p11util.h usr/lib/common/event_client.h \
usr/lib/common/list.h usr/lib/common/tok_specific.h \
usr/lib/common/uri_enc.h usr/lib/common/uri.h \
- usr/lib/common/buffer.h usr/lib/common/pin_prompt.h
+ usr/lib/common/buffer.h usr/lib/common/pin_prompt.h \
+ usr/lib/common/pqc_defs.h
diff --git a/usr/lib/common/globals.c b/usr/lib/common/globals.c
index db4d352c..5b79e785 100644
--- a/usr/lib/common/globals.c
+++ b/usr/lib/common/globals.c
@@ -27,6 +27,7 @@
#include "defs.h"
#include "host_defs.h"
#include "h_extern.h"
+#include "pqc_oids.h"
struct ST_FCN_LIST function_list;
diff --git a/usr/lib/common/pqc_defs.h b/usr/lib/common/pqc_defs.h
new file mode 100644
index 00000000..51ee1200
--- /dev/null
+++ b/usr/lib/common/pqc_defs.h
@@ -0,0 +1,48 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2022
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+#ifndef _PQC_DEFS
+#define _PQC_DEFS
+
+#include <stdio.h>
+
+#include "pqc_oids.h"
+
+extern const CK_BYTE dilithium_r2_65[];
+extern const CK_ULONG dilithium_r2_65_len;
+extern const CK_BYTE dilithium_r2_87[];
+extern const CK_ULONG dilithium_r2_87_len;
+extern const CK_BYTE dilithium_r3_44[];
+extern const CK_ULONG dilithium_r3_44_len;
+extern const CK_BYTE dilithium_r3_56[];
+extern const CK_ULONG dilithium_r3_56_len;
+extern const CK_BYTE dilithium_r3_87[];
+extern const CK_ULONG dilithium_r3_87_len;
+
+extern const CK_BYTE kyber_r2_768[];
+extern const CK_ULONG kyber_r2_768_len;
+extern const CK_BYTE kyber_r2_1024[];
+extern const CK_ULONG kyber_r2_1024_len;
+
+struct pqc_oid {
+ const CK_BYTE *oid;
+ CK_ULONG oid_len;
+ CK_ULONG keyform;
+};
+
+extern const struct pqc_oid dilithium_oids[];
+extern const struct pqc_oid kyber_oids[];
+
+const struct pqc_oid *find_pqc_by_keyform(const struct pqc_oid *pqcs,
+ CK_ULONG keyform);
+const struct pqc_oid *find_pqc_by_oid(const struct pqc_oid *pqcs,
+ CK_BYTE *oid, CK_ULONG oid_len);
+
+#endif
diff --git a/usr/lib/common/pqc_supported.c b/usr/lib/common/pqc_supported.c
new file mode 100644
index 00000000..4f048c33
--- /dev/null
+++ b/usr/lib/common/pqc_supported.c
@@ -0,0 +1,78 @@
+/*
+ * COPYRIGHT (c) International Business Machines Corp. 2022
+ *
+ * This program is provided under the terms of the Common Public License,
+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be
+ * found in the file LICENSE file or at
+ * https://opensource.org/licenses/cpl1.0.php
+ */
+
+#include <string.h>
+#include "pkcs11types.h"
+#include "pqc_defs.h"
+
+const CK_BYTE dilithium_r2_65[] = OCK_DILITHIUM_R2_65;
+const CK_ULONG dilithium_r2_65_len = sizeof(dilithium_r2_65);
+const CK_BYTE dilithium_r2_87[] = OCK_DILITHIUM_R2_87;
+const CK_ULONG dilithium_r2_87_len = sizeof(dilithium_r2_87);
+const CK_BYTE dilithium_r3_44[] = OCK_DILITHIUM_R3_44;
+const CK_ULONG dilithium_r3_44_len = sizeof(dilithium_r3_44);
+const CK_BYTE dilithium_r3_65[] = OCK_DILITHIUM_R3_65;
+const CK_ULONG dilithium_r3_65_len = sizeof(dilithium_r3_65);
+const CK_BYTE dilithium_r3_87[] = OCK_DILITHIUM_R3_87;
+const CK_ULONG dilithium_r3_87_len = sizeof(dilithium_r3_87);
+
+const struct pqc_oid dilithium_oids[] = {
+ { .oid = dilithium_r2_65, .oid_len = dilithium_r2_65_len,
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65 },
+ { .oid = dilithium_r2_87, .oid_len = dilithium_r2_87_len,
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_87 },
+ { .oid = dilithium_r3_44, .oid_len = dilithium_r3_44_len,
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_44 },
+ { .oid = dilithium_r3_65, .oid_len = dilithium_r3_65_len,
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_65 },
+ { .oid = dilithium_r3_87, .oid_len = dilithium_r3_87_len,
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_87 },
+ { .oid = NULL, .oid_len = 0, .keyform = 0 }
+};
+
+const CK_BYTE kyber_r2_768[] = OCK_KYBER_R2_768;
+const CK_ULONG kyber_r2_768_len = sizeof(kyber_r2_768);
+const CK_BYTE kyber_r2_1024[] = OCK_KYBER_R2_1024;
+const CK_ULONG kyber_r2_1024_len = sizeof(kyber_r2_1024);
+
+const struct pqc_oid kyber_oids[] = {
+ { .oid = kyber_r2_768, .oid_len = kyber_r2_768_len,
+ .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_768 },
+ { .oid = kyber_r2_1024, .oid_len = kyber_r2_1024_len,
+ .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_1024 },
+ { .oid = NULL, .oid_len = 0, .keyform = 0 }
+};
+
+const struct pqc_oid *find_pqc_by_keyform(const struct pqc_oid *pqcs,
+ CK_ULONG keyform)
+{
+ CK_ULONG i;
+
+ for (i = 0; pqcs[i].oid != NULL; i++) {
+ if (pqcs[i].keyform == keyform)
+ return &pqcs[i];
+ }
+
+ return NULL;
+}
+
+const struct pqc_oid *find_pqc_by_oid(const struct pqc_oid *pqcs,
+ CK_BYTE *oid, CK_ULONG oid_len)
+{
+ CK_ULONG i;
+
+ for (i = 0; pqcs[i].oid != NULL; i++) {
+ if (pqcs[i].oid_len == oid_len &&
+ memcmp(pqcs[i].oid, oid, oid_len) == 0)
+ return &pqcs[i];
+ }
+
+ return NULL;
+}
--
2.16.2.windows.1

View File

@ -1,604 +0,0 @@
From 76307be97a42f5a743e7cf0ef75a87dac0c0106f Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 13:04:24 +0100
Subject: [PATCH 19/34] COMMON: Dilithium key BER encoding/decoding allow
different OIDs
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/cca_stdll/cca_stdll.mk | 2 +-
usr/lib/common/asn1.c | 143 ++++++++++++++++++++-----------
usr/lib/common/globals.c | 8 +-
usr/lib/common/h_extern.h | 54 ++++++------
usr/lib/common/key.c | 10 ++-
usr/lib/common/key_mgr.c | 13 ++-
usr/lib/ep11_stdll/ep11_specific.c | 6 +-
usr/lib/ep11_stdll/ep11_stdll.mk | 3 +-
usr/lib/ica_s390_stdll/ica_s390_stdll.mk | 2 +-
usr/lib/icsf_stdll/icsf_stdll.mk | 2 +-
usr/lib/soft_stdll/soft_stdll.mk | 2 +-
usr/lib/tpm_stdll/tpm_stdll.mk | 2 +-
usr/sbin/pkcscca/pkcscca.mk | 2 +-
13 files changed, 152 insertions(+), 97 deletions(-)
diff --git a/usr/lib/cca_stdll/cca_stdll.mk b/usr/lib/cca_stdll/cca_stdll.mk
index 9b71085a..5963df59 100644
--- a/usr/lib/cca_stdll/cca_stdll.mk
+++ b/usr/lib/cca_stdll/cca_stdll.mk
@@ -41,7 +41,7 @@ opencryptoki_stdll_libpkcs11_cca_la_SOURCES = usr/lib/common/asn1.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
usr/lib/api/policyhelper.c usr/lib/config/configuration.c \
usr/lib/config/cfgparse.y usr/lib/config/cfglex.l \
- usr/lib/common/mech_openssl.c
+ usr/lib/common/mech_openssl.c usr/lib/common/pqc_supported.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_cca_la_SOURCES += \
diff --git a/usr/lib/common/asn1.c b/usr/lib/common/asn1.c
index b3f49c41..884ef489 100644
--- a/usr/lib/common/asn1.c
+++ b/usr/lib/common/asn1.c
@@ -24,6 +24,7 @@
#include "host_defs.h"
#include "h_extern.h"
#include "trace.h"
+#include "pqc_defs.h"
//
@@ -3616,7 +3617,7 @@ cleanup:
*
* SEQUENCE (2 elem)
* SEQUENCE (2 elem)
- * OBJECT IDENTIFIER 1.3.6.1.4.1.2.267.1.6.5
+ * OBJECT IDENTIFIER 1.3.6.1.4.1.2.267.xxx
* NULL
* BIT STRING (1 elem)
* SEQUENCE (2 elem)
@@ -3624,20 +3625,26 @@ cleanup:
* BIT STRING (13824 bit) = 1728 bytes
*/
CK_RV ber_encode_IBM_DilithiumPublicKey(CK_BBOOL length_only,
- CK_BYTE **data, CK_ULONG *data_len,
- CK_ATTRIBUTE *rho, CK_ATTRIBUTE *t1)
+ CK_BYTE **data, CK_ULONG *data_len,
+ const CK_BYTE *oid, CK_ULONG oid_len,
+ CK_ATTRIBUTE *rho, CK_ATTRIBUTE *t1)
{
CK_BYTE *buf = NULL, *buf2 = NULL, *buf3 = NULL, *buf4 = NULL;
- CK_ULONG len = 0, len4, offset, total, total_len;
+ CK_BYTE *buf5 = NULL, *algid = NULL;
+ CK_ULONG len = 0, len4, offset, total, total_len, algid_len;
CK_RV rc;
UNUSED(length_only);
offset = 0;
rc = 0;
- total_len = ber_AlgIdDilithiumLen;
+ total_len = 0;
total = 0;
+ /* Calculate storage for AlgID sequence */
+ rc |= ber_encode_SEQUENCE(TRUE, NULL, &total_len, NULL,
+ oid_len + ber_NULLLen);
+
/* Calculate storage for inner sequence */
rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, rho->ulValueLen);
offset += len;
@@ -3709,12 +3716,30 @@ CK_RV ber_encode_IBM_DilithiumPublicKey(CK_BBOOL length_only,
/*
* SEQUENCE (2 elem)
- * OBJECT IDENTIFIER 1.3.6.1.4.1.2.267.1.6.5
+ * OBJECT IDENTIFIER 1.3.6.1.4.1.2.267.xxx
* NULL <- no parms for this oid
*/
- total_len = 0;
- memcpy(buf3 + total_len, ber_AlgIdDilithium, ber_AlgIdDilithiumLen);
- total_len += ber_AlgIdDilithiumLen;
+ buf5 = (CK_BYTE *) malloc(oid_len + ber_NULLLen);
+ if (!buf5) {
+ TRACE_ERROR("%s Memory allocation failed\n", __func__);
+ rc = CKR_HOST_MEMORY;
+ goto error;
+ }
+ memcpy(buf5, oid, oid_len);
+ memcpy(buf5 + oid_len, ber_NULL, ber_NULLLen);
+
+ rc = ber_encode_SEQUENCE(FALSE, &algid, &algid_len, buf5,
+ oid_len + ber_NULLLen);
+ free(buf5);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ber_encode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
+ goto error;
+ }
+
+ total_len = algid_len;
+ memcpy(buf3, algid, algid_len);
+ free(algid);
+ algid = NULL;
/*
* BIT STRING (1 elem)
@@ -3760,16 +3785,15 @@ error:
CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
- CK_ULONG data_len,
- CK_ATTRIBUTE **rho_attr,
- CK_ATTRIBUTE **t1_attr)
+ CK_ULONG data_len,
+ CK_ATTRIBUTE **rho_attr,
+ CK_ATTRIBUTE **t1_attr)
{
CK_ATTRIBUTE *rho_attr_temp = NULL;
CK_ATTRIBUTE *t1_attr_temp = NULL;
- CK_BYTE *algid_DilithiumBase = NULL;
- CK_BYTE *algid = NULL;
- CK_ULONG algid_len;
+ CK_BYTE *algoid = NULL;
+ CK_ULONG algoid_len;
CK_BYTE *param = NULL;
CK_ULONG param_len;
CK_BYTE *val = NULL;
@@ -3780,26 +3804,20 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG rho_len;
CK_BYTE *t1;
CK_ULONG t1_len;
- CK_ULONG field_len, offset, len;
+ CK_ULONG field_len, offset;
CK_RV rc;
UNUSED(data_len); // XXX can this parameter be removed ?
- rc = ber_decode_SPKI(data, &algid, &algid_len, &param, &param_len,
+ rc = ber_decode_SPKI(data, &algoid, &algoid_len, &param, &param_len,
&val, &val_len);
if (rc != CKR_OK) {
TRACE_DEVEL("ber_decode_SPKI failed\n");
return rc;
}
- /* Make sure we're dealing with a Dilithium key */
- rc = ber_decode_SEQUENCE((CK_BYTE *)ber_AlgIdDilithium, &algid_DilithiumBase, &len,
- &field_len);
- if (rc != CKR_OK) {
- TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
- return rc;
- }
- if (memcmp(algid, algid_DilithiumBase, len) != 0) {
+ if (algoid_len != dilithium_r2_65_len ||
+ memcmp(algoid, dilithium_r2_65, dilithium_r2_65_len) != 0) {
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
@@ -3879,18 +3897,20 @@ cleanup:
* }
*/
CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
- CK_BYTE **data,
- CK_ULONG *data_len,
- CK_ATTRIBUTE *rho,
- CK_ATTRIBUTE *seed,
- CK_ATTRIBUTE *tr,
- CK_ATTRIBUTE *s1,
- CK_ATTRIBUTE *s2,
- CK_ATTRIBUTE *t0,
- CK_ATTRIBUTE *t1)
+ CK_BYTE **data,
+ CK_ULONG *data_len,
+ const CK_BYTE *oid, CK_ULONG oid_len,
+ CK_ATTRIBUTE *rho,
+ CK_ATTRIBUTE *seed,
+ CK_ATTRIBUTE *tr,
+ CK_ATTRIBUTE *s1,
+ CK_ATTRIBUTE *s2,
+ CK_ATTRIBUTE *t0,
+ CK_ATTRIBUTE *t1)
{
CK_BYTE *buf = NULL, *buf2 = NULL, *buf3 = NULL;
- CK_ULONG len, len2 = 0, offset;
+ CK_BYTE *algid = NULL, *algid_buf = NULL;
+ CK_ULONG len, len2 = 0, offset, algid_len = 0;
CK_BYTE version[] = { 0 };
CK_RV rc;
@@ -3898,6 +3918,9 @@ CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
offset = 0;
rc = 0;
+ rc |= ber_encode_SEQUENCE(TRUE, NULL, &algid_len, NULL,
+ oid_len + ber_NULLLen);
+
rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, sizeof(version));
offset += len;
rc |= ber_encode_BIT_STRING(TRUE, NULL, &len, NULL, rho->ulValueLen, 0);
@@ -3931,7 +3954,7 @@ CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
}
rc = ber_encode_PrivateKeyInfo(TRUE,
NULL, data_len,
- NULL, ber_AlgIdDilithiumLen,
+ NULL, algid_len,
NULL, len);
if (rc != CKR_OK) {
TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
@@ -4051,10 +4074,28 @@ CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
TRACE_ERROR("ber_encode_SEQUENCE failed\n");
goto error;
}
+
+ algid_buf = (CK_BYTE *) malloc(oid_len + ber_NULLLen);
+ if (!algid_buf) {
+ TRACE_ERROR("%s Memory allocation failed\n", __func__);
+ rc = CKR_HOST_MEMORY;
+ goto error;
+ }
+ memcpy(algid_buf, oid, oid_len);
+ memcpy(algid_buf + oid_len, ber_NULL, ber_NULLLen);
+
+ rc = ber_encode_SEQUENCE(FALSE, &algid, &algid_len, algid_buf,
+ oid_len + ber_NULLLen);
+ free(algid_buf);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ber_encode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
+ goto error;
+ }
+
rc = ber_encode_PrivateKeyInfo(FALSE,
data, data_len,
- ber_AlgIdDilithium,
- ber_AlgIdDilithiumLen, buf2, len);
+ algid, algid_len,
+ buf2, len);
if (rc != CKR_OK) {
TRACE_ERROR("ber_encode_PrivateKeyInfo failed\n");
}
@@ -4066,6 +4107,8 @@ error:
free(buf2);
if (buf)
free(buf);
+ if (algid)
+ free(algid);
return rc;
}
@@ -4087,19 +4130,19 @@ error:
* }
*/
CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
- CK_ULONG data_len,
- CK_ATTRIBUTE **rho,
- CK_ATTRIBUTE **seed,
- CK_ATTRIBUTE **tr,
- CK_ATTRIBUTE **s1,
- CK_ATTRIBUTE **s2,
- CK_ATTRIBUTE **t0,
- CK_ATTRIBUTE **t1)
+ CK_ULONG data_len,
+ CK_ATTRIBUTE **rho,
+ CK_ATTRIBUTE **seed,
+ CK_ATTRIBUTE **tr,
+ CK_ATTRIBUTE **s1,
+ CK_ATTRIBUTE **s2,
+ CK_ATTRIBUTE **t0,
+ CK_ATTRIBUTE **t1)
{
CK_ATTRIBUTE *rho_attr = NULL, *seed_attr = NULL;
CK_ATTRIBUTE *tr_attr = NULL, *s1_attr = NULL, *s2_attr = NULL;
CK_ATTRIBUTE *t0_attr = NULL, *t1_attr = NULL;
- CK_BYTE *alg = NULL;
+ CK_BYTE *algoid = NULL;
CK_BYTE *dilithium_priv_key = NULL;
CK_BYTE *buf = NULL;
CK_BYTE *tmp = NULL;
@@ -4107,15 +4150,15 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
CK_RV rc;
/* Check if this is a Dilithium private key */
- rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len,
+ rc = ber_decode_PrivateKeyInfo(data, data_len, &algoid, &len,
&dilithium_priv_key);
if (rc != CKR_OK) {
TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
return rc;
}
- if (memcmp(alg, ber_AlgIdDilithium, ber_AlgIdDilithiumLen) != 0) {
- // probably ought to use a different error
+ if (len != dilithium_r2_65_len + ber_NULLLen ||
+ memcmp(algoid, dilithium_r2_65, dilithium_r2_65_len) != 0) {
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
diff --git a/usr/lib/common/globals.c b/usr/lib/common/globals.c
index 5b79e785..a7197ec6 100644
--- a/usr/lib/common/globals.c
+++ b/usr/lib/common/globals.c
@@ -105,11 +105,7 @@ const CK_BYTE ber_AlgIdRSAEncryption[] = {
const CK_BYTE der_AlgIdECBase[] =
{ 0x30, 0x09, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 };
-const CK_BYTE ber_AlgIdDilithium[] =
- { 0x30, 0x0F, 0x06, 0x0B, 0x2B, 0x06, 0x01,
- 0x04, 0x01, 0x02, 0x82, 0x0B, 0x01, 0x06,
- 0x05, 0x05, 0x00
-};
+const CK_BYTE ber_NULL[] = { 0x05, 0x00 };
// ID Lengths
//
@@ -135,7 +131,7 @@ const CK_ULONG ber_AlgSha384Len = sizeof(ber_AlgSha384);
const CK_ULONG ber_AlgSha512Len = sizeof(ber_AlgSha512);
const CK_ULONG ber_AlgIdRSAEncryptionLen = sizeof(ber_AlgIdRSAEncryption);
const CK_ULONG der_AlgIdECBaseLen = sizeof(der_AlgIdECBase);
-const CK_ULONG ber_AlgIdDilithiumLen = sizeof(ber_AlgIdDilithium);
+const CK_ULONG ber_NULLLen = sizeof(ber_NULL);
const CK_ULONG des_weak_count = 4;
const CK_ULONG des_semi_weak_count = 12;
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index 340ab88d..41ca12df 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -56,16 +56,14 @@ extern const CK_BYTE ber_rsaEncryption[];
extern const CK_ULONG ber_rsaEncryptionLen;
extern const CK_BYTE der_AlgIdECBase[];
extern const CK_ULONG der_AlgIdECBaseLen;
-extern const CK_BYTE ber_AlgIdDilithium[];
-extern const CK_ULONG ber_AlgIdDilithiumLen;
extern const CK_BYTE ber_idDSA[];
extern const CK_ULONG ber_idDSALen;
extern const CK_BYTE ber_idDH[];
extern const CK_ULONG ber_idDHLen;
extern const CK_BYTE ber_idEC[];
extern const CK_ULONG ber_idECLen;
-extern const CK_BYTE ber_idDilithium[];
-extern const CK_ULONG ber_idDilithiumLen;
+extern const CK_BYTE ber_NULL[];
+extern const CK_ULONG ber_NULLLen;
#if !(NOMD2)
extern const CK_BYTE ber_md2WithRSAEncryption[];
@@ -2742,35 +2740,37 @@ CK_RV ber_decode_ECDHPrivateKey(CK_BYTE *data,
CK_ATTRIBUTE **pub_key,
CK_ATTRIBUTE **priv_key);
-CK_RV ber_encode_IBM_DilithiumPublicKey(CK_BBOOL length_only, CK_BYTE **data,
- CK_ULONG *data_len, CK_ATTRIBUTE *rho,
- CK_ATTRIBUTE *t1);
+CK_RV ber_encode_IBM_DilithiumPublicKey(CK_BBOOL length_only,
+ CK_BYTE **data, CK_ULONG *data_len,
+ const CK_BYTE *oid, CK_ULONG oid_len,
+ CK_ATTRIBUTE *rho, CK_ATTRIBUTE *t1);
CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
- CK_ULONG data_len,
- CK_ATTRIBUTE **rho_attr,
- CK_ATTRIBUTE **t1_attr);
+ CK_ULONG data_len,
+ CK_ATTRIBUTE **rho_attr,
+ CK_ATTRIBUTE **t1_attr);
CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
- CK_BYTE **data,
- CK_ULONG *data_len,
- CK_ATTRIBUTE *rho,
- CK_ATTRIBUTE *seed,
- CK_ATTRIBUTE *tr,
- CK_ATTRIBUTE *s1,
- CK_ATTRIBUTE *s2,
- CK_ATTRIBUTE *t0,
- CK_ATTRIBUTE *t1);
+ CK_BYTE **data,
+ CK_ULONG *data_len,
+ const CK_BYTE *oid, CK_ULONG oid_len,
+ CK_ATTRIBUTE *rho,
+ CK_ATTRIBUTE *seed,
+ CK_ATTRIBUTE *tr,
+ CK_ATTRIBUTE *s1,
+ CK_ATTRIBUTE *s2,
+ CK_ATTRIBUTE *t0,
+ CK_ATTRIBUTE *t1);
CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
- CK_ULONG data_len,
- CK_ATTRIBUTE **rho,
- CK_ATTRIBUTE **seed,
- CK_ATTRIBUTE **tr,
- CK_ATTRIBUTE **s1,
- CK_ATTRIBUTE **s2,
- CK_ATTRIBUTE **t0,
- CK_ATTRIBUTE **t1);
+ CK_ULONG data_len,
+ CK_ATTRIBUTE **rho,
+ CK_ATTRIBUTE **seed,
+ CK_ATTRIBUTE **tr,
+ CK_ATTRIBUTE **s1,
+ CK_ATTRIBUTE **s2,
+ CK_ATTRIBUTE **t0,
+ CK_ATTRIBUTE **t1);
typedef CK_RV (*t_rsa_encrypt)(STDLL_TokData_t *, CK_BYTE *in_data,
CK_ULONG in_data_len, CK_BYTE *out_data,
diff --git a/usr/lib/common/key.c b/usr/lib/common/key.c
index 6e9a839a..41857b97 100644
--- a/usr/lib/common/key.c
+++ b/usr/lib/common/key.c
@@ -81,6 +81,7 @@
#include "h_extern.h"
#include "attributes.h"
#include "trace.h"
+#include "pqc_defs.h"
#include "tok_spec_struct.h"
@@ -2688,7 +2689,10 @@ CK_RV ibm_dilithium_publ_get_spki(TEMPLATE *tmpl, CK_BBOOL length_only,
return rc;
}
- rc = ber_encode_IBM_DilithiumPublicKey(length_only, data,data_len, rho, t1);
+ rc = ber_encode_IBM_DilithiumPublicKey(length_only, data, data_len,
+ dilithium_r2_65,
+ dilithium_r2_65_len,
+ rho, t1);
if (rc != CKR_OK) {
TRACE_ERROR("ber_encode_IBM_DilithiumPublicKey failed.\n");
return rc;
@@ -2766,7 +2770,9 @@ CK_RV ibm_dilithium_priv_wrap_get_data(TEMPLATE *tmpl,
}
rc = ber_encode_IBM_DilithiumPrivateKey(length_only, data, data_len,
- rho, seed, tr, s1, s2, t0, t1);
+ dilithium_r2_65,
+ dilithium_r2_65_len,
+ rho, seed, tr, s1, s2, t0, t1);
if (rc != CKR_OK) {
TRACE_DEVEL("ber_encode_IBM_DilithiumPrivateKey failed\n");
}
diff --git a/usr/lib/common/key_mgr.c b/usr/lib/common/key_mgr.c
index 99f2a72e..01103dc2 100644
--- a/usr/lib/common/key_mgr.c
+++ b/usr/lib/common/key_mgr.c
@@ -35,6 +35,7 @@
#include "attributes.h"
#include "tok_spec_struct.h"
#include "trace.h"
+#include "pqc_defs.h"
#include "../api/policy.h"
#include "../api/statistics.h"
@@ -1368,7 +1369,7 @@ CK_RV key_mgr_get_private_key_type(CK_BYTE *keydata,
{
CK_BYTE *alg = NULL;
CK_BYTE *priv_key = NULL;
- CK_ULONG alg_len;
+ CK_ULONG alg_len, i;
CK_RV rc;
rc = ber_decode_PrivateKeyInfo(keydata, keylen, &alg, &alg_len, &priv_key);
@@ -1408,10 +1409,14 @@ CK_RV key_mgr_get_private_key_type(CK_BYTE *keydata,
return CKR_OK;
}
}
- // Check only the OBJECT IDENTIFIER for DILITHIUM
+ // Check only the OBJECT IDENTIFIERs for DILITHIUM
//
- if (alg_len >= ber_idDilithiumLen) {
- if (memcmp(alg, ber_idDilithium, ber_idDilithiumLen) == 0) {
+ for (i = 0; dilithium_oids[i].oid != NULL; i++) {
+ if (alg_len == dilithium_oids[i].oid_len + ber_NULLLen &&
+ memcmp(alg, dilithium_oids[i].oid,
+ dilithium_oids[i].oid_len) == 0 &&
+ memcmp(alg + dilithium_oids[i].oid_len,
+ ber_NULL, ber_NULLLen) == 0) {
*keytype = CKK_IBM_PQC_DILITHIUM;
return CKR_OK;
}
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index e3451163..45069ae8 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -37,6 +37,7 @@
#include "trace.h"
#include "ock_syslog.h"
#include "ec_defs.h"
+#include "pqc_defs.h"
#include "p11util.h"
#include "events.h"
#include "cfgparser.h"
@@ -3645,7 +3646,10 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
}
/* Encode the public key */
- rc = ber_encode_IBM_DilithiumPublicKey(0, &data, &data_len, rho, t1);
+ rc = ber_encode_IBM_DilithiumPublicKey(FALSE, &data, &data_len,
+ dilithium_r2_65,
+ dilithium_r2_65_len,
+ rho, t1);
if (rc != CKR_OK) {
TRACE_ERROR("%s public key import class=0x%lx rc=0x%lx "
"data_len=0x%lx\n", __func__, class, rc, data_len);
diff --git a/usr/lib/ep11_stdll/ep11_stdll.mk b/usr/lib/ep11_stdll/ep11_stdll.mk
index 9a8aa76a..11061f76 100644
--- a/usr/lib/ep11_stdll/ep11_stdll.mk
+++ b/usr/lib/ep11_stdll/ep11_stdll.mk
@@ -43,7 +43,8 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = usr/lib/common/asn1.c \
usr/lib/ep11_stdll/ep11_specific.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
usr/lib/api/policyhelper.c usr/lib/config/configuration.c \
- usr/lib/config/cfgparse.y usr/lib/config/cfglex.l
+ usr/lib/config/cfgparse.y usr/lib/config/cfglex.l \
+ usr/lib/common/pqc_supported.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_ep11_la_SOURCES += \
diff --git a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
index cb9d898f..f89cd343 100644
--- a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
+++ b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk
@@ -38,7 +38,7 @@ opencryptoki_stdll_libpkcs11_ica_la_SOURCES = \
usr/lib/ica_s390_stdll/ica_specific.c usr/lib/common/dlist.c \
usr/lib/common/mech_openssl.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
- usr/lib/api/policyhelper.c
+ usr/lib/api/policyhelper.c usr/lib/common/pqc_supported.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_ica_la_SOURCES += \
diff --git a/usr/lib/icsf_stdll/icsf_stdll.mk b/usr/lib/icsf_stdll/icsf_stdll.mk
index ee83f674..ebf24290 100644
--- a/usr/lib/icsf_stdll/icsf_stdll.mk
+++ b/usr/lib/icsf_stdll/icsf_stdll.mk
@@ -43,7 +43,7 @@ opencryptoki_stdll_libpkcs11_icsf_la_SOURCES = usr/lib/common/asn1.c \
usr/lib/icsf_stdll/icsf_specific.c \
usr/lib/icsf_stdll/icsf.c usr/lib/common/utility_common.c \
usr/lib/common/ec_supported.c usr/lib/api/policyhelper.c \
- usr/lib/config/configuration.c \
+ usr/lib/config/configuration.c usr/lib/common/pqc_supported.c \
usr/lib/config/cfgparse.y usr/lib/config/cfglex.l \
usr/lib/common/mech_openssl.c
diff --git a/usr/lib/soft_stdll/soft_stdll.mk b/usr/lib/soft_stdll/soft_stdll.mk
index 6cdf82b8..7a842ddc 100644
--- a/usr/lib/soft_stdll/soft_stdll.mk
+++ b/usr/lib/soft_stdll/soft_stdll.mk
@@ -36,7 +36,7 @@ opencryptoki_stdll_libpkcs11_sw_la_SOURCES = \
usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c \
usr/lib/common/dlist.c usr/lib/common/mech_openssl.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
- usr/lib/api/policyhelper.c
+ usr/lib/api/policyhelper.c usr/lib/common/pqc_supported.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_sw_la_SOURCES += \
diff --git a/usr/lib/tpm_stdll/tpm_stdll.mk b/usr/lib/tpm_stdll/tpm_stdll.mk
index 54551c1f..7fa18121 100644
--- a/usr/lib/tpm_stdll/tpm_stdll.mk
+++ b/usr/lib/tpm_stdll/tpm_stdll.mk
@@ -38,7 +38,7 @@ opencryptoki_stdll_libpkcs11_tpm_la_SOURCES = \
usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c \
usr/lib/common/dlist.c usr/lib/common/mech_openssl.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
- usr/lib/api/policyhelper.c
+ usr/lib/api/policyhelper.c usr/lib/common/pqc_supported.c
if ENABLE_LOCKS
opencryptoki_stdll_libpkcs11_tpm_la_SOURCES += \
diff --git a/usr/sbin/pkcscca/pkcscca.mk b/usr/sbin/pkcscca/pkcscca.mk
index 187a93f2..59300ef5 100644
--- a/usr/sbin/pkcscca/pkcscca.mk
+++ b/usr/sbin/pkcscca/pkcscca.mk
@@ -41,7 +41,7 @@ usr_sbin_pkcscca_pkcscca_SOURCES = usr/lib/common/asn1.c \
usr/lib/common/dlist.c usr/sbin/pkcscca/pkcscca.c \
usr/lib/common/utility_common.c usr/lib/common/ec_supported.c \
usr/lib/common/pin_prompt.c usr/lib/common/mech_openssl.c \
- usr/lib/api/policyhelper.c
+ usr/lib/api/policyhelper.c usr/lib/common/pqc_supported.c
nodist_usr_sbin_pkcscca_pkcscca_SOURCES = usr/lib/api/mechtable.c
--
2.16.2.windows.1

View File

@ -1,815 +0,0 @@
From 108b7ea5f8b8eedf3ad56b014b6807fc1a0c692c Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 16 Feb 2022 16:20:41 +0100
Subject: [PATCH 20/34] COMMON/EP11: Add CKA_VALUE holding SPKI/PKCS#8 of key
for Dilithium keys
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/common/asn1.c | 41 ++++++-
usr/lib/common/h_extern.h | 11 +-
usr/lib/common/key.c | 167 +++++++++++++++++++++----
usr/lib/ep11_stdll/ep11_specific.c | 245 ++++++++++++++-----------------------
4 files changed, 274 insertions(+), 190 deletions(-)
diff --git a/usr/lib/common/asn1.c b/usr/lib/common/asn1.c
index 884ef489..dbf06dfd 100644
--- a/usr/lib/common/asn1.c
+++ b/usr/lib/common/asn1.c
@@ -3787,10 +3787,12 @@ error:
CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG data_len,
CK_ATTRIBUTE **rho_attr,
- CK_ATTRIBUTE **t1_attr)
+ CK_ATTRIBUTE **t1_attr,
+ CK_ATTRIBUTE **value_attr)
{
CK_ATTRIBUTE *rho_attr_temp = NULL;
CK_ATTRIBUTE *t1_attr_temp = NULL;
+ CK_ATTRIBUTE *value_attr_temp = NULL;
CK_BYTE *algoid = NULL;
CK_ULONG algoid_len;
@@ -3804,7 +3806,7 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG rho_len;
CK_BYTE *t1;
CK_ULONG t1_len;
- CK_ULONG field_len, offset;
+ CK_ULONG field_len, offset, raw_spki_len;
CK_RV rc;
UNUSED(data_len); // XXX can this parameter be removed ?
@@ -3866,8 +3868,21 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
goto cleanup;
}
+ /* Add raw SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
+ rc = ber_decode_SEQUENCE(data, &val, &val_len, &raw_spki_len);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
+ goto cleanup;
+ }
+ rc = build_attribute(CKA_VALUE, data, raw_spki_len, &value_attr_temp);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("build_attribute failed\n");
+ goto cleanup;
+ }
+
*rho_attr = rho_attr_temp;
*t1_attr = t1_attr_temp;
+ *value_attr = value_attr_temp;
return CKR_OK;
@@ -3876,6 +3891,8 @@ cleanup:
free(rho_attr_temp);
if (t1_attr_temp)
free(t1_attr_temp);
+ if (value_attr_temp)
+ free(value_attr_temp);
return rc;
}
@@ -4137,11 +4154,12 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
CK_ATTRIBUTE **s1,
CK_ATTRIBUTE **s2,
CK_ATTRIBUTE **t0,
- CK_ATTRIBUTE **t1)
+ CK_ATTRIBUTE **t1,
+ CK_ATTRIBUTE **value)
{
CK_ATTRIBUTE *rho_attr = NULL, *seed_attr = NULL;
CK_ATTRIBUTE *tr_attr = NULL, *s1_attr = NULL, *s2_attr = NULL;
- CK_ATTRIBUTE *t0_attr = NULL, *t1_attr = NULL;
+ CK_ATTRIBUTE *t0_attr = NULL, *t1_attr = NULL, *value_attr = NULL;
CK_BYTE *algoid = NULL;
CK_BYTE *dilithium_priv_key = NULL;
CK_BYTE *buf = NULL;
@@ -4314,6 +4332,18 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
goto cleanup;
}
+ /* Add private key as CKA_VALUE to public key (z/OS ICSF compatibility) */
+ rc = ber_decode_SEQUENCE(data, &tmp, &len, &field_len);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ber_decode_SEQUENCE failed with rc=0x%lx\n", __func__, rc);
+ goto cleanup;
+ }
+ rc = build_attribute(CKA_VALUE, data, field_len, &value_attr);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("build_attribute for (t1) failed\n");
+ goto cleanup;
+ }
+
*rho = rho_attr;
*seed = seed_attr;
*tr = tr_attr;
@@ -4321,6 +4351,7 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
*s2 = s2_attr;
*t0 = t0_attr;
*t1 = t1_attr;
+ *value = value_attr;
return CKR_OK;
@@ -4340,6 +4371,8 @@ cleanup:
free(s2_attr);
if (t0_attr)
free(t0_attr);
+ if (value_attr)
+ free(value_attr);
return rc;
}
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index 41ca12df..53909e99 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -2500,9 +2500,10 @@ CK_RV ibm_dilithium_priv_validate_attribute(STDLL_TokData_t *tokdata, TEMPLATE *
CK_RV ibm_dilithium_priv_wrap_get_data(TEMPLATE *tmpl, CK_BBOOL length_only,
CK_BYTE **data, CK_ULONG *data_len);
CK_RV ibm_dilithium_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data,
- CK_ULONG total_length);
+ CK_ULONG total_length, CK_BBOOL add_value);
CK_RV ibm_dilithium_priv_unwrap_get_data(TEMPLATE *tmpl,
- CK_BYTE *data, CK_ULONG total_length);
+ CK_BYTE *data, CK_ULONG total_length,
+ CK_BBOOL add_value);
// diffie-hellman routines
//
@@ -2748,7 +2749,8 @@ CK_RV ber_encode_IBM_DilithiumPublicKey(CK_BBOOL length_only,
CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG data_len,
CK_ATTRIBUTE **rho_attr,
- CK_ATTRIBUTE **t1_attr);
+ CK_ATTRIBUTE **t1_attr,
+ CK_ATTRIBUTE **value_attr);
CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
CK_BYTE **data,
@@ -2770,7 +2772,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
CK_ATTRIBUTE **s1,
CK_ATTRIBUTE **s2,
CK_ATTRIBUTE **t0,
- CK_ATTRIBUTE **t1);
+ CK_ATTRIBUTE **t1,
+ CK_ATTRIBUTE **value);
typedef CK_RV (*t_rsa_encrypt)(STDLL_TokData_t *, CK_BYTE *in_data,
CK_ULONG in_data_len, CK_BYTE *out_data,
diff --git a/usr/lib/common/key.c b/usr/lib/common/key.c
index 41857b97..b0050816 100644
--- a/usr/lib/common/key.c
+++ b/usr/lib/common/key.c
@@ -1051,7 +1051,7 @@ CK_RV priv_key_unwrap(TEMPLATE *tmpl,
rc = ec_priv_unwrap(tmpl, data, data_len);
break;
case CKK_IBM_PQC_DILITHIUM:
- rc = ibm_dilithium_priv_unwrap(tmpl, data, data_len);
+ rc = ibm_dilithium_priv_unwrap(tmpl, data, data_len, TRUE);
break;
default:
TRACE_ERROR("%s\n", ock_err(ERR_WRAPPED_KEY_INVALID));
@@ -2781,13 +2781,16 @@ CK_RV ibm_dilithium_priv_wrap_get_data(TEMPLATE *tmpl,
}
CK_RV ibm_dilithium_priv_unwrap_get_data(TEMPLATE *tmpl, CK_BYTE *data,
- CK_ULONG total_length)
+ CK_ULONG total_length,
+ CK_BBOOL add_value)
{
CK_ATTRIBUTE *rho = NULL;
CK_ATTRIBUTE *t1 = NULL;
+ CK_ATTRIBUTE *value = NULL;
CK_RV rc;
- rc = ber_decode_IBM_DilithiumPublicKey(data, total_length, &rho, &t1);
+ rc = ber_decode_IBM_DilithiumPublicKey(data, total_length, &rho, &t1,
+ &value);
if (rc != CKR_OK) {
TRACE_ERROR("ber_decode_DilithiumPublicKey failed\n");
return rc;
@@ -2805,6 +2808,16 @@ CK_RV ibm_dilithium_priv_unwrap_get_data(TEMPLATE *tmpl, CK_BYTE *data,
goto error;
}
t1 = NULL;
+ if (add_value) {
+ rc = template_update_attribute(tmpl, value);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("template_update_attribute failed.\n");
+ goto error;
+ }
+ } else {
+ free(value);
+ }
+ value = NULL;
return CKR_OK;
@@ -2813,6 +2826,8 @@ error:
free(rho);
if (t1)
free(t1);
+ if (value)
+ free(value);
return rc;
}
@@ -2820,14 +2835,15 @@ error:
//
//
CK_RV ibm_dilithium_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data,
- CK_ULONG total_length)
+ CK_ULONG total_length, CK_BBOOL add_value)
{
- CK_ATTRIBUTE *rho = NULL, *seed = NULL, *tr = NULL;
+ CK_ATTRIBUTE *rho = NULL, *seed = NULL, *tr = NULL, *value = NULL;
CK_ATTRIBUTE *s1 = NULL, *s2 = NULL, *t0 = NULL, *t1 = NULL;
CK_RV rc;
rc = ber_decode_IBM_DilithiumPrivateKey(data, total_length,
- &rho, &seed, &tr, &s1, &s2, &t0, &t1);
+ &rho, &seed, &tr, &s1, &s2, &t0,
+ &t1, &value);
if (rc != CKR_OK) {
TRACE_ERROR("der_decode_IBM_DilithiumPrivateKey failed\n");
return rc;
@@ -2877,6 +2893,16 @@ CK_RV ibm_dilithium_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data,
}
}
t1 = NULL;
+ if (add_value) {
+ rc = template_update_attribute(tmpl, value);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("template_update_attribute failed.\n");
+ goto error;
+ }
+ } else {
+ free(value);
+ }
+ value = NULL;
return CKR_OK;
@@ -2895,6 +2921,8 @@ error:
free(t0);
if (t1)
free(t1);
+ if (value)
+ free(value);
return rc;
}
@@ -4633,6 +4661,7 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
CK_ATTRIBUTE *rho_attr = NULL;
CK_ATTRIBUTE *t1_attr = NULL;
CK_ATTRIBUTE *keyform_attr = NULL;
+ CK_ATTRIBUTE *value_attr = NULL;
CK_RV rc;
publ_key_set_default_attributes(tmpl, mode);
@@ -4641,8 +4670,9 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
keyform_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
rho_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
t1_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
+ value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
- if (!type_attr || !rho_attr || !t1_attr || !keyform_attr) {
+ if (!type_attr || !rho_attr || !t1_attr || !keyform_attr || !value_attr) {
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
rc = CKR_HOST_MEMORY;
goto error;
@@ -4666,6 +4696,10 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
t1_attr->ulValueLen = 0;
t1_attr->pValue = NULL;
+ value_attr->type = CKA_VALUE;
+ value_attr->ulValueLen = 0;
+ value_attr->pValue = NULL;
+
rc = template_update_attribute(tmpl, type_attr);
if (rc != CKR_OK) {
TRACE_ERROR("template_update_attribute failed\n");
@@ -4690,6 +4724,12 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
goto error;
}
keyform_attr = NULL;
+ rc = template_update_attribute(tmpl, value_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("template_update_attribute failed\n");
+ goto error;
+ }
+ value_attr = NULL;
return CKR_OK;
@@ -4702,6 +4742,8 @@ error:
free(t1_attr);
if (keyform_attr)
free(keyform_attr);
+ if (value_attr)
+ free(value_attr);
return rc;
}
@@ -4719,6 +4761,7 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
CK_ATTRIBUTE *t0_attr = NULL;
CK_ATTRIBUTE *t1_attr = NULL;
CK_ATTRIBUTE *keyform_attr = NULL;
+ CK_ATTRIBUTE *value_attr = NULL;
CK_RV rc;
priv_key_set_default_attributes(tmpl, mode);
@@ -4732,9 +4775,10 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
s2_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
t0_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
t1_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
+ value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
if (!type_attr || !rho_attr || !seed_attr || !tr_attr || !s1_attr
- || !s2_attr || !t0_attr || !t1_attr || !keyform_attr) {
+ || !s2_attr || !t0_attr || !t1_attr || !keyform_attr || !value_attr) {
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
rc = CKR_HOST_MEMORY;
goto error;
@@ -4778,6 +4822,10 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
t1_attr->ulValueLen = 0;
t1_attr->pValue = NULL;
+ value_attr->type = CKA_VALUE;
+ value_attr->ulValueLen = 0;
+ value_attr->pValue = NULL;
+
rc = template_update_attribute(tmpl, type_attr);
if (rc != CKR_OK) {
TRACE_ERROR("template_update_attribute failed\n");
@@ -4832,6 +4880,12 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
goto error;
}
t1_attr = NULL;
+ rc = template_update_attribute(tmpl, value_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("template_update_attribute failed\n");
+ goto error;
+ }
+ value_attr = NULL;
return CKR_OK;
@@ -4854,6 +4908,8 @@ error:
free(t1_attr);
if (keyform_attr)
free(keyform_attr);
+ if (value_attr)
+ free(value_attr);
return rc;
}
@@ -4869,18 +4925,46 @@ CK_RV ibm_dilithium_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode
CKA_IBM_DILITHIUM_T1,
};
CK_ULONG i;
+ CK_RV rc;
- /* MODE_KEYGEN: attrs are added during keygen */
- if (mode == MODE_KEYGEN || mode == MODE_UNWRAP)
- return publ_key_check_required_attributes(tmpl, mode);
-
- /* MODE_CREATE (key import) or MODE_COPY: check if all attrs present */
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
- if (!(template_attribute_find(tmpl, req_attrs[i], &attr))) {
- TRACE_ERROR("%s, attribute %08lX missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ switch (mode) {
+ case MODE_KEYGEN:
+ case MODE_UNWRAP:
+ /* Attrs will be added during keygen/unwrap */
+ break;
+ case MODE_CREATE:
+ /* Either CKA_VALUE or all other attrs must be present */
+ if (template_attribute_find(tmpl, CKA_VALUE, &attr) &&
+ attr->ulValueLen > 0 && attr->pValue != NULL)
+ break;
+ for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
+ rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
+ if (rc != CKR_OK) {
+ if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
+ TRACE_ERROR("%s, attribute %08lX missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ return rc;
+ }
+ }
+ break;
+ case MODE_COPY:
+ /* CKA_VALUE and all other attrs must be present */
+ if (!template_attribute_find(tmpl, CKA_VALUE, &attr) &&
+ attr->ulValueLen > 0 && attr->pValue != NULL) {
+ TRACE_ERROR("%s, attribute CKA_VALUE missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE));
return CKR_TEMPLATE_INCOMPLETE;
}
+ for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
+ rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
+ if (rc != CKR_OK) {
+ if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
+ TRACE_ERROR("%s, attribute %08lX missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ return rc;
+ }
+ }
+ break;
}
/* All required attrs found, check them */
@@ -4903,18 +4987,47 @@ CK_RV ibm_dilithium_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode
CKA_IBM_DILITHIUM_T1,
};
CK_ULONG i;
+ CK_RV rc;
- /* MODE_KEYGEN: attrs are added during keygen */
- if (mode == MODE_KEYGEN || mode == MODE_UNWRAP)
- return priv_key_check_required_attributes(tmpl, mode);
-
- /* MODE_CREATE (key import) or MODE_COPY: check if all attrs present */
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
- if (!(template_attribute_find(tmpl, req_attrs[i], &attr))) {
- TRACE_ERROR("%s, attribute %08lX missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ switch (mode) {
+ case MODE_KEYGEN:
+ case MODE_UNWRAP:
+ /* Attrs will be added during keygen/unwrap */
+ break;
+ case MODE_CREATE:
+ /* Either CKA_VALUE or all other attrs must be present */
+ if (template_attribute_find(tmpl, CKA_VALUE, &attr) &&
+ attr->ulValueLen > 0 && attr->pValue != NULL)
+ break;
+ for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
+ rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
+ if (rc != CKR_OK) {
+ if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
+ TRACE_ERROR("%s, attribute %08lX missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ return rc;
+ }
+ }
+ break;
+ case MODE_COPY:
+ /* CKA_VALUE and all other attrs must be present */
+ if (!template_attribute_find(tmpl, CKA_VALUE, &attr) &&
+ attr->ulValueLen > 0 && attr->pValue != NULL) {
+ TRACE_ERROR("%s, attribute CKA_VALUE missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE));
return CKR_TEMPLATE_INCOMPLETE;
+
+ }
+ for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
+ rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
+ if (rc != CKR_OK) {
+ if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
+ TRACE_ERROR("%s, attribute %08lX missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ return rc;
+ }
}
+ break;
}
/* All required attrs found, check them */
@@ -4930,6 +5043,7 @@ CK_RV ibm_dilithium_publ_validate_attribute(STDLL_TokData_t *tokdata,
switch (attr->type) {
case CKA_IBM_DILITHIUM_RHO:
case CKA_IBM_DILITHIUM_T1:
+ case CKA_VALUE:
if (mode == MODE_CREATE)
return CKR_OK;
TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
@@ -4969,6 +5083,7 @@ CK_RV ibm_dilithium_priv_validate_attribute(STDLL_TokData_t *tokdata,
case CKA_IBM_DILITHIUM_S2:
case CKA_IBM_DILITHIUM_T0:
case CKA_IBM_DILITHIUM_T1:
+ case CKA_VALUE:
if (mode == MODE_CREATE)
return CKR_OK;
TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 45069ae8..9221b8cd 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -3585,6 +3585,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
+ CK_ATTRIBUTE *value_attr = NULL;
+ CK_BBOOL data_alloced = TRUE;
memcpy(iv, "1234567812345678", AES_BLOCK_SIZE);
@@ -3606,57 +3608,55 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
if (class != CKO_PRIVATE_KEY) {
-
/* Make an SPKI for the public IBM Dilithium key */
- CK_ULONG keyform;
- CK_ATTRIBUTE *rho;
- CK_ATTRIBUTE *t1;
-
- /* A public IBM Dilithium key must have a keyform value */
- rc = template_attribute_get_ulong(dilithium_key_obj->template,
- CKA_IBM_DILITHIUM_KEYFORM,
- &keyform);
- if (rc != CKR_OK) {
- TRACE_ERROR("Could not find CKA_IBM_DILITHIUM_KEYFORM for the "
- "key.\n");
- goto done;
- }
-
- /* Check if it's an expected keyform */
- if (keyform != IBM_DILITHIUM_KEYFORM_ROUND2) {
- TRACE_ERROR("Keyform is not supported\n");
- rc = CKR_TEMPLATE_INCONSISTENT;
- goto done;
- }
- /* A public IBM Dilithium key must have a rho value */
- rc = template_attribute_get_non_empty(dilithium_key_obj->template,
- CKA_IBM_DILITHIUM_RHO, &rho);
- if (rc != CKR_OK) {
- TRACE_ERROR("Could not find CKA_IBM_DILITHIUM_RHO for the key.\n");
- goto done;
- }
+ /* A public IBM Dilithium key must either have a CKA_VALUE containing
+ * the SPKI, or must have a keyform value and the individual attributes
+ */
+ if (template_attribute_find(dilithium_key_obj->template,
+ CKA_VALUE, &value_attr) &&
+ value_attr->ulValueLen > 0 && value_attr ->pValue != NULL) {
+ /* CKA_VALUE with SPKI */
+ data = value_attr ->pValue;
+ data_len = value_attr->ulValueLen;
+ data_alloced = FALSE;
+
+ /* Decode SPKI and add public key attributes */
+ rc = ibm_dilithium_priv_unwrap_get_data(dilithium_key_obj->template,
+ data, data_len, FALSE);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to decode SPKI from CKA_VALUE.\n");
+ goto done;
+ }
+ } else {
+ /* Individual attributes */
+ rc = ibm_dilithium_publ_get_spki(dilithium_key_obj->template,
+ FALSE, &data, &data_len);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s public key import class=0x%lx rc=0x%lx "
+ "data_len=0x%lx\n", __func__, class, rc, data_len);
+ goto done;
+ } else {
+ TRACE_INFO("%s public key import class=0x%lx rc=0x%lx "
+ "data_len=0x%lx\n", __func__, class, rc, data_len);
+ }
- /* A public IBM Dilithium key must have a t1 value */
- rc = template_attribute_get_non_empty(dilithium_key_obj->template,
- CKA_IBM_DILITHIUM_T1, &t1);
- if (rc != CKR_OK) {
- TRACE_ERROR("Could not find CKA_IBM_DILITHIUM_T1 for the key.\n");
- goto done;
- }
+ /* Add SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
+ rc = build_attribute(CKA_VALUE, data, data_len, &value_attr);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("build_attribute failed\n");
+ goto done;
+ }
- /* Encode the public key */
- rc = ber_encode_IBM_DilithiumPublicKey(FALSE, &data, &data_len,
- dilithium_r2_65,
- dilithium_r2_65_len,
- rho, t1);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s public key import class=0x%lx rc=0x%lx "
- "data_len=0x%lx\n", __func__, class, rc, data_len);
- goto done;
- } else {
- TRACE_INFO("%s public key import class=0x%lx rc=0x%lx "
- "data_len=0x%lx\n", __func__, class, rc, data_len);
+ rc = template_update_attribute(dilithium_key_obj->template,
+ value_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(value_attr);
+ goto done;
+ }
+ value_attr = NULL;
}
/* save the SPKI as blob although it is not a blob.
@@ -3676,14 +3676,35 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* imported private IBM Dilithium key goes here */
- /* extract the secret data to be wrapped
- * since this is AES_CBC_PAD, padding is done in mechanism.
+ /* A public IBM Dilithium key must either have a CKA_VALUE containing
+ * the PKCS#8 encoded private key, or must have a keyform value and the
+ * individual attributes
*/
- rc = ibm_dilithium_priv_wrap_get_data(dilithium_key_obj->template, FALSE,
- &data, &data_len);
- if (rc != CKR_OK) {
- TRACE_DEVEL("%s Dilithium wrap get data failed\n", __func__);
- goto done;
+ if (template_attribute_find(dilithium_key_obj->template,
+ CKA_VALUE, &value_attr) &&
+ value_attr->ulValueLen > 0 && value_attr ->pValue != NULL) {
+ /* CKA_VALUE with SPKI */
+ data = value_attr ->pValue;
+ data_len = value_attr->ulValueLen;
+ data_alloced = FALSE;
+
+ /* Decode PKCS#8 private key and add key attributes */
+ rc = ibm_dilithium_priv_unwrap(dilithium_key_obj->template,
+ data, data_len, FALSE);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to decode private key from CKA_VALUE.\n");
+ goto done;
+ }
+ } else {
+ /* extract the secret data to be wrapped
+ * since this is AES_CBC_PAD, padding is done in mechanism.
+ */
+ rc = ibm_dilithium_priv_wrap_get_data(dilithium_key_obj->template,
+ FALSE, &data, &data_len);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("%s Dilithium wrap get data failed\n", __func__);
+ goto done;
+ }
}
/* encrypt */
@@ -3743,10 +3764,15 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
}
cleanse_attribute(dilithium_key_obj->template, CKA_VALUE);
+ cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_SEED);
+ cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_TR);
+ cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_S1);
+ cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_S2);
+ cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_T0);
}
done:
- if (data) {
+ if (data_alloced && data) {
OPENSSL_cleanse(data, data_len);
free(data);
}
@@ -6422,16 +6448,10 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
size_t privkey_blob_len = sizeof(privkey_blob);
unsigned char spki[MAX_BLOBSIZE];
size_t spki_len = sizeof(spki);
- CK_ULONG bit_str_len;
- CK_BYTE *key;
- CK_BYTE *data, *oid, *parm;
- CK_ULONG data_len, oid_len, parm_len;
- CK_ULONG field_len;
CK_ULONG ktype = CKK_IBM_PQC_DILITHIUM;
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
- CK_BYTE *rho, *t1;
CK_ATTRIBUTE *new_publ_attrs = NULL, *new_priv_attrs = NULL;
CK_ULONG new_publ_attrs_len = 0, new_priv_attrs_len = 0;
CK_ATTRIBUTE *new_publ_attrs2 = NULL, *new_priv_attrs2 = NULL;
@@ -6567,105 +6587,17 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
goto error;
}
- /* Decode SPKI */
- rc = ber_decode_SPKI(spki, &oid, &oid_len, &parm, &parm_len, &key,
- &bit_str_len);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s read key from SPKI failed with rc=0x%lx\n", __func__,
- rc);
- goto error;
- }
-
- /* Public key must be a sequence holding two bit-strings: (rho, t1) */
- rc = ber_decode_SEQUENCE(key, &data, &data_len, &field_len);
+ rc = ibm_dilithium_priv_unwrap_get_data(publ_tmpl, spki, spki_len, TRUE);
if (rc != CKR_OK) {
- TRACE_ERROR("%s read sequence failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
-
- /* Decode rho */
- rho = key + field_len - data_len;
- rc = ber_decode_BIT_STRING(rho, &data, &data_len, &field_len);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s read rho failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- /* Remove leading unused-bits byte, returned by ber_decode_BIT_STRING */
- data++;
- data_len--;
-#ifdef DEBUG
- TRACE_DEBUG("%s dilithium_generate_keypair (rho):\n", __func__);
- TRACE_DEBUG_DUMP(" ", data, data_len);
-#endif
-
- /* build and add CKA_IBM_DILITHIUM_RHO for public key */
- rc = build_attribute(CKA_IBM_DILITHIUM_RHO, data, data_len, &attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- rc = template_update_attribute(publ_tmpl, attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
- goto error;
- }
-
- /* build and add CKA_IBM_DILITHIUM_RHO for private key */
- rc = build_attribute(CKA_IBM_DILITHIUM_RHO, data, data_len, &attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- rc = template_update_attribute(priv_tmpl, attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
- goto error;
- }
-
- /* Decode t1 */
- t1 = rho + field_len;
- rc = ber_decode_BIT_STRING(t1, &data, &data_len, &field_len);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s read t failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- /* Remove leading unused-bits byte, returned by ber_decode_BIT_STRING */
- data++;
- data_len--;
-#ifdef DEBUG
- TRACE_DEBUG("%s dilithium_generate_keypair (t1):\n", __func__);
- TRACE_DEBUG_DUMP(" ", data, data_len);
-#endif
-
- /* build and add CKA_IBM_DILITHIUM_T1 for public key */
- rc = build_attribute(CKA_IBM_DILITHIUM_T1, data, data_len, &attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- rc = template_update_attribute(publ_tmpl, attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s ibm_dilithium_priv_unwrap_get_data with rc=0x%lx\n",
+ __func__, rc);
goto error;
}
- /* build and add CKA_IBM_DILITHIUM_T1 for private key */
- rc = build_attribute(CKA_IBM_DILITHIUM_T1, data, data_len, &attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n", __func__, rc);
- goto error;
- }
- rc = template_update_attribute(priv_tmpl, attr);
+ rc = ibm_dilithium_priv_unwrap_get_data(priv_tmpl, spki, spki_len, FALSE);
if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
- __func__, rc);
- free(attr);
+ TRACE_ERROR("%s ibm_dilithium_priv_unwrap_get_data with rc=0x%lx\n",
+ __func__, rc);
goto error;
}
@@ -9043,7 +8975,8 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
rc = dh_priv_unwrap_get_data(key_obj->template, csum, cslen);
break;
case CKK_IBM_PQC_DILITHIUM:
- rc = ibm_dilithium_priv_unwrap_get_data(key_obj->template, csum, cslen);
+ rc = ibm_dilithium_priv_unwrap_get_data(key_obj->template,
+ csum, cslen, FALSE);
break;
}
--
2.16.2.windows.1

View File

@ -1,994 +0,0 @@
From 57cd8cd4db0d68c08b123b669f1cf57bed0fe34d Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Thu, 17 Feb 2022 10:27:56 +0100
Subject: [PATCH 21/34] COMMON/EP11: Allow to select Dilithium variant via mode
or key form attribute
Attributes CKA_IBM_DILITHIUM_KEYFORM or CKA_IBM_DILITHIUM_MODE can
be used to select the Dilithium variant to use.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
testcases/common/common.c | 4 +-
usr/lib/common/asn1.c | 20 +-
usr/lib/common/h_extern.h | 11 +-
usr/lib/common/key.c | 443 +++++++++++++++++++++++--------------
usr/lib/ep11_stdll/ep11_specific.c | 84 +++++--
5 files changed, 375 insertions(+), 187 deletions(-)
diff --git a/testcases/common/common.c b/testcases/common/common.c
index 8ec5043b..fac9e4e6 100644
--- a/testcases/common/common.c
+++ b/testcases/common/common.c
@@ -629,7 +629,7 @@ CK_RV create_DilithiumPrivateKey(CK_SESSION_HANDLE session,
CK_UTF8CHAR label[] = "A Dilithium private key object";
CK_BYTE subject[] = {0};
CK_BYTE id[] = { 123 };
- CK_ULONG keyform = IBM_DILITHIUM_KEYFORM_ROUND2;
+ CK_ULONG keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65;
CK_RV rc;
CK_BBOOL true = TRUE;
@@ -678,7 +678,7 @@ CK_RV create_DilithiumPublicKey(CK_SESSION_HANDLE session,
CK_KEY_TYPE keyType = CKK_IBM_PQC_DILITHIUM;
CK_UTF8CHAR label[] = "A Dilithium public key object";
CK_BBOOL true = TRUE;
- CK_ULONG keyform = IBM_DILITHIUM_KEYFORM_ROUND2;
+ CK_ULONG keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65;
CK_ATTRIBUTE template[] = {
{CKA_CLASS, &class, sizeof(class)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
diff --git a/usr/lib/common/asn1.c b/usr/lib/common/asn1.c
index dbf06dfd..85d3924c 100644
--- a/usr/lib/common/asn1.c
+++ b/usr/lib/common/asn1.c
@@ -3788,7 +3788,8 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG data_len,
CK_ATTRIBUTE **rho_attr,
CK_ATTRIBUTE **t1_attr,
- CK_ATTRIBUTE **value_attr)
+ CK_ATTRIBUTE **value_attr,
+ const struct pqc_oid **oid)
{
CK_ATTRIBUTE *rho_attr_temp = NULL;
CK_ATTRIBUTE *t1_attr_temp = NULL;
@@ -3818,8 +3819,8 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
return rc;
}
- if (algoid_len != dilithium_r2_65_len ||
- memcmp(algoid, dilithium_r2_65, dilithium_r2_65_len) != 0) {
+ *oid = find_pqc_by_oid(dilithium_oids, algoid, algoid_len);
+ if (*oid == NULL) {
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
@@ -4155,7 +4156,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
CK_ATTRIBUTE **s2,
CK_ATTRIBUTE **t0,
CK_ATTRIBUTE **t1,
- CK_ATTRIBUTE **value)
+ CK_ATTRIBUTE **value,
+ const struct pqc_oid **oid)
{
CK_ATTRIBUTE *rho_attr = NULL, *seed_attr = NULL;
CK_ATTRIBUTE *tr_attr = NULL, *s1_attr = NULL, *s2_attr = NULL;
@@ -4175,8 +4177,14 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
return rc;
}
- if (len != dilithium_r2_65_len + ber_NULLLen ||
- memcmp(algoid, dilithium_r2_65, dilithium_r2_65_len) != 0) {
+ if (len <= ber_NULLLen ||
+ memcmp(algoid + len - ber_NULLLen, ber_NULL, ber_NULLLen) != 0) {
+ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
+ return CKR_FUNCTION_FAILED;
+ }
+ len -= ber_NULLLen;
+ *oid = find_pqc_by_oid(dilithium_oids, algoid, len);
+ if (*oid == NULL) {
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index 53909e99..fdbcacd9 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -26,6 +26,7 @@
#include <stdio.h>
#include "dlist.h"
#include "host_defs.h"
+#include "pqc_defs.h"
#include <openssl/evp.h>
@@ -2504,6 +2505,10 @@ CK_RV ibm_dilithium_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data,
CK_RV ibm_dilithium_priv_unwrap_get_data(TEMPLATE *tmpl,
CK_BYTE *data, CK_ULONG total_length,
CK_BBOOL add_value);
+const struct pqc_oid *ibm_pqc_get_keyform_mode(TEMPLATE *tmpl,
+ CK_MECHANISM_TYPE mech);
+CK_RV ibm_pqc_add_keyform_mode(TEMPLATE *tmpl, const struct pqc_oid *oid,
+ CK_MECHANISM_TYPE mech);
// diffie-hellman routines
//
@@ -2750,7 +2755,8 @@ CK_RV ber_decode_IBM_DilithiumPublicKey(CK_BYTE *data,
CK_ULONG data_len,
CK_ATTRIBUTE **rho_attr,
CK_ATTRIBUTE **t1_attr,
- CK_ATTRIBUTE **value_attr);
+ CK_ATTRIBUTE **value_attr,
+ const struct pqc_oid **oid);
CK_RV ber_encode_IBM_DilithiumPrivateKey(CK_BBOOL length_only,
CK_BYTE **data,
@@ -2773,7 +2779,8 @@ CK_RV ber_decode_IBM_DilithiumPrivateKey(CK_BYTE *data,
CK_ATTRIBUTE **s2,
CK_ATTRIBUTE **t0,
CK_ATTRIBUTE **t1,
- CK_ATTRIBUTE **value);
+ CK_ATTRIBUTE **value,
+ const struct pqc_oid **oid);
typedef CK_RV (*t_rsa_encrypt)(STDLL_TokData_t *, CK_BYTE *in_data,
CK_ULONG in_data_len, CK_BYTE *out_data,
diff --git a/usr/lib/common/key.c b/usr/lib/common/key.c
index b0050816..ba40cefd 100644
--- a/usr/lib/common/key.c
+++ b/usr/lib/common/key.c
@@ -2654,6 +2654,117 @@ error:
return rc;
}
+static CK_RV ibm_pqc_keyform_mode_attrs_by_mech(CK_MECHANISM_TYPE mech,
+ CK_ATTRIBUTE_TYPE *keyform_attr,
+ CK_ATTRIBUTE_TYPE *mode_attr,
+ const struct pqc_oid **oids)
+{
+ switch (mech) {
+ case CKM_IBM_DILITHIUM:
+ *keyform_attr = CKA_IBM_DILITHIUM_KEYFORM;
+ *mode_attr = CKA_IBM_DILITHIUM_MODE;
+ *oids = dilithium_oids;
+ break;
+ case CKM_IBM_KYBER:
+ *keyform_attr = CKA_IBM_KYBER_KEYFORM;
+ *mode_attr = CKA_IBM_KYBER_MODE;
+ *oids = kyber_oids;
+ break;
+ default:
+ TRACE_ERROR("Unsupported mechanims: 0x%lx\n", mech);
+ return CKR_MECHANISM_INVALID;
+ }
+
+ return CKR_OK;
+}
+
+const struct pqc_oid *ibm_pqc_get_keyform_mode(TEMPLATE *tmpl,
+ CK_MECHANISM_TYPE mech)
+{
+ CK_ATTRIBUTE *attr = NULL;
+ const struct pqc_oid *oids, *oid;
+ CK_ATTRIBUTE_TYPE keyform_attr;
+ CK_ATTRIBUTE_TYPE mode_attr;
+
+ if (ibm_pqc_keyform_mode_attrs_by_mech(mech, &keyform_attr,
+ &mode_attr, &oids) != CKR_OK)
+ return NULL;
+
+ if (template_attribute_find(tmpl, keyform_attr, &attr) &&
+ attr->ulValueLen == sizeof(CK_ULONG) && attr->pValue != NULL) {
+ oid = find_pqc_by_keyform(oids, *(CK_ULONG *)(attr->pValue));
+ if (oid == NULL) {
+ TRACE_ERROR("KEYFORM attribute specifies an invalid value: %lu\n",
+ *(CK_ULONG *)(attr->pValue));
+ return NULL;
+ }
+ return oid;
+ }
+
+ if (template_attribute_find(tmpl, mode_attr, &attr) &&
+ attr->ulValueLen != 0 && attr->pValue != NULL) {
+ oid = find_pqc_by_oid(oids, attr->pValue, attr->ulValueLen);
+ if (oid == NULL) {
+ TRACE_ERROR("MODE attribute specifies an invalid value\n");
+ return NULL;
+ }
+ return oid;
+ }
+
+ TRACE_ERROR("Neither KEYFORM nor MODE found\n");
+ return NULL;
+}
+
+CK_RV ibm_pqc_add_keyform_mode(TEMPLATE *tmpl, const struct pqc_oid *oid,
+ CK_MECHANISM_TYPE mech)
+{
+ CK_ATTRIBUTE *mode = NULL;
+ CK_ATTRIBUTE *keyform = NULL;
+ CK_RV rc;
+ CK_ATTRIBUTE_TYPE keyform_attr;
+ CK_ATTRIBUTE_TYPE mode_attr;
+ const struct pqc_oid *oids;
+
+ if (ibm_pqc_keyform_mode_attrs_by_mech(mech, &keyform_attr,
+ &mode_attr, &oids) != CKR_OK)
+ return CKR_MECHANISM_INVALID;
+
+ rc = build_attribute(mode_attr, (CK_BYTE *)oid->oid, oid->oid_len, &mode);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("build_attribute failed\n");
+ goto error;
+ }
+ rc = template_update_attribute(tmpl, mode);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("template_update_attribute failed.\n");
+ goto error;
+ }
+ mode = NULL;
+
+ rc = build_attribute(keyform_attr, (CK_BYTE *)&oid->keyform,
+ sizeof(CK_ULONG), &keyform);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("build_attribute failed\n");
+ goto error;
+ }
+ rc = template_update_attribute(tmpl, keyform);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("template_update_attribute failed.\n");
+ goto error;
+ }
+ keyform = NULL;
+
+ return CKR_OK;
+
+error:
+ if (mode)
+ free(mode);
+ if (keyform)
+ free(keyform);
+
+ return rc;
+}
+
/*
* Extract the SubjectPublicKeyInfo from the Dilithium public key
*/
@@ -2662,21 +2773,12 @@ CK_RV ibm_dilithium_publ_get_spki(TEMPLATE *tmpl, CK_BBOOL length_only,
{
CK_ATTRIBUTE *rho = NULL;
CK_ATTRIBUTE *t1 = NULL;
- CK_ULONG keyform;
+ const struct pqc_oid *oid;
CK_RV rc;
- rc = template_attribute_get_ulong(tmpl, CKA_IBM_DILITHIUM_KEYFORM,
- &keyform);
- if (rc != CKR_OK) {
- TRACE_ERROR("Could not find CKA_IBM_DILITHIUM_KEYFORM for the key.\n");
- return rc;
- }
-
- if ( keyform != IBM_DILITHIUM_KEYFORM_ROUND2) {
- TRACE_ERROR("This key has an unexpected CKA_IBM_DILITHIUM_KEYFORM: "
- "%ld \n", keyform);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ oid = ibm_pqc_get_keyform_mode(tmpl, CKM_IBM_DILITHIUM);
+ if (oid == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
rc = template_attribute_get_non_empty(tmpl, CKA_IBM_DILITHIUM_RHO, &rho);
if (rc != CKR_OK) {
@@ -2690,8 +2792,7 @@ CK_RV ibm_dilithium_publ_get_spki(TEMPLATE *tmpl, CK_BBOOL length_only,
}
rc = ber_encode_IBM_DilithiumPublicKey(length_only, data, data_len,
- dilithium_r2_65,
- dilithium_r2_65_len,
+ oid->oid, oid->oid_len,
rho, t1);
if (rc != CKR_OK) {
TRACE_ERROR("ber_encode_IBM_DilithiumPublicKey failed.\n");
@@ -2709,23 +2810,12 @@ CK_RV ibm_dilithium_priv_wrap_get_data(TEMPLATE *tmpl,
CK_ATTRIBUTE *rho = NULL, *seed = NULL;
CK_ATTRIBUTE *tr = NULL, *s1 = NULL, *s2 = NULL;
CK_ATTRIBUTE *t0 = NULL, *t1 = NULL;
- CK_ULONG keyform;
+ const struct pqc_oid *oid;
CK_RV rc;
- /* A private Dilithium key must have a keyform value */
- rc = template_attribute_get_ulong(tmpl, CKA_IBM_DILITHIUM_KEYFORM,
- &keyform);
- if (rc != CKR_OK) {
- TRACE_ERROR("Could not find CKA_IBM_DILITHIUM_KEYFORM for the key.\n");
- return rc;
- }
-
- /* Check if it's an expected keyform */
- if (keyform != IBM_DILITHIUM_KEYFORM_ROUND2) {
- TRACE_ERROR("This key has an unexpected CKA_IBM_DILITHIUM_KEYFORM: %ld\n",
- keyform);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
+ oid = ibm_pqc_get_keyform_mode(tmpl, CKM_IBM_DILITHIUM);
+ if (oid == NULL)
+ return CKR_TEMPLATE_INCOMPLETE;
rc = template_attribute_get_non_empty(tmpl, CKA_IBM_DILITHIUM_RHO, &rho);
if (rc != CKR_OK) {
@@ -2770,8 +2860,7 @@ CK_RV ibm_dilithium_priv_wrap_get_data(TEMPLATE *tmpl,
}
rc = ber_encode_IBM_DilithiumPrivateKey(length_only, data, data_len,
- dilithium_r2_65,
- dilithium_r2_65_len,
+ oid->oid, oid->oid_len,
rho, seed, tr, s1, s2, t0, t1);
if (rc != CKR_OK) {
TRACE_DEVEL("ber_encode_IBM_DilithiumPrivateKey failed\n");
@@ -2787,15 +2876,22 @@ CK_RV ibm_dilithium_priv_unwrap_get_data(TEMPLATE *tmpl, CK_BYTE *data,
CK_ATTRIBUTE *rho = NULL;
CK_ATTRIBUTE *t1 = NULL;
CK_ATTRIBUTE *value = NULL;
+ const struct pqc_oid *oid;
CK_RV rc;
rc = ber_decode_IBM_DilithiumPublicKey(data, total_length, &rho, &t1,
- &value);
+ &value, &oid);
if (rc != CKR_OK) {
TRACE_ERROR("ber_decode_DilithiumPublicKey failed\n");
return rc;
}
+ rc = ibm_pqc_add_keyform_mode(tmpl, oid, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
+ return rc;
+ }
+
rc = template_update_attribute(tmpl, rho);
if (rc != CKR_OK) {
TRACE_DEVEL("template_update_attribute failed.\n");
@@ -2839,16 +2935,23 @@ CK_RV ibm_dilithium_priv_unwrap(TEMPLATE *tmpl, CK_BYTE *data,
{
CK_ATTRIBUTE *rho = NULL, *seed = NULL, *tr = NULL, *value = NULL;
CK_ATTRIBUTE *s1 = NULL, *s2 = NULL, *t0 = NULL, *t1 = NULL;
+ const struct pqc_oid *oid;
CK_RV rc;
rc = ber_decode_IBM_DilithiumPrivateKey(data, total_length,
&rho, &seed, &tr, &s1, &s2, &t0,
- &t1, &value);
+ &t1, &value, &oid);
if (rc != CKR_OK) {
TRACE_ERROR("der_decode_IBM_DilithiumPrivateKey failed\n");
return rc;
}
+ rc = ibm_pqc_add_keyform_mode(tmpl, oid, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
+ return rc;
+ }
+
rc = template_update_attribute(tmpl, rho);
if (rc != CKR_OK) {
TRACE_ERROR("template_update_attribute failed\n");
@@ -4660,19 +4763,17 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
CK_ATTRIBUTE *type_attr = NULL;
CK_ATTRIBUTE *rho_attr = NULL;
CK_ATTRIBUTE *t1_attr = NULL;
- CK_ATTRIBUTE *keyform_attr = NULL;
CK_ATTRIBUTE *value_attr = NULL;
CK_RV rc;
publ_key_set_default_attributes(tmpl, mode);
type_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
- keyform_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
rho_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
t1_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
- if (!type_attr || !rho_attr || !t1_attr || !keyform_attr || !value_attr) {
+ if (!type_attr || !rho_attr || !t1_attr || !value_attr) {
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
rc = CKR_HOST_MEMORY;
goto error;
@@ -4683,11 +4784,6 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
*(CK_KEY_TYPE *) type_attr->pValue = CKK_IBM_PQC_DILITHIUM;
- keyform_attr->type = CKA_IBM_DILITHIUM_KEYFORM;
- keyform_attr->ulValueLen = sizeof(CK_ULONG);
- keyform_attr->pValue = (CK_BYTE *) keyform_attr + sizeof(CK_ATTRIBUTE);
- *(CK_ULONG *) keyform_attr->pValue = IBM_DILITHIUM_KEYFORM_ROUND2;
-
rho_attr->type = CKA_IBM_DILITHIUM_RHO;
rho_attr->ulValueLen = 0;
rho_attr->pValue = NULL;
@@ -4718,12 +4814,6 @@ CK_RV ibm_dilithium_publ_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
goto error;
}
t1_attr = NULL;
- rc = template_update_attribute(tmpl, keyform_attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("template_update_attribute failed\n");
- goto error;
- }
- keyform_attr = NULL;
rc = template_update_attribute(tmpl, value_attr);
if (rc != CKR_OK) {
TRACE_ERROR("template_update_attribute failed\n");
@@ -4740,8 +4830,6 @@ error:
free(rho_attr);
if (t1_attr)
free(t1_attr);
- if (keyform_attr)
- free(keyform_attr);
if (value_attr)
free(value_attr);
@@ -4760,14 +4848,12 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
CK_ATTRIBUTE *s2_attr = NULL;
CK_ATTRIBUTE *t0_attr = NULL;
CK_ATTRIBUTE *t1_attr = NULL;
- CK_ATTRIBUTE *keyform_attr = NULL;
CK_ATTRIBUTE *value_attr = NULL;
CK_RV rc;
priv_key_set_default_attributes(tmpl, mode);
type_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
- keyform_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG));
rho_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
seed_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
tr_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
@@ -4778,7 +4864,7 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE));
if (!type_attr || !rho_attr || !seed_attr || !tr_attr || !s1_attr
- || !s2_attr || !t0_attr || !t1_attr || !keyform_attr || !value_attr) {
+ || !s2_attr || !t0_attr || !t1_attr || !value_attr) {
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
rc = CKR_HOST_MEMORY;
goto error;
@@ -4789,11 +4875,6 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
type_attr->pValue = (CK_BYTE *) type_attr + sizeof(CK_ATTRIBUTE);
*(CK_KEY_TYPE *) type_attr->pValue = CKK_IBM_PQC_DILITHIUM;
- keyform_attr->type = CKA_IBM_DILITHIUM_KEYFORM;
- keyform_attr->ulValueLen = sizeof(CK_ULONG);
- keyform_attr->pValue = (CK_BYTE *) keyform_attr + sizeof(CK_ATTRIBUTE);
- *(CK_ULONG *) keyform_attr->pValue = IBM_DILITHIUM_KEYFORM_ROUND2;
-
rho_attr->type = CKA_IBM_DILITHIUM_RHO;
rho_attr->ulValueLen = 0;
rho_attr->pValue = NULL;
@@ -4832,12 +4913,6 @@ CK_RV ibm_dilithium_priv_set_default_attributes(TEMPLATE *tmpl, CK_ULONG mode)
goto error;
}
type_attr = NULL;
- rc = template_update_attribute(tmpl, keyform_attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("template_update_attribute failed\n");
- goto error;
- }
- keyform_attr = NULL;
rc = template_update_attribute(tmpl, rho_attr);
if (rc != CKR_OK) {
TRACE_ERROR("template_update_attribute failed\n");
@@ -4906,38 +4981,59 @@ error:
free(t0_attr);
if (t1_attr)
free(t1_attr);
- if (keyform_attr)
- free(keyform_attr);
if (value_attr)
free(value_attr);
return rc;
}
-// ibm_dilithium_publ_check_required_attributes()
-//
-CK_RV ibm_dilithium_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
+static CK_RV ibm_pqc_check_attributes(TEMPLATE *tmpl, CK_ULONG mode,
+ CK_MECHANISM_TYPE mech,
+ CK_ULONG *req_attrs,
+ CK_ULONG num_req_attrs)
{
+ CK_ATTRIBUTE_TYPE keyform_attr;
+ CK_ATTRIBUTE_TYPE mode_attr;
CK_ATTRIBUTE *attr = NULL;
- static CK_ULONG req_attrs[] = {
- CKA_IBM_DILITHIUM_KEYFORM,
- CKA_IBM_DILITHIUM_RHO,
- CKA_IBM_DILITHIUM_T1,
- };
+ CK_BBOOL keyform_present = FALSE;
+ CK_BBOOL mode_present = FALSE;
+ const struct pqc_oid *oids, *oid;
CK_ULONG i;
CK_RV rc;
+ if (ibm_pqc_keyform_mode_attrs_by_mech(mech, &keyform_attr,
+ &mode_attr, &oids) != CKR_OK)
+ return CKR_MECHANISM_INVALID;
+
+ if (template_attribute_find(tmpl, keyform_attr, &attr) &&
+ attr->ulValueLen == sizeof(CK_ULONG) && attr->pValue != NULL) {
+ oid = find_pqc_by_keyform(oids, *(CK_ULONG *)(attr->pValue));
+ if (oid == NULL) {
+ TRACE_ERROR("%s, attribute KEYFORM has an unsupported value.\n",
+ ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ keyform_present = TRUE;
+ }
+
+ if (template_attribute_find(tmpl, mode_attr, &attr) &&
+ attr->ulValueLen > 0 && attr->pValue != NULL) {
+ oid = find_pqc_by_oid(oids, attr->pValue, attr->ulValueLen);
+ if (oid == NULL) {
+ TRACE_ERROR("%s, attribute MODE has an unsupported value.\n",
+ ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ mode_present = TRUE;
+ }
+
switch (mode) {
- case MODE_KEYGEN:
- case MODE_UNWRAP:
- /* Attrs will be added during keygen/unwrap */
- break;
case MODE_CREATE:
/* Either CKA_VALUE or all other attrs must be present */
if (template_attribute_find(tmpl, CKA_VALUE, &attr) &&
attr->ulValueLen > 0 && attr->pValue != NULL)
break;
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
+ for (i = 0; i < num_req_attrs; i++) {
rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
if (rc != CKR_OK) {
if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
@@ -4946,27 +5042,58 @@ CK_RV ibm_dilithium_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode
return rc;
}
}
+ /* fallthrough */
+ case MODE_KEYGEN:
+ /* Either keyform or mode or none of it must be present */
+ if (keyform_present && mode_present) {
+ TRACE_ERROR("%s, only one of KEYFORM or MODE can be specified .\n",
+ ock_err(ERR_TEMPLATE_INCONSISTENT));
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
+ break;
+ case MODE_UNWRAP:
+ /* neither keyform or mode must be present */
+ if (keyform_present || mode_present) {
+ TRACE_ERROR("%s, none of KEYFORM or MODE can be specified .\n",
+ ock_err(ERR_TEMPLATE_INCONSISTENT));
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
break;
case MODE_COPY:
- /* CKA_VALUE and all other attrs must be present */
- if (!template_attribute_find(tmpl, CKA_VALUE, &attr) &&
- attr->ulValueLen > 0 && attr->pValue != NULL) {
- TRACE_ERROR("%s, attribute CKA_VALUE missing.\n",
+ /* All attributes must be present */
+ if (!keyform_present || !mode_present) {
+ TRACE_ERROR("%s, KEYFORM or MODE must be specified .\n",
ock_err(ERR_TEMPLATE_INCOMPLETE));
return CKR_TEMPLATE_INCOMPLETE;
}
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
- rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
- if (rc != CKR_OK) {
- if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
- TRACE_ERROR("%s, attribute %08lX missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
- return rc;
+ for (i = 0; i < num_req_attrs; i++) {
+ if (!template_attribute_find(tmpl, req_attrs[i], &attr)) {
+ TRACE_ERROR("%s, attribute %08lX missing.\n",
+ ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
+ return CKR_TEMPLATE_INCOMPLETE;
}
}
break;
}
+ return CKR_OK;
+}
+
+// ibm_dilithium_publ_check_required_attributes()
+//
+CK_RV ibm_dilithium_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
+{
+ static CK_ULONG req_attrs[] = {
+ CKA_IBM_DILITHIUM_RHO,
+ CKA_IBM_DILITHIUM_T1,
+ };
+ CK_RV rc;
+
+ rc = ibm_pqc_check_attributes(tmpl, mode, CKM_IBM_DILITHIUM, req_attrs,
+ sizeof(req_attrs) / sizeof(req_attrs[0]));
+ if (rc != CKR_OK)
+ return rc;
+
/* All required attrs found, check them */
return publ_key_check_required_attributes(tmpl, mode);
}
@@ -4975,9 +5102,7 @@ CK_RV ibm_dilithium_publ_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode
//
CK_RV ibm_dilithium_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode)
{
- CK_ATTRIBUTE *attr = NULL;
static CK_ULONG req_attrs[] = {
- CKA_IBM_DILITHIUM_KEYFORM,
CKA_IBM_DILITHIUM_RHO,
CKA_IBM_DILITHIUM_SEED,
CKA_IBM_DILITHIUM_TR,
@@ -4986,52 +5111,62 @@ CK_RV ibm_dilithium_priv_check_required_attributes(TEMPLATE *tmpl, CK_ULONG mode
CKA_IBM_DILITHIUM_T0,
CKA_IBM_DILITHIUM_T1,
};
- CK_ULONG i;
CK_RV rc;
- switch (mode) {
- case MODE_KEYGEN:
- case MODE_UNWRAP:
- /* Attrs will be added during keygen/unwrap */
- break;
- case MODE_CREATE:
- /* Either CKA_VALUE or all other attrs must be present */
- if (template_attribute_find(tmpl, CKA_VALUE, &attr) &&
- attr->ulValueLen > 0 && attr->pValue != NULL)
- break;
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
- rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
- if (rc != CKR_OK) {
- if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
- TRACE_ERROR("%s, attribute %08lX missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
- return rc;
- }
- }
- break;
- case MODE_COPY:
- /* CKA_VALUE and all other attrs must be present */
- if (!template_attribute_find(tmpl, CKA_VALUE, &attr) &&
- attr->ulValueLen > 0 && attr->pValue != NULL) {
- TRACE_ERROR("%s, attribute CKA_VALUE missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE));
- return CKR_TEMPLATE_INCOMPLETE;
+ rc = ibm_pqc_check_attributes(tmpl, mode, CKM_IBM_DILITHIUM, req_attrs,
+ sizeof(req_attrs) / sizeof(req_attrs[0]));
+ if (rc != CKR_OK)
+ return rc;
+
+ /* All required attrs found, check them */
+ return priv_key_check_required_attributes(tmpl, mode);
+}
+
+static CK_RV ibm_pqc_validate_keyform_mode(CK_ATTRIBUTE *attr, CK_ULONG mode,
+ CK_MECHANISM_TYPE mech)
+{
+ CK_ATTRIBUTE_TYPE keyform_attr;
+ CK_ATTRIBUTE_TYPE mode_attr;
+ const struct pqc_oid *oids, *oid;
+ if (ibm_pqc_keyform_mode_attrs_by_mech(mech, &keyform_attr,
+ &mode_attr, &oids) != CKR_OK)
+ return CKR_MECHANISM_INVALID;
+
+ if (attr->type == keyform_attr) {
+ if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
+ if (attr->ulValueLen != sizeof(CK_ULONG) || attr->pValue == NULL) {
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ oid = find_pqc_by_keyform(oids, *((CK_ULONG *)attr->pValue));
+ if (oid == NULL) {
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ return CKR_OK;
}
- for (i = 0; i < sizeof(req_attrs) / sizeof(req_attrs[0]); i++) {
- rc = template_attribute_get_non_empty(tmpl, req_attrs[i], &attr);
- if (rc != CKR_OK) {
- if (rc != CKR_ATTRIBUTE_VALUE_INVALID)
- TRACE_ERROR("%s, attribute %08lX missing.\n",
- ock_err(ERR_TEMPLATE_INCOMPLETE), req_attrs[i]);
- return rc;
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ if (attr->type == mode_attr) {
+ if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
+ if (attr->ulValueLen == 0 || attr->pValue == NULL) {
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ oid = find_pqc_by_oid(oids, attr->pValue, attr->ulValueLen);
+ if (oid == NULL) {
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
+ return CKR_OK;
}
- break;
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
+ return CKR_ATTRIBUTE_READ_ONLY;
}
- /* All required attrs found, check them */
- return priv_key_check_required_attributes(tmpl, mode);
+ return CKR_OK;
}
// ibm_dilithium_publ_validate_attribute()
@@ -5040,7 +5175,15 @@ CK_RV ibm_dilithium_publ_validate_attribute(STDLL_TokData_t *tokdata,
TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
CK_ULONG mode)
{
+ CK_RV rc;
+
switch (attr->type) {
+ case CKA_IBM_DILITHIUM_KEYFORM:
+ case CKA_IBM_DILITHIUM_MODE:
+ rc = ibm_pqc_validate_keyform_mode(attr, mode, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK)
+ return rc;
+ return CKR_OK;
case CKA_IBM_DILITHIUM_RHO:
case CKA_IBM_DILITHIUM_T1:
case CKA_VALUE:
@@ -5048,22 +5191,6 @@ CK_RV ibm_dilithium_publ_validate_attribute(STDLL_TokData_t *tokdata,
return CKR_OK;
TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
return CKR_ATTRIBUTE_READ_ONLY;
- case CKA_IBM_DILITHIUM_KEYFORM:
- if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
- if (attr->ulValueLen != sizeof(CK_ULONG) || attr->pValue == NULL) {
- TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- switch (*((CK_ULONG *)attr->pValue)) {
- case IBM_DILITHIUM_KEYFORM_ROUND2:
- return CKR_OK;
- default:
- TRACE_ERROR("%s\n", ock_err(CKR_ATTRIBUTE_VALUE_INVALID));
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
- return CKR_ATTRIBUTE_READ_ONLY;
default:
return publ_key_validate_attribute(tokdata, tmpl, attr, mode);
}
@@ -5075,7 +5202,15 @@ CK_RV ibm_dilithium_priv_validate_attribute(STDLL_TokData_t *tokdata,
TEMPLATE *tmpl, CK_ATTRIBUTE *attr,
CK_ULONG mode)
{
+ CK_RV rc;
+
switch (attr->type) {
+ case CKA_IBM_DILITHIUM_KEYFORM:
+ case CKA_IBM_DILITHIUM_MODE:
+ rc = ibm_pqc_validate_keyform_mode(attr, mode, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK)
+ return rc;
+ return CKR_OK;
case CKA_IBM_DILITHIUM_RHO:
case CKA_IBM_DILITHIUM_SEED:
case CKA_IBM_DILITHIUM_TR:
@@ -5088,22 +5223,6 @@ CK_RV ibm_dilithium_priv_validate_attribute(STDLL_TokData_t *tokdata,
return CKR_OK;
TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
return CKR_ATTRIBUTE_READ_ONLY;
- case CKA_IBM_DILITHIUM_KEYFORM:
- if (mode == MODE_CREATE || mode == MODE_KEYGEN) {
- if (attr->ulValueLen != sizeof(CK_ULONG) || attr->pValue == NULL) {
- TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_VALUE_INVALID));
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- switch (*((CK_ULONG *)attr->pValue)) {
- case IBM_DILITHIUM_KEYFORM_ROUND2:
- return CKR_OK;
- default:
- TRACE_ERROR("%s\n", ock_err(CKR_ATTRIBUTE_VALUE_INVALID));
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
- return CKR_ATTRIBUTE_READ_ONLY;
default:
return priv_key_validate_attribute(tokdata, tmpl, attr, mode);
}
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 9221b8cd..c440cac5 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -158,8 +158,8 @@ const char label[] = "ep11tok";
#define MAX_CSUMSIZE 64
#define EP11_CSUMSIZE 3
#define MAX_DIGEST_STATE_BYTES 1024
-#define MAX_CRYPT_STATE_BYTES 8192
-#define MAX_SIGN_STATE_BYTES 8192
+#define MAX_CRYPT_STATE_BYTES 12288
+#define MAX_SIGN_STATE_BYTES 12288
#define MAX_APQN 256
#define EP11_BLOB_WKID_OFFSET 32
@@ -1937,7 +1937,9 @@ static CK_BBOOL attr_applicable_for_ep11(STDLL_TokData_t * tokdata,
case CKK_IBM_PQC_DILITHIUM:
if (attr->type == CKA_ENCRYPT || attr->type == CKA_DECRYPT ||
attr->type == CKA_WRAP || attr->type == CKA_UNWRAP ||
- attr->type == CKA_DERIVE)
+ attr->type == CKA_DERIVE ||
+ attr->type == CKA_IBM_DILITHIUM_KEYFORM ||
+ attr->type == CKA_IBM_DILITHIUM_MODE)
return CK_FALSE;
break;
default:
@@ -3587,6 +3589,7 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
CK_ATTRIBUTE *value_attr = NULL;
CK_BBOOL data_alloced = TRUE;
+ const struct pqc_oid *oid;
memcpy(iv, "1234567812345678", AES_BLOCK_SIZE);
@@ -3611,7 +3614,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* Make an SPKI for the public IBM Dilithium key */
/* A public IBM Dilithium key must either have a CKA_VALUE containing
- * the SPKI, or must have a keyform value and the individual attributes
+ * the SPKI, or must have a keyform/mode value and the individual
+ * attributes
*/
if (template_attribute_find(dilithium_key_obj->template,
CKA_VALUE, &value_attr) &&
@@ -3621,7 +3625,10 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
data_len = value_attr->ulValueLen;
data_alloced = FALSE;
- /* Decode SPKI and add public key attributes */
+ /*
+ * Decode SPKI and add public key attributes. This also adds the
+ * keyform and mode attributes to the template.
+ */
rc = ibm_dilithium_priv_unwrap_get_data(dilithium_key_obj->template,
data, data_len, FALSE);
if (rc != CKR_OK) {
@@ -3641,6 +3648,21 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
"data_len=0x%lx\n", __func__, class, rc, data_len);
}
+ /* Ensure both, keyform and mode attributes are added */
+ oid = ibm_pqc_get_keyform_mode(dilithium_key_obj->template,
+ CKM_IBM_DILITHIUM);
+ if (oid == NULL) {
+ rc = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ rc = ibm_pqc_add_keyform_mode(dilithium_key_obj->template,
+ oid, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
+ goto done;
+ }
+
/* Add SPKI as CKA_VALUE to public key (z/OS ICSF compatibility) */
rc = build_attribute(CKA_VALUE, data, data_len, &value_attr);
if (rc != CKR_OK) {
@@ -3677,8 +3699,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* imported private IBM Dilithium key goes here */
/* A public IBM Dilithium key must either have a CKA_VALUE containing
- * the PKCS#8 encoded private key, or must have a keyform value and the
- * individual attributes
+ * the PKCS#8 encoded private key, or must have a keyform/mode value
+ * and the individual attributes
*/
if (template_attribute_find(dilithium_key_obj->template,
CKA_VALUE, &value_attr) &&
@@ -3696,8 +3718,9 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
} else {
- /* extract the secret data to be wrapped
- * since this is AES_CBC_PAD, padding is done in mechanism.
+ /* Extract the secret data to be wrapped since this is AES_CBC_PAD,
+ * padding is done in mechanism. This also adds the keyform and mode
+ * attributes to the template.
*/
rc = ibm_dilithium_priv_wrap_get_data(dilithium_key_obj->template,
FALSE, &data, &data_len);
@@ -3705,6 +3728,21 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
TRACE_DEVEL("%s Dilithium wrap get data failed\n", __func__);
goto done;
}
+
+ /* Ensure both, keyform and mode attributes are added */
+ oid = ibm_pqc_get_keyform_mode(dilithium_key_obj->template,
+ CKM_IBM_DILITHIUM);
+ if (oid == NULL) {
+ rc = CKR_TEMPLATE_INCOMPLETE;
+ goto done;
+ }
+
+ rc = ibm_pqc_add_keyform_mode(dilithium_key_obj->template,
+ oid, CKM_IBM_DILITHIUM);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
+ goto done;
+ }
}
/* encrypt */
@@ -6456,8 +6494,7 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
CK_ULONG new_publ_attrs_len = 0, new_priv_attrs_len = 0;
CK_ATTRIBUTE *new_publ_attrs2 = NULL, *new_priv_attrs2 = NULL;
CK_ULONG new_publ_attrs2_len = 0, new_priv_attrs2_len = 0;
- const CK_BYTE dilithium_oid[] = { 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01,
- 0x02, 0x82, 0x0b, 0x01, 0x06, 0x05 };
+ const struct pqc_oid *dilithium_oid;
if (pMechanism->mechanism != CKM_IBM_DILITHIUM) {
TRACE_ERROR("Invalid mechanism provided for %s\n ", __func__);
@@ -6480,9 +6517,25 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
goto error;
}
+ dilithium_oid = ibm_pqc_get_keyform_mode(publ_tmpl, CKM_IBM_DILITHIUM);
+ if (dilithium_oid == NULL)
+ dilithium_oid = ibm_pqc_get_keyform_mode(priv_tmpl, CKM_IBM_DILITHIUM);
+ if (dilithium_oid == NULL)
+ dilithium_oid = find_pqc_by_keyform(dilithium_oids,
+ CK_IBM_DILITHIUM_KEYFORM_ROUND2_65);
+ if (dilithium_oid == NULL) {
+ TRACE_ERROR("%s Failed to determine Dilithium OID\n", __func__);
+ rc = CKR_FUNCTION_FAILED;
+ goto error;
+ }
+
+ TRACE_INFO("%s Generate Dilithium key with keyform %lu\n", __func__,
+ dilithium_oid->keyform);
+
rc = add_to_attribute_array(&new_publ_attrs, &new_publ_attrs_len,
- CKA_IBM_PQC_PARAMS, (CK_BYTE *)dilithium_oid,
- sizeof(dilithium_oid));
+ CKA_IBM_PQC_PARAMS,
+ (CK_BYTE *)dilithium_oid->oid,
+ dilithium_oid->oid_len);
if (rc != CKR_OK) {
TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
__func__, rc);
@@ -6490,8 +6543,9 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
}
rc = add_to_attribute_array(&new_priv_attrs, &new_priv_attrs_len,
- CKA_IBM_PQC_PARAMS,(CK_BYTE *)dilithium_oid,
- sizeof(dilithium_oid));
+ CKA_IBM_PQC_PARAMS,
+ (CK_BYTE *)dilithium_oid->oid,
+ dilithium_oid->oid_len);
if (rc != CKR_OK) {
TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
__func__, rc);
--
2.16.2.windows.1

View File

@ -1,308 +0,0 @@
From cf68e9b9d342ced84e8a7fa88b0787a40a44cebb Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Thu, 17 Feb 2022 17:04:11 +0100
Subject: [PATCH 22/34] EP11: Query supported PQC variants and restrict usage
Allow only those PQC variants that are supported by all
configured APQNs. If a key is used with an unsupported strength,
CKR_KEY_SIZE_RANGE is returned.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 187 +++++++++++++++++++++++++++++++++----
1 file changed, 168 insertions(+), 19 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index c440cac5..479951cb 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -540,6 +540,11 @@ static CK_RV handle_all_ep11_cards(ep11_target_t * ep11_targets,
#define PKEY_MODE_DEFAULT 1
#define PKEY_MODE_ENABLE4NONEXTR 2
+#define PQC_BYTE_NO(idx) (((idx) - 1) / 8)
+#define PQC_BIT_IN_BYTE(idx) (((idx - 1)) % 8)
+#define PQC_BIT_MASK(idx) (0x80 >> PQC_BIT_IN_BYTE(idx))
+#define PQC_BYTES ((((XCP_PQC_MAX / 32) * 32) + 32) / 8)
+
typedef struct {
volatile unsigned long ref_count;
target_t target;
@@ -549,6 +554,7 @@ typedef struct {
size_t control_points_len;
size_t max_control_point_index;
CK_CHAR serialNumber[16];
+ CK_BYTE pqc_strength[PQC_BYTES];
} ep11_target_info_t;
typedef struct {
@@ -660,6 +666,87 @@ static CK_RV check_expected_mkvp(STDLL_TokData_t *tokdata, CK_BYTE *blob,
return CKR_OK;
}
+static CK_BBOOL ep11_pqc_strength_supported(ep11_target_info_t *target_info,
+ CK_MECHANISM_TYPE mech,
+ const struct pqc_oid *oid)
+{
+ CK_ULONG strength;
+
+ switch (mech) {
+ case CKM_IBM_DILITHIUM:
+ switch (oid->keyform) {
+ case CK_IBM_DILITHIUM_KEYFORM_ROUND2_65:
+ strength = XCP_PQC_S_DILITHIUM_R2_65;
+ break;
+ case CK_IBM_DILITHIUM_KEYFORM_ROUND2_87:
+ strength = XCP_PQC_S_DILITHIUM_R2_87;
+ break;
+ case CK_IBM_DILITHIUM_KEYFORM_ROUND3_44:
+ strength = XCP_PQC_S_DILITHIUM_R3_44;
+ break;
+ case CK_IBM_DILITHIUM_KEYFORM_ROUND3_65:
+ strength = XCP_PQC_S_DILITHIUM_R3_65;
+ break;
+ case CK_IBM_DILITHIUM_KEYFORM_ROUND3_87:
+ strength = XCP_PQC_S_DILITHIUM_R3_87;
+ break;
+ default:
+ TRACE_DEVEL("Dilithium keyform %lu not supported by EP11\n",
+ oid->keyform);
+ return FALSE;
+ }
+ break;
+ case CKM_IBM_KYBER:
+ switch (oid->keyform) {
+ case CK_IBM_KYBER_KEYFORM_ROUND2_768:
+ strength = XCP_PQC_S_KYBER_R2_768;
+ break;
+ case CK_IBM_KYBER_KEYFORM_ROUND2_1024:
+ strength = XCP_PQC_S_KYBER_R2_1024;
+ break;
+ default:
+ TRACE_DEVEL("Kyber keyform %lu not supported by EP11\n",
+ oid->keyform);
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+
+ if ((target_info->pqc_strength[PQC_BYTE_NO(strength)] &
+ PQC_BIT_MASK(strength)) == 0) {
+ TRACE_DEVEL("Keyform %lu not supported by configured APQNs\n",
+ oid->keyform);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static CK_BBOOL ep11_pqc_obj_strength_supported(ep11_target_info_t *target_info,
+ CK_MECHANISM_TYPE mech,
+ OBJECT *key_obj)
+{
+ const struct pqc_oid *oid;
+
+ switch (mech) {
+ case CKM_IBM_DILITHIUM:
+ case CKM_IBM_KYBER:
+ break;
+ default:
+ return TRUE;
+ }
+
+ oid = ibm_pqc_get_keyform_mode(key_obj->template, mech);
+ if (oid == NULL) {
+ TRACE_DEVEL("No keyform/mode found in key object\n");
+ return FALSE;
+ }
+
+ return ep11_pqc_strength_supported(target_info, mech, oid);
+}
+
/*******************************************************************************
*
* Begin EP11 protected key option
@@ -3747,10 +3834,15 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* encrypt */
RETRY_START(rc, tokdata)
- rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
- ep11_data->raw2key_wrap_blob_l,
- &mech_w, data, data_len,
- cipher, &cipher_l, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, CKM_IBM_DILITHIUM,
+ dilithium_key_obj))
+ rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
+ ep11_data->raw2key_wrap_blob_l,
+ &mech_w, data, data_len,
+ cipher, &cipher_l,
+ target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, sess)
TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n",
@@ -6583,12 +6675,16 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
- rc = dll_m_GenerateKeyPair(pMechanism,
- new_publ_attrs2, new_publ_attrs2_len,
- new_priv_attrs2, new_priv_attrs2_len,
- ep11_pin_blob, ep11_pin_blob_len,
- privkey_blob, &privkey_blob_len, spki,
- &spki_len, target_info->target);
+ if (ep11_pqc_strength_supported(target_info, pMechanism->mechanism,
+ dilithium_oid))
+ rc = dll_m_GenerateKeyPair(pMechanism,
+ new_publ_attrs2, new_publ_attrs2_len,
+ new_priv_attrs2, new_priv_attrs2_len,
+ ep11_pin_blob, ep11_pin_blob_len,
+ privkey_blob, &privkey_blob_len, spki,
+ &spki_len, target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, sess)
if (rc != CKR_OK) {
rc = ep11_error_to_pkcs11_error(rc, sess);
@@ -7336,8 +7432,13 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_SignInit(ep11_sign_state, &ep11_sign_state_l,
- mech, keyblob, keyblobsize, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_SignInit(ep11_sign_state, &ep11_sign_state_l,
+ mech, keyblob, keyblobsize,
+ target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
@@ -7570,8 +7671,12 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_SignSingle(keyblob, keyblobsize, mech, in_data, in_data_len,
- signature, sig_len, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_SignSingle(keyblob, keyblobsize, mech, in_data, in_data_len,
+ signature, sig_len, target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
rc = ep11_error_to_pkcs11_error(rc, session);
@@ -7689,8 +7794,12 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_VerifyInit(ep11_sign_state, &ep11_sign_state_l, mech,
- spki, spki_len, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_VerifyInit(ep11_sign_state, &ep11_sign_state_l, mech,
+ spki, spki_len, target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
@@ -7929,8 +8038,12 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_VerifySingle(spki, spki_len, mech, in_data, in_data_len,
- signature, sig_len, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_VerifySingle(spki, spki_len, mech, in_data, in_data_len,
+ signature, sig_len, target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
rc = ep11_error_to_pkcs11_error(rc, session);
@@ -11751,6 +11864,7 @@ typedef struct query_version
CK_CHAR serialNumber[16];
CK_BBOOL first;
CK_BBOOL error;
+ CK_BYTE pqc_strength[PQC_BYTES];
} query_version_t;
static CK_RV version_query_handler(uint_32 adapter, uint_32 domain,
@@ -11759,9 +11873,11 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain,
query_version_t *qv = (query_version_t *)handler_data;
CK_IBM_XCP_INFO xcp_info;
CK_ULONG xcp_info_len = sizeof(xcp_info);
+ CK_BYTE pqc_strength[PQC_BYTES] = { 0 };
+ CK_ULONG pqc_strength_len = sizeof(pqc_strength);
CK_RV rc;
target_t target;
- CK_ULONG card_type;
+ CK_ULONG card_type, i;
ep11_card_version_t *card_version;
rc = get_ep11_target_for_apqn(adapter, domain, &target, 0);
@@ -11877,6 +11993,30 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain,
if (qv->first)
memcpy(qv->serialNumber, xcp_info.serialNumber,
sizeof(qv->serialNumber));
+
+ /* Query for PQC strength support. If the PQC strength query is not
+ available only Dilithium 6-5 round 2 is available. */
+ rc = dll_m_get_xcp_info(&pqc_strength, &pqc_strength_len,
+ CK_IBM_XCPQ_PQC_STRENGTHS, 0, target);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("%s Failed to query PQC-strength from adapter %02X.%04X\n",
+ __func__, adapter, domain);
+ /* Only R2_65 is available */
+ pqc_strength[PQC_BYTE_NO(XCP_PQC_S_DILITHIUM_R2_65)] |=
+ PQC_BIT_MASK(XCP_PQC_S_DILITHIUM_R2_65);
+ rc = CKR_OK;
+ }
+
+ TRACE_DEBUG("PQC-strength of %02X.%04X:\n", adapter, domain);
+ TRACE_DEBUG_DUMP("", pqc_strength, sizeof(qv->pqc_strength));
+
+ if (qv->first) {
+ memcpy(qv->pqc_strength, pqc_strength, sizeof(qv->pqc_strength));
+ } else {
+ for (i = 0; i < sizeof(qv->pqc_strength); i++)
+ qv->pqc_strength[i] &= pqc_strength[i];
+ }
+
qv->first = FALSE;
out:
@@ -11934,6 +12074,7 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata,
ep11_private_data_t *ep11_data = tokdata->private_data;
ep11_card_version_t *card_version;
query_version_t qv;
+ CK_ULONG i;
CK_RV rc;
memset(&qv, 0, sizeof(qv));
@@ -11991,6 +12132,14 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata,
TRACE_INFO("%s Used Firmware API: %lu\n", __func__,
target_info->used_firmware_API_version);
+ memcpy(target_info->pqc_strength, qv.pqc_strength, sizeof(qv.pqc_strength));
+
+ TRACE_INFO("Combined PQC-strength:\n");
+ for (i = 1; i <= XCP_PQC_MAX; i++) {
+ TRACE_INFO(" Strength %lu: %d\n", i,
+ (qv.pqc_strength[PQC_BYTE_NO(i)] & PQC_BIT_MASK(i)) != 0);
+ }
+
return CKR_OK;
}
--
2.16.2.windows.1

View File

@ -1,218 +0,0 @@
From ff2bfaa612704a7b8fb5126d450b596106421244 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 18 Feb 2022 12:58:24 +0100
Subject: [PATCH 23/34] POLICY: Dilithium strength and signature size depends
on variant
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
testcases/unit/unit.mk | 3 +-
usr/lib/api/api.mk | 1 +
usr/lib/api/mechtable.inc | 2 +-
usr/lib/api/policy.c | 65 +++++++++++++++++++++++++++++++++++++++++-
usr/lib/common/pqc_defs.h | 2 ++
usr/lib/common/pqc_supported.c | 27 ++++++++++++------
6 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/testcases/unit/unit.mk b/testcases/unit/unit.mk
index accaebca..56ae3bcc 100644
--- a/testcases/unit/unit.mk
+++ b/testcases/unit/unit.mk
@@ -22,7 +22,8 @@ testcases_unit_policytest_SOURCES=testcases/unit/policytest.c \
usr/lib/common/kdf_translation.c \
usr/lib/common/mgf_translation.c \
usr/lib/api/supportedstrengths.c \
- usr/lib/config/cfgparse.y usr/lib/config/cfglex.l
+ usr/lib/config/cfgparse.y usr/lib/config/cfglex.l \
+ usr/lib/common/pqc_supported.c
nodist_testcases_unit_policytest_SOURCES=usr/lib/api/mechtable.c
diff --git a/usr/lib/api/api.mk b/usr/lib/api/api.mk
index 8ec4034e..f222dce7 100644
--- a/usr/lib/api/api.mk
+++ b/usr/lib/api/api.mk
@@ -30,6 +30,7 @@ opencryptoki_libopencryptoki_la_SOURCES = usr/lib/api/api_interface.c \
usr/lib/common/kdf_translation.c \
usr/lib/common/mgf_translation.c \
usr/lib/api/supportedstrengths.c \
+ usr/lib/common/pqc_supported.c \
usr/lib/config/cfgparse.y usr/lib/config/cfglex.l
nodist_opencryptoki_libopencryptoki_la_SOURCES = \
diff --git a/usr/lib/api/mechtable.inc b/usr/lib/api/mechtable.inc
index f74e08b7..e3d14e3e 100644
--- a/usr/lib/api/mechtable.inc
+++ b/usr/lib/api/mechtable.inc
@@ -78,7 +78,7 @@ const struct mechrow mechtable_rows[] =
{ "CKM_IBM_ATTRIBUTEBOUND_WRAP", CKM_IBM_ATTRIBUTEBOUND_WRAP, 0, MC_INFORMATION_UNAVAILABLE, MCF_WRAPUNWRAP | MCF_NEEDSPARAM },
{ "CKM_IBM_BTC_DERIVE", CKM_IBM_BTC_DERIVE, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE | MCF_NEEDSPARAM },
{ "CKM_IBM_CMAC", CKM_IBM_CMAC, 0, MC_KEY_DEPENDENT, MCF_SIGNVERIFY },
- { "CKM_IBM_DILITHIUM", CKM_IBM_DILITHIUM, 0, 3366, MCF_KEYGEN | MCF_SIGNVERIFY },
+ { "CKM_IBM_DILITHIUM", CKM_IBM_DILITHIUM, 0, MC_KEY_DEPENDENT, MCF_KEYGEN | MCF_SIGNVERIFY },
{ "CKM_IBM_ECDSA_OTHER", CKM_IBM_ECDSA_OTHER, 0, MC_KEY_DEPENDENT, MCF_SIGNVERIFY | MCF_NEEDSPARAM },
{ "CKM_IBM_EC_X25519", CKM_IBM_EC_X25519, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE },
{ "CKM_IBM_EC_X448", CKM_IBM_EC_X448, 0, MC_INFORMATION_UNAVAILABLE, MCF_DERIVE },
diff --git a/usr/lib/api/policy.c b/usr/lib/api/policy.c
index 82e799cd..4bee5180 100644
--- a/usr/lib/api/policy.c
+++ b/usr/lib/api/policy.c
@@ -25,6 +25,7 @@
#include <grp.h>
#include <errno.h>
#include <host_defs.h>
+#include <pqc_defs.h>
/* in h_extern.h, but not included since it creates too many unneeded
dependencies for unit tests. */
@@ -179,6 +180,65 @@ static CK_RV policy_get_curve_args(get_attr_val_f getattr, void *d,
return rv;
}
+static CK_RV policy_get_pqc_args(CK_KEY_TYPE key_type,
+ get_attr_val_f getattr, void *d,
+ free_attr_f free_attr, CK_ULONG *size,
+ CK_ULONG *siglen, const CK_BYTE **oid,
+ CK_ULONG *oidlen)
+{
+ CK_ATTRIBUTE_TYPE keyform_attr;
+ CK_ATTRIBUTE_TYPE mode_attr;
+ CK_ATTRIBUTE *keyform = NULL, *mode = NULL;
+ const struct pqc_oid *oids, *pqc_oid = NULL;
+ CK_RV rv;
+
+ switch (key_type) {
+ case CKK_IBM_PQC_DILITHIUM:
+ keyform_attr = CKA_IBM_DILITHIUM_KEYFORM;
+ mode_attr = CKA_IBM_DILITHIUM_MODE;
+ oids = dilithium_oids;
+ break;
+ case CKK_IBM_PQC_KYBER:
+ keyform_attr = CKA_IBM_KYBER_KEYFORM;
+ mode_attr = CKA_IBM_KYBER_MODE;
+ oids = kyber_oids;
+ break;
+ default:
+ TRACE_ERROR("Unsupported key type 0x%lx\n", key_type);
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+
+ rv = getattr(d, keyform_attr, &keyform);
+ if (rv == CKR_OK && keyform->ulValueLen == sizeof(CK_ULONG)) {
+ pqc_oid = find_pqc_by_keyform(oids, *(CK_ULONG *)keyform->pValue);
+ } else {
+ rv = getattr(d, mode_attr, &mode);
+ if (rv == CKR_OK && mode->ulValueLen > 0)
+ pqc_oid = find_pqc_by_oid(oids, mode->pValue, mode->ulValueLen);
+ }
+ if (pqc_oid == NULL) {
+ TRACE_ERROR("Did not find KEYFORM or MODE for key type 0x%lx\n",
+ key_type);
+ rv = CKR_TEMPLATE_INCOMPLETE;
+ goto out;
+ }
+
+ *size = pqc_oid->policy_size;
+ *siglen = pqc_oid->policy_siglen;
+ *oid = pqc_oid->oid;
+ *oidlen = pqc_oid->oid_len;
+
+out:
+ if (free_attr) {
+ if (keyform)
+ free_attr(keyform);
+ if (mode)
+ free_attr(mode);
+ }
+
+ return rv;
+}
+
static CK_RV policy_extract_key_data(get_attr_val_f getattr, void *d,
free_attr_f free_attr,
CK_ULONG *comptarget, CK_ULONG *size,
@@ -273,7 +333,8 @@ static CK_RV policy_extract_key_data(get_attr_val_f getattr, void *d,
*comptarget = COMPARE_SYMMETRIC;
break;
case CKK_IBM_PQC_DILITHIUM:
- *size = 256;
+ rv = policy_get_pqc_args(*(CK_ULONG *)keytype->pValue, getattr, d,
+ free_attr, size, siglen, oid, oidlen);
*comptarget = COMPARE_PQC;
break;
/* POLICY: New CKK */
@@ -346,6 +407,8 @@ static CK_RV policy_get_sig_size(CK_MECHANISM_PTR mech, struct objstrength *s,
case CKM_RSA_X9_31:
/* Fallthrough */
case CKM_IBM_ED448_SHA3:
+ /* Fallthrough */
+ case CKM_IBM_DILITHIUM:
*ssize = s->siglen;
break;
case CKM_DSA_SHA1:
diff --git a/usr/lib/common/pqc_defs.h b/usr/lib/common/pqc_defs.h
index 51ee1200..947f86a7 100644
--- a/usr/lib/common/pqc_defs.h
+++ b/usr/lib/common/pqc_defs.h
@@ -35,6 +35,8 @@ struct pqc_oid {
const CK_BYTE *oid;
CK_ULONG oid_len;
CK_ULONG keyform;
+ CK_ULONG policy_size;
+ CK_ULONG policy_siglen;
};
extern const struct pqc_oid dilithium_oids[];
diff --git a/usr/lib/common/pqc_supported.c b/usr/lib/common/pqc_supported.c
index 4f048c33..77970352 100644
--- a/usr/lib/common/pqc_supported.c
+++ b/usr/lib/common/pqc_supported.c
@@ -25,16 +25,22 @@ const CK_ULONG dilithium_r3_87_len = sizeof(dilithium_r3_87);
const struct pqc_oid dilithium_oids[] = {
{ .oid = dilithium_r2_65, .oid_len = dilithium_r2_65_len,
- .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65 },
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65,
+ .policy_size = 256, .policy_siglen = 3366 },
{ .oid = dilithium_r2_87, .oid_len = dilithium_r2_87_len,
- .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_87 },
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_87,
+ .policy_size = 256, .policy_siglen = 4668 },
{ .oid = dilithium_r3_44, .oid_len = dilithium_r3_44_len,
- .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_44 },
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_44,
+ .policy_size = 256, .policy_siglen = 2420 },
{ .oid = dilithium_r3_65, .oid_len = dilithium_r3_65_len,
- .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_65 },
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_65,
+ .policy_size = 256, .policy_siglen = 3293 },
{ .oid = dilithium_r3_87, .oid_len = dilithium_r3_87_len,
- .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_87 },
- { .oid = NULL, .oid_len = 0, .keyform = 0 }
+ .keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_87,
+ .policy_size = 256, .policy_siglen = 4595 },
+ { .oid = NULL, .oid_len = 0, .keyform = 0,
+ .policy_size = 0, .policy_siglen = 0 }
};
const CK_BYTE kyber_r2_768[] = OCK_KYBER_R2_768;
@@ -44,10 +50,13 @@ const CK_ULONG kyber_r2_1024_len = sizeof(kyber_r2_1024);
const struct pqc_oid kyber_oids[] = {
{ .oid = kyber_r2_768, .oid_len = kyber_r2_768_len,
- .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_768 },
+ .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_768,
+ .policy_size = 256, .policy_siglen = 0 },
{ .oid = kyber_r2_1024, .oid_len = kyber_r2_1024_len,
- .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_1024 },
- { .oid = NULL, .oid_len = 0, .keyform = 0 }
+ .keyform = CK_IBM_KYBER_KEYFORM_ROUND2_1024,
+ .policy_size = 256, .policy_siglen = 0 },
+ { .oid = NULL, .oid_len = 0, .keyform = 0,
+ .policy_size = 0, .policy_siglen = 0 }
};
const struct pqc_oid *find_pqc_by_keyform(const struct pqc_oid *pqcs,
--
2.16.2.windows.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,479 +0,0 @@
From 5b5d1830dadfbbd310c11d26d86426ed63eed936 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 1 Mar 2022 11:09:26 +0100
Subject: [PATCH 26/34] EP11: Add support for generating and importing Kyber
keys
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 222 ++++++++++++++++++++++---------------
1 file changed, 134 insertions(+), 88 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 44796dba..bc17b07a 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -3664,14 +3664,14 @@ import_DH_key_end:
}
/*
- * makes blobs for private imported IBM Dilithium keys and
- * SPKIs for public imported IBM Dilithium keys.
+ * makes blobs for private imported IBM PQC keys and
+ * SPKIs for public imported IBM PQC keys.
* Similar to rawkey_2_blob, but keys must follow a standard BER encoding.
*/
-static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
- OBJECT *dilithium_key_obj,
- CK_BYTE *blob, size_t *blob_size,
- CK_BYTE *spki, size_t *spki_size)
+static CK_RV import_IBM_pqc_key(STDLL_TokData_t *tokdata, SESSION *sess,
+ OBJECT *pqc_key_obj, CK_KEY_TYPE keytype,
+ CK_BYTE *blob, size_t *blob_size,
+ CK_BYTE *spki, size_t *spki_size)
{
ep11_private_data_t *ep11_data = tokdata->private_data;
CK_RV rc;
@@ -3692,11 +3692,27 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
CK_ATTRIBUTE *value_attr = NULL;
CK_BBOOL data_alloced = TRUE;
const struct pqc_oid *oid;
+ const char *key_type_str;
+ CK_MECHANISM_TYPE pqc_mech;
+
+ switch (keytype) {
+ case CKK_IBM_PQC_DILITHIUM:
+ key_type_str = "Dilithium";
+ pqc_mech = CKM_IBM_DILITHIUM;
+ break;
+ case CKK_IBM_PQC_KYBER:
+ key_type_str = "Kyber";
+ pqc_mech = CKM_IBM_KYBER;
+ break;
+ default:
+ TRACE_ERROR("Invalid key type provided for %s\n ", __func__);
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
memcpy(iv, "1234567812345678", AES_BLOCK_SIZE);
/* need class for secret/public key info */
- rc = template_attribute_get_ulong(dilithium_key_obj->template, CKA_CLASS,
+ rc = template_attribute_get_ulong(pqc_key_obj->template, CKA_CLASS,
&class);
if (rc != CKR_OK) {
TRACE_ERROR("Could not find CKA_CLASS for the key.\n");
@@ -3706,20 +3722,20 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* m_Unwrap builds key blob in the card,
* tell ep11 the attributes the user specified for that key.
*/
- rc = build_ep11_attrs(tokdata, dilithium_key_obj->template,
+ rc = build_ep11_attrs(tokdata, pqc_key_obj->template,
&p_attrs, &attrs_len,
- CKK_IBM_PQC_DILITHIUM, class, -1, &mech_w);
+ keytype, class, -1, &mech_w);
if (rc != CKR_OK)
goto done;
if (class != CKO_PRIVATE_KEY) {
- /* Make an SPKI for the public IBM Dilithium key */
+ /* Make an SPKI for the public IBM PQC key */
- /* A public IBM Dilithium key must either have a CKA_VALUE containing
+ /* A public IBM PQC key must either have a CKA_VALUE containing
* the SPKI, or must have a keyform/mode value and the individual
* attributes
*/
- if (template_attribute_find(dilithium_key_obj->template,
+ if (template_attribute_find(pqc_key_obj->template,
CKA_VALUE, &value_attr) &&
value_attr->ulValueLen > 0 && value_attr ->pValue != NULL) {
/* CKA_VALUE with SPKI */
@@ -3731,16 +3747,16 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
* Decode SPKI and add public key attributes. This also adds the
* keyform and mode attributes to the template.
*/
- rc = ibm_dilithium_priv_unwrap_get_data(dilithium_key_obj->template,
- data, data_len, FALSE);
+ rc = ibm_pqc_priv_unwrap_get_data(pqc_key_obj->template, keytype,
+ data, data_len, FALSE);
if (rc != CKR_OK) {
TRACE_ERROR("Failed to decode SPKI from CKA_VALUE.\n");
goto done;
}
} else {
/* Individual attributes */
- rc = ibm_dilithium_publ_get_spki(dilithium_key_obj->template,
- FALSE, &data, &data_len);
+ rc = ibm_pqc_publ_get_spki(pqc_key_obj->template, keytype,
+ FALSE, &data, &data_len);
if (rc != CKR_OK) {
TRACE_ERROR("%s public key import class=0x%lx rc=0x%lx "
"data_len=0x%lx\n", __func__, class, rc, data_len);
@@ -3751,15 +3767,13 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
}
/* Ensure both, keyform and mode attributes are added */
- oid = ibm_pqc_get_keyform_mode(dilithium_key_obj->template,
- CKM_IBM_DILITHIUM);
+ oid = ibm_pqc_get_keyform_mode(pqc_key_obj->template, pqc_mech);
if (oid == NULL) {
rc = CKR_TEMPLATE_INCOMPLETE;
goto done;
}
- rc = ibm_pqc_add_keyform_mode(dilithium_key_obj->template,
- oid, CKM_IBM_DILITHIUM);
+ rc = ibm_pqc_add_keyform_mode(pqc_key_obj->template, oid, pqc_mech);
if (rc != CKR_OK) {
TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
goto done;
@@ -3772,7 +3786,7 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
- rc = template_update_attribute(dilithium_key_obj->template,
+ rc = template_update_attribute(pqc_key_obj->template,
value_attr);
if (rc != CKR_OK) {
TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
@@ -3786,7 +3800,7 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* save the SPKI as blob although it is not a blob.
* The card expects MACed-SPKIs as public keys.
*/
- rc = make_maced_spki(tokdata, sess, dilithium_key_obj, data, data_len,
+ rc = make_maced_spki(tokdata, sess, pqc_key_obj, data, data_len,
blob, blob_size, -1);
if (rc != CKR_OK) {
TRACE_ERROR("%s failed to make a MACed-SPKI rc=0x%lx\n",
@@ -3798,13 +3812,13 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
} else {
- /* imported private IBM Dilithium key goes here */
+ /* imported private IBM PQC key goes here */
- /* A public IBM Dilithium key must either have a CKA_VALUE containing
+ /* A public IBM PQC key must either have a CKA_VALUE containing
* the PKCS#8 encoded private key, or must have a keyform/mode value
* and the individual attributes
*/
- if (template_attribute_find(dilithium_key_obj->template,
+ if (template_attribute_find(pqc_key_obj->template,
CKA_VALUE, &value_attr) &&
value_attr->ulValueLen > 0 && value_attr ->pValue != NULL) {
/* CKA_VALUE with SPKI */
@@ -3813,8 +3827,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
data_alloced = FALSE;
/* Decode PKCS#8 private key and add key attributes */
- rc = ibm_dilithium_priv_unwrap(dilithium_key_obj->template,
- data, data_len, FALSE);
+ rc = ibm_pqc_priv_unwrap(pqc_key_obj->template, keytype,
+ data, data_len, FALSE);
if (rc != CKR_OK) {
TRACE_ERROR("Failed to decode private key from CKA_VALUE.\n");
goto done;
@@ -3824,23 +3838,22 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
* padding is done in mechanism. This also adds the keyform and mode
* attributes to the template.
*/
- rc = ibm_dilithium_priv_wrap_get_data(dilithium_key_obj->template,
- FALSE, &data, &data_len);
+ rc = ibm_pqc_priv_wrap_get_data(pqc_key_obj->template, keytype,
+ FALSE, &data, &data_len);
if (rc != CKR_OK) {
- TRACE_DEVEL("%s Dilithium wrap get data failed\n", __func__);
+ TRACE_DEVEL("%s %s wrap get data failed\n", __func__,
+ key_type_str);
goto done;
}
/* Ensure both, keyform and mode attributes are added */
- oid = ibm_pqc_get_keyform_mode(dilithium_key_obj->template,
- CKM_IBM_DILITHIUM);
+ oid = ibm_pqc_get_keyform_mode(pqc_key_obj->template, pqc_mech);
if (oid == NULL) {
rc = CKR_TEMPLATE_INCOMPLETE;
goto done;
}
- rc = ibm_pqc_add_keyform_mode(dilithium_key_obj->template,
- oid, CKM_IBM_DILITHIUM);
+ rc = ibm_pqc_add_keyform_mode(pqc_key_obj->template, oid, pqc_mech);
if (rc != CKR_OK) {
TRACE_ERROR("ibm_pqc_add_keyform_mode failed\n");
goto done;
@@ -3849,8 +3862,8 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
/* encrypt */
RETRY_START(rc, tokdata)
- if (ep11_pqc_obj_strength_supported(target_info, CKM_IBM_DILITHIUM,
- dilithium_key_obj))
+ if (ep11_pqc_obj_strength_supported(target_info, pqc_mech,
+ pqc_key_obj))
rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
ep11_data->raw2key_wrap_blob_l,
&mech_w, data, data_len,
@@ -3870,8 +3883,7 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
- rc = check_key_attributes(tokdata, CKK_IBM_PQC_DILITHIUM,
- CKO_PRIVATE_KEY,
+ rc = check_key_attributes(tokdata, keytype, CKO_PRIVATE_KEY,
p_attrs, attrs_len,
&new_p_attrs, &new_attrs_len, -1);
if (rc != CKR_OK) {
@@ -3880,12 +3892,12 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
goto done;
}
- trace_attributes(__func__, "Dilithium import:", new_p_attrs, new_attrs_len);
+ trace_attributes(__func__, "PQC import:", new_p_attrs, new_attrs_len);
- ep11_get_pin_blob(ep11_session, object_is_session_object(dilithium_key_obj),
+ ep11_get_pin_blob(ep11_session, object_is_session_object(pqc_key_obj),
&ep11_pin_blob, &ep11_pin_blob_len);
- /* calls the card, it decrypts the private Dilithium key,
+ /* calls the card, it decrypts the private PQC key,
* reads its BER format and builds a blob.
*/
RETRY_START(rc, tokdata)
@@ -3908,12 +3920,20 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t *tokdata, SESSION *sess,
__func__, rc, *blob_size);
}
- cleanse_attribute(dilithium_key_obj->template, CKA_VALUE);
- cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_SEED);
- cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_TR);
- cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_S1);
- cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_S2);
- cleanse_attribute(dilithium_key_obj->template, CKA_IBM_DILITHIUM_T0);
+ cleanse_attribute(pqc_key_obj->template, CKA_VALUE);
+
+ switch (keytype) {
+ case CKK_IBM_PQC_DILITHIUM:
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_DILITHIUM_SEED);
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_DILITHIUM_TR);
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_DILITHIUM_S1);
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_DILITHIUM_S2);
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_DILITHIUM_T0);
+ break;
+ case CKK_IBM_PQC_KYBER:
+ cleanse_attribute(pqc_key_obj->template, CKA_IBM_KYBER_SK);
+ break;
+ }
}
done:
@@ -4020,15 +4040,16 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess,
__func__, rc, blobsize);
break;
case CKK_IBM_PQC_DILITHIUM:
- rc = import_IBM_Dilithium_key(tokdata, sess, obj, blob, &blobsize,
- spki, &spkisize);
+ case CKK_IBM_PQC_KYBER:
+ rc = import_IBM_pqc_key(tokdata, sess, obj, keytype, blob, &blobsize,
+ spki, &spkisize);
if (rc != CKR_OK) {
- TRACE_ERROR("%s import IBM Dilithium key rc=0x%lx blobsize=0x%zx\n",
- __func__, rc, blobsize);
+ TRACE_ERROR("%s import IBM PQC key kytype=0x%lx rc=0x%lx blobsize=0x%zx\n",
+ __func__, keytype, rc, blobsize);
return rc;
}
- TRACE_INFO("%s import IBM Dilithium key rc=0x%lx blobsize=0x%zx\n",
- __func__, rc, blobsize);
+ TRACE_INFO("%s import IBM PQC key kytype=0x%lx rc=0x%lx blobsize=0x%zx\n",
+ __func__, keytype, rc, blobsize);
break;
case CKK_DES2:
case CKK_DES3:
@@ -6582,10 +6603,10 @@ error:
return rc;
}
-static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
- SESSION *sess,
- CK_MECHANISM_PTR pMechanism,
- TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
+static CK_RV ibm_pqc_generate_keypair(STDLL_TokData_t *tokdata,
+ SESSION *sess,
+ CK_MECHANISM_PTR pMechanism,
+ TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
{
CK_RV rc;
CK_ATTRIBUTE *attr = NULL;
@@ -6593,7 +6614,7 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
size_t privkey_blob_len = sizeof(privkey_blob);
unsigned char spki[MAX_BLOBSIZE];
size_t spki_len = sizeof(spki);
- CK_ULONG ktype = CKK_IBM_PQC_DILITHIUM;
+ CK_ULONG ktype;
unsigned char *ep11_pin_blob = NULL;
CK_ULONG ep11_pin_blob_len = 0;
ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
@@ -6601,9 +6622,19 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
CK_ULONG new_publ_attrs_len = 0, new_priv_attrs_len = 0;
CK_ATTRIBUTE *new_publ_attrs2 = NULL, *new_priv_attrs2 = NULL;
CK_ULONG new_publ_attrs2_len = 0, new_priv_attrs2_len = 0;
- const struct pqc_oid *dilithium_oid;
+ const struct pqc_oid *pqc_oid;
+ const char *key_type_str;
- if (pMechanism->mechanism != CKM_IBM_DILITHIUM) {
+ switch (pMechanism->mechanism) {
+ case CKM_IBM_DILITHIUM:
+ key_type_str = "Dilithium";
+ ktype = CKK_IBM_PQC_DILITHIUM;
+ break;
+ case CKM_IBM_KYBER:
+ key_type_str = "Kyber";
+ ktype = CKK_IBM_PQC_KYBER;
+ break;
+ default:
TRACE_ERROR("Invalid mechanism provided for %s\n ", __func__);
return CKR_MECHANISM_INVALID;
}
@@ -6624,25 +6655,37 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
goto error;
}
- dilithium_oid = ibm_pqc_get_keyform_mode(publ_tmpl, CKM_IBM_DILITHIUM);
- if (dilithium_oid == NULL)
- dilithium_oid = ibm_pqc_get_keyform_mode(priv_tmpl, CKM_IBM_DILITHIUM);
- if (dilithium_oid == NULL)
- dilithium_oid = find_pqc_by_keyform(dilithium_oids,
- CK_IBM_DILITHIUM_KEYFORM_ROUND2_65);
- if (dilithium_oid == NULL) {
- TRACE_ERROR("%s Failed to determine Dilithium OID\n", __func__);
+ pqc_oid = ibm_pqc_get_keyform_mode(publ_tmpl, pMechanism->mechanism);
+ if (pqc_oid == NULL)
+ pqc_oid = ibm_pqc_get_keyform_mode(priv_tmpl, pMechanism->mechanism);
+ if (pqc_oid == NULL) {
+ switch (pMechanism->mechanism) {
+ case CKM_IBM_DILITHIUM:
+ pqc_oid = find_pqc_by_keyform(dilithium_oids,
+ CK_IBM_DILITHIUM_KEYFORM_ROUND2_65);
+ break;
+ case CKM_IBM_KYBER:
+ pqc_oid = find_pqc_by_keyform(kyber_oids,
+ CK_IBM_KYBER_KEYFORM_ROUND2_1024);
+ break;
+ default:
+ /* pqc_oid stays NULL */
+ break;
+ }
+ }
+ if (pqc_oid == NULL) {
+ TRACE_ERROR("%s Failed to determine %s OID\n", __func__, key_type_str);
rc = CKR_FUNCTION_FAILED;
goto error;
}
- TRACE_INFO("%s Generate Dilithium key with keyform %lu\n", __func__,
- dilithium_oid->keyform);
+ TRACE_INFO("%s Generate %s key with keyform %lu\n", __func__, key_type_str,
+ pqc_oid->keyform);
rc = add_to_attribute_array(&new_publ_attrs, &new_publ_attrs_len,
CKA_IBM_PQC_PARAMS,
- (CK_BYTE *)dilithium_oid->oid,
- dilithium_oid->oid_len);
+ (CK_BYTE *)pqc_oid->oid,
+ pqc_oid->oid_len);
if (rc != CKR_OK) {
TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
__func__, rc);
@@ -6651,8 +6694,8 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
rc = add_to_attribute_array(&new_priv_attrs, &new_priv_attrs_len,
CKA_IBM_PQC_PARAMS,
- (CK_BYTE *)dilithium_oid->oid,
- dilithium_oid->oid_len);
+ (CK_BYTE *)pqc_oid->oid,
+ pqc_oid->oid_len);
if (rc != CKR_OK) {
TRACE_ERROR("%s add_to_attribute_array failed with rc=0x%lx\n",
__func__, rc);
@@ -6663,8 +6706,8 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
new_publ_attrs, new_publ_attrs_len,
&new_publ_attrs2, &new_publ_attrs2_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s Dilithium check public key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s %s check public key attributes failed with "
+ "rc=0x%lx\n", __func__, key_type_str, rc);
goto error;
}
@@ -6672,14 +6715,14 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
new_priv_attrs, new_priv_attrs_len,
&new_priv_attrs2, &new_priv_attrs2_len, -1);
if (rc != CKR_OK) {
- TRACE_ERROR("%s Dilithium check private key attributes failed with "
- "rc=0x%lx\n", __func__, rc);
+ TRACE_ERROR("%s %s check private key attributes failed with "
+ "rc=0x%lx\n", __func__, key_type_str, rc);
goto error;
}
- trace_attributes(__func__, "Dilithium public key attributes:",
+ trace_attributes(__func__, "PQC public key attributes:",
new_publ_attrs2, new_publ_attrs2_len);
- trace_attributes(__func__, "Dilithium private key attributes:",
+ trace_attributes(__func__, "PQC private key attributes:",
new_priv_attrs2, new_priv_attrs2_len);
ep11_get_pin_blob(ep11_session,
@@ -6691,7 +6734,7 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
RETRY_START(rc, tokdata)
if (ep11_pqc_strength_supported(target_info, pMechanism->mechanism,
- dilithium_oid))
+ pqc_oid))
rc = dll_m_GenerateKeyPair(pMechanism,
new_publ_attrs2, new_publ_attrs2_len,
new_priv_attrs2, new_priv_attrs2_len,
@@ -6752,16 +6795,18 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t *tokdata,
goto error;
}
- rc = ibm_dilithium_priv_unwrap_get_data(publ_tmpl, spki, spki_len, TRUE);
+ rc = ibm_pqc_priv_unwrap_get_data(publ_tmpl, ktype,
+ spki, spki_len, TRUE);
if (rc != CKR_OK) {
- TRACE_ERROR("%s ibm_dilithium_priv_unwrap_get_data with rc=0x%lx\n",
+ TRACE_ERROR("%s ibm_pqc_priv_unwrap_get_data with rc=0x%lx\n",
__func__, rc);
goto error;
}
- rc = ibm_dilithium_priv_unwrap_get_data(priv_tmpl, spki, spki_len, FALSE);
+ rc = ibm_pqc_priv_unwrap_get_data(priv_tmpl, ktype,
+ spki, spki_len, FALSE);
if (rc != CKR_OK) {
- TRACE_ERROR("%s ibm_dilithium_priv_unwrap_get_data with rc=0x%lx\n",
+ TRACE_ERROR("%s ibm_pqc_priv_unwrap_get_data with rc=0x%lx\n",
__func__, rc);
goto error;
}
@@ -6854,9 +6899,10 @@ CK_RV ep11tok_generate_key_pair(STDLL_TokData_t * tokdata, SESSION * sess,
private_key_obj->template);
break;
case CKM_IBM_DILITHIUM:
- rc = ibm_dilithium_generate_keypair(tokdata, sess, pMechanism,
- public_key_obj->template,
- private_key_obj->template);
+ case CKM_IBM_KYBER:
+ rc = ibm_pqc_generate_keypair(tokdata, sess, pMechanism,
+ public_key_obj->template,
+ private_key_obj->template);
break;
default:
TRACE_ERROR("%s invalid mech %s\n", __func__,
--
2.16.2.windows.1

View File

@ -1,339 +0,0 @@
From 51ed2d7171e5423cfec86c36ffa32e8e9e0de01c Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 1 Mar 2022 16:55:01 +0100
Subject: [PATCH 27/34] EP11: Add support for encrypt/decrypt and KEM
operations with Kyber
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 174 ++++++++++++++++++++++++++++++++++---
usr/lib/ep11_stdll/new_host.c | 24 +++--
2 files changed, 180 insertions(+), 18 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index bc17b07a..9efce053 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -5196,6 +5196,126 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata,
return rc;
}
+struct EP11_KYBER_MECH {
+ CK_MECHANISM mech;
+ struct XCP_KYBER_KEM_PARAMS params;
+};
+
+static CK_RV ep11tok_kyber_mech_pre_process(STDLL_TokData_t *tokdata,
+ CK_MECHANISM *mech,
+ struct EP11_KYBER_MECH *mech_ep11,
+ OBJECT **secret_key_obj)
+{
+ CK_IBM_KYBER_PARAMS *kyber_params;
+ CK_RV rc;
+
+ kyber_params = mech->pParameter;
+ if (mech->ulParameterLen != sizeof(CK_IBM_KYBER_PARAMS)) {
+ TRACE_ERROR("Mechanism parameter length not as expected\n");
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ if (kyber_params->ulVersion != CK_IBM_KYBER_KEM_VERSION) {
+ TRACE_ERROR("Unsupported version in Kyber mechanism param\n");
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ mech_ep11->mech.mechanism = mech->mechanism;
+ mech_ep11->mech.pParameter = &mech_ep11->params;
+ mech_ep11->mech.ulParameterLen = sizeof(mech_ep11->params);
+
+ memset(&mech_ep11->params, 0, sizeof(mech_ep11->params));
+ mech_ep11->params.version = XCP_KYBER_KEM_VERSION;
+ mech_ep11->params.mode = kyber_params->mode;
+ mech_ep11->params.kdf = kyber_params->kdf;
+ mech_ep11->params.prepend = kyber_params->bPrepend;
+ mech_ep11->params.pSharedData = kyber_params->pSharedData;
+ mech_ep11->params.ulSharedDataLen = kyber_params->ulSharedDataLen;
+
+ switch (kyber_params->mode) {
+ case CK_IBM_KYBER_KEM_ENCAPSULATE:
+ if (kyber_params->ulCipherLen > 0 && kyber_params->pCipher == NULL) {
+ TRACE_ERROR("Unsupported cipher buffer in Kyber mechnism param "
+ "cannot be NULL\n");
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ mech_ep11->params.pCipher = NULL;
+ mech_ep11->params.ulCipherLen = 0;
+ /* Cipher is returned in 2nd output param of m_DeriveKey */
+ break;
+
+ case CK_IBM_KEM_DECAPSULATE:
+ mech_ep11->params.pCipher = kyber_params->pCipher;
+ mech_ep11->params.ulCipherLen = kyber_params->ulCipherLen;
+ break;
+
+ default:
+ TRACE_ERROR("Unsupported mode in Kyber mechanism param\n");
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ if (kyber_params->bPrepend) {
+ rc = h_opaque_2_blob(tokdata, kyber_params->hSecret,
+ &mech_ep11->params.pBlob,
+ &mech_ep11->params.ulBlobLen,
+ secret_key_obj, READ_LOCK);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s failed hSecret=0x%lx\n", __func__,
+ kyber_params->hSecret);
+ return rc;
+ }
+ }
+
+ return CKR_OK;
+}
+
+static CK_RV ep11tok_kyber_mech_post_process(STDLL_TokData_t *tokdata,
+ CK_MECHANISM *mech,
+ CK_BYTE *csum, CK_ULONG cslen)
+{
+ CK_IBM_KYBER_PARAMS *kyber_params;
+ CK_ULONG cipher_len;
+
+ UNUSED(tokdata);
+
+ kyber_params = mech->pParameter;
+ if (mech->ulParameterLen != sizeof(CK_IBM_KYBER_PARAMS)) {
+ TRACE_ERROR("Mechanism parameter length not as expected\n");
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ if (kyber_params->mode != CK_IBM_KYBER_KEM_ENCAPSULATE)
+ return CKR_OK;
+
+ /*
+ * For encapsulate:
+ * Generated cipher is returned in csum prepended with the checksum of
+ * the generated symmetric key and its bit count (in total 7 bytes).
+ */
+ if (cslen < EP11_CSUMSIZE + 4) {
+ TRACE_ERROR("%s returned cipher size is invalid: %lu\n",
+ __func__, cslen);
+ return CKR_FUNCTION_FAILED;
+ }
+
+ cipher_len = cslen - (EP11_CSUMSIZE + 4);
+
+ if (kyber_params->ulCipherLen < cipher_len) {
+ TRACE_ERROR("%s Cipher buffer in kyber mechanism param too small, required: %lu\n",
+ __func__, cipher_len);
+ kyber_params->ulCipherLen = cipher_len;
+ OPENSSL_cleanse(&csum[EP11_CSUMSIZE + 4], cipher_len);
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ memcpy(kyber_params->pCipher, &csum[EP11_CSUMSIZE + 4], cipher_len);
+ kyber_params->ulCipherLen = cipher_len;
+
+ OPENSSL_cleanse(&csum[EP11_CSUMSIZE + 4], cipher_len);
+ return CKR_OK;
+}
+
CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE hBaseKey,
CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs,
@@ -5236,6 +5356,8 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
CK_BYTE *spki = NULL;
CK_ULONG spki_length = 0;
CK_ATTRIBUTE *spki_attr = NULL;
+ struct EP11_KYBER_MECH mech_ep11;
+ OBJECT *kyber_secret_obj = NULL;
memset(newblob, 0, sizeof(newblob));
@@ -5517,16 +5639,29 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
}
+ if (mech->mechanism == CKM_IBM_KYBER) {
+ rc = ep11tok_kyber_mech_pre_process(tokdata, mech, &mech_ep11,
+ &kyber_secret_obj);
+ if (rc != CKR_OK)
+ goto error;
+ mech = &mech_ep11.mech;
+ }
+
trace_attributes(__func__, "Derive:", new_attrs2, new_attrs2_len);
ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len),
&ep11_pin_blob, &ep11_pin_blob_len);
RETRY_START(rc, tokdata)
- rc =
- dll_m_DeriveKey(mech, new_attrs2, new_attrs2_len, keyblob, keyblobsize,
- NULL, 0, ep11_pin_blob, ep11_pin_blob_len, newblob,
- &newblobsize, csum, &cslen, target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ base_key_obj))
+ rc = dll_m_DeriveKey(mech, new_attrs2, new_attrs2_len,
+ keyblob, keyblobsize, NULL, 0,
+ ep11_pin_blob, ep11_pin_blob_len, newblob,
+ &newblobsize, csum, &cslen,
+ target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
@@ -5610,6 +5745,12 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
}
+ if (mech->mechanism == CKM_IBM_KYBER) {
+ rc = ep11tok_kyber_mech_post_process(tokdata, mech_orig, csum, cslen);
+ if (rc != CKR_OK)
+ goto error;
+ }
+
if (class == CKO_SECRET_KEY && cslen >= EP11_CSUMSIZE) {
/* First 3 bytes of csum is the check value */
rc = build_attribute(CKA_CHECK_VALUE, csum, EP11_CSUMSIZE, &chk_attr);
@@ -5666,6 +5807,8 @@ error:
object_put(tokdata, base_key_obj, TRUE);
base_key_obj = NULL;
+ object_put(tokdata, kyber_secret_obj, TRUE);
+ kyber_secret_obj = NULL;
return rc;
}
@@ -7399,6 +7542,7 @@ CK_BOOL ep11tok_mech_single_only(CK_MECHANISM *mech)
{
switch (mech->mechanism) {
case CKM_IBM_ECDSA_OTHER:
+ case CKM_IBM_KYBER:
return CK_TRUE;
default:
return CK_FALSE;
@@ -8301,9 +8445,14 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_DecryptSingle(keyblob, keyblobsize, mech, input_data,
- input_data_len, output_data, p_output_data_len,
- target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_DecryptSingle(keyblob, keyblobsize, mech, input_data,
+ input_data_len, output_data,
+ p_output_data_len,
+ target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
rc = ep11_error_to_pkcs11_error(rc, session);
@@ -8511,9 +8660,14 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
}
RETRY_START(rc, tokdata)
- rc = dll_m_EncryptSingle(keyblob, keyblobsize, mech, input_data,
- input_data_len, output_data, p_output_data_len,
- target_info->target);
+ if (ep11_pqc_obj_strength_supported(target_info, mech->mechanism,
+ key_obj))
+ rc = dll_m_EncryptSingle(keyblob, keyblobsize, mech, input_data,
+ input_data_len, output_data,
+ p_output_data_len,
+ target_info->target);
+ else
+ rc = CKR_KEY_SIZE_RANGE;
RETRY_END(rc, tokdata, session)
if (rc != CKR_OK) {
rc = ep11_error_to_pkcs11_error(rc, session);
diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c
index dccdfe96..60027c85 100644
--- a/usr/lib/ep11_stdll/new_host.c
+++ b/usr/lib/ep11_stdll/new_host.c
@@ -2061,7 +2061,8 @@ CK_RV SC_EncryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->encr_ctx.multi_init = FALSE;
sess->encr_ctx.multi = FALSE;
- if (ep11tok_optimize_single_ops(tokdata) &&
+ if ((ep11tok_optimize_single_ops(tokdata) ||
+ ep11tok_mech_single_only(pMechanism)) &&
!ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
/* In case of a single part encrypt operation we don't need the
* EncryptInit, instead we can use the EncryptSingle which is much
@@ -2159,7 +2160,8 @@ CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
- if (ep11tok_optimize_single_ops(tokdata) &&
+ if ((ep11tok_optimize_single_ops(tokdata) ||
+ ep11tok_mech_single_only(&sess->encr_ctx.mech)) &&
!ep11tok_pkey_usage_ok(tokdata, sess, sess->encr_ctx.key, &sess->encr_ctx.mech)) {
rc = ep11tok_encrypt_single(tokdata, sess, &sess->encr_ctx.mech,
length_only, sess->encr_ctx.key,
@@ -2217,7 +2219,8 @@ CK_RV SC_EncryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
- if (sess->encr_ctx.active == FALSE) {
+ if (sess->encr_ctx.active == FALSE ||
+ ep11tok_mech_single_only(&sess->encr_ctx.mech)) {
TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
rc = CKR_OPERATION_NOT_INITIALIZED;
goto done;
@@ -2293,7 +2296,8 @@ CK_RV SC_EncryptFinal(STDLL_TokData_t * tokdata, ST_SESSION_HANDLE * sSession,
goto done;
}
- if (sess->encr_ctx.active == FALSE) {
+ if (sess->encr_ctx.active == FALSE ||
+ ep11tok_mech_single_only(&sess->encr_ctx.mech)) {
TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
rc = CKR_OPERATION_NOT_INITIALIZED;
goto done;
@@ -2385,7 +2389,8 @@ CK_RV SC_DecryptInit(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
sess->decr_ctx.multi_init = FALSE;
sess->decr_ctx.multi = FALSE;
- if (ep11tok_optimize_single_ops(tokdata) &&
+ if ((ep11tok_optimize_single_ops(tokdata) ||
+ ep11tok_mech_single_only(pMechanism)) &&
!ep11tok_pkey_usage_ok(tokdata, sess, hKey, pMechanism)) {
/* In case of a single part decrypt operation we don't need the
* DecryptInit, instead we can use the EncryptSingle which is much
@@ -2483,7 +2488,8 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
- if (ep11tok_optimize_single_ops(tokdata) &&
+ if ((ep11tok_optimize_single_ops(tokdata) ||
+ ep11tok_mech_single_only(&sess->decr_ctx.mech)) &&
!ep11tok_pkey_usage_ok(tokdata, sess, sess->decr_ctx.key, &sess->decr_ctx.mech)) {
rc = ep11tok_decrypt_single(tokdata, sess, &sess->decr_ctx.mech,
length_only, sess->decr_ctx.key,
@@ -2541,7 +2547,8 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
- if (sess->decr_ctx.active == FALSE) {
+ if (sess->decr_ctx.active == FALSE ||
+ ep11tok_mech_single_only(&sess->decr_ctx.mech)) {
TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
rc = CKR_OPERATION_NOT_INITIALIZED;
goto done;
@@ -2617,7 +2624,8 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
goto done;
}
- if (sess->decr_ctx.active == FALSE) {
+ if (sess->decr_ctx.active == FALSE ||
+ ep11tok_mech_single_only(&sess->decr_ctx.mech)) {
TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED));
rc = CKR_OPERATION_NOT_INITIALIZED;
goto done;
--
2.16.2.windows.1

View File

@ -1,259 +0,0 @@
From 181b11362e95ff8ac4e812073c8f7267a02f1bf1 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 2 Mar 2022 16:44:27 +0100
Subject: [PATCH 28/34] POLICY/STATISTICS: Check for Kyber KEM KDFs and count
KDF digest usage
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
man/man5/policy.conf.5.in | 2 +-
tools/policyexamplegen.c | 8 ++++++-
usr/lib/api/policy.c | 45 ++++++++++++++++++++++++++++++++++++----
usr/lib/api/statistics.c | 20 +++++++++++++++++-
usr/lib/common/kdf_translation.c | 30 +++++++++++++++++++++++++++
usr/lib/common/utility_common.c | 5 +++++
6 files changed, 103 insertions(+), 7 deletions(-)
diff --git a/man/man5/policy.conf.5.in b/man/man5/policy.conf.5.in
index 0b8bed27..c04b2adf 100644
--- a/man/man5/policy.conf.5.in
+++ b/man/man5/policy.conf.5.in
@@ -133,7 +133,7 @@ empty list allows no MGF.
.BR allowedkdfs
This key specifies the allowed Key Derivation Functions (KDFs) for use
-in ECDH key derivation. The value is a list of
+in ECDH key derivation and Kyber KEM. The value is a list of
.BR CKD_
constants supported by openCryptoki. This list has the same format as
the
diff --git a/tools/policyexamplegen.c b/tools/policyexamplegen.c
index 1649fc05..362acdf9 100644
--- a/tools/policyexamplegen.c
+++ b/tools/policyexamplegen.c
@@ -99,7 +99,13 @@ int main(void)
puts(" CKD_SHA224_KDF,");
puts(" CKD_SHA256_KDF,");
puts(" CKD_SHA384_KDF,");
- puts(" CKD_SHA512_KDF");
+ puts(" CKD_SHA512_KDF,");
+ puts(" CKD_IBM_HYBRID_NULL,");
+ puts(" CKD_IBM_HYBRID_SHA1_KDF,");
+ puts(" CKD_IBM_HYBRID_SHA224_KDF,");
+ puts(" CKD_IBM_HYBRID_SHA256_KDF,");
+ puts(" CKD_IBM_HYBRID_SHA384_KDF,");
+ puts(" CKD_IBM_HYBRID_SHA512_KDF");
puts(" # No comma after last element!");
puts(")");
puts("");
diff --git a/usr/lib/api/policy.c b/usr/lib/api/policy.c
index b513a8a9..8189dab0 100644
--- a/usr/lib/api/policy.c
+++ b/usr/lib/api/policy.c
@@ -70,6 +70,7 @@ struct policy_private {
CK_ULONG allowedmgfs;
CK_ULONG allowedvendormgfs;
CK_ULONG allowedkdfs;
+ CK_ULONG allowedvendorkdfs;
CK_ULONG allowedprfs;
CK_ULONG maxcurvesize;
/* Strength struct ordered from highest to lowest. */
@@ -105,6 +106,7 @@ void policy_private_deactivate(struct policy_private *pp)
pp->allowedmgfs = ~0lu;
pp->allowedvendormgfs = ~0lu;
pp->allowedkdfs = ~0lu;
+ pp->allowedvendorkdfs = ~0lu;
pp->allowedprfs = ~0lu;
pp->maxcurvesize = 521u;
}
@@ -496,8 +498,14 @@ static inline CK_RV policy_is_mgf_allowed(struct policy_private *pp,
static inline CK_RV policy_is_kdf_allowed(struct policy_private *pp,
CK_ULONG kdf)
{
- if (pp->allowedkdfs & (1u << kdf))
- return CKR_OK;
+ if (kdf > CKD_VENDOR_DEFINED) {
+ if ((kdf - CKD_VENDOR_DEFINED - 1) <= 31 &&
+ (pp->allowedvendorkdfs & (1u << (kdf - CKD_VENDOR_DEFINED - 1))))
+ return CKR_OK;
+ } else {
+ if (kdf <= 31 && (pp->allowedkdfs & (1u << kdf)))
+ return CKR_OK;
+ }
TRACE_WARNING("POLICY VIOLATION: kdf not allowed: 0x%lx\n", kdf);
return CKR_FUNCTION_FAILED;
}
@@ -920,6 +928,16 @@ static CK_RV policy_is_mech_allowed(policy_t p, CK_MECHANISM_PTR mech,
break;
}
break;
+ case CKM_IBM_KYBER:
+ /* Only KEM uses a parameter, KeyGen, Encrypt/Decrypt don't */
+ if (mech->ulParameterLen != sizeof(CK_IBM_KYBER_PARAMS))
+ break;
+ if (policy_is_kdf_allowed(pp,
+ ((CK_IBM_KYBER_PARAMS *)mech->pParameter)->kdf) != CKR_OK) {
+ rv = CKR_FUNCTION_FAILED;
+ break;
+ }
+ break;
default:
break;
}
@@ -1533,7 +1551,7 @@ static CK_RV policy_parse_kdfs(struct policy_private *pp,
struct ConfigBaseNode *list)
{
struct ConfigBaseNode *i;
- CK_ULONG kdfs = 0, kdf;
+ CK_ULONG kdfs = 0, vkdfs = 0, kdf;
CK_RV rc = CKR_OK;
int f;
@@ -1545,10 +1563,28 @@ static CK_RV policy_parse_kdfs(struct policy_private *pp,
i->key, i->line);
break;
}
- kdfs |= (1u << kdf);
+
+ if (kdf >= CKD_VENDOR_DEFINED) {
+ if ((kdf - CKD_VENDOR_DEFINED - 1) > 31) {
+ TRACE_ERROR("POLICY: KDF invalid: \"%s\" (line %hd)\n",
+ i->key, i->line);
+ rc = CKR_FUNCTION_FAILED;
+ break;
+ }
+ vkdfs |= (1u << (kdf - CKD_VENDOR_DEFINED - 1));
+ } else {
+ if (kdf > 31) {
+ TRACE_ERROR("POLICY: KDF invalid: \"%s\" (line %hd)\n",
+ i->key, i->line);
+ rc = CKR_FUNCTION_FAILED;
+ break;
+ }
+ kdfs |= (1u << kdf);
+ }
}
}
pp->allowedkdfs = kdfs;
+ pp->allowedvendorkdfs = vkdfs;
return rc;
}
@@ -1742,6 +1778,7 @@ CK_RV policy_load_policy_cfg(struct policy_private *pp,
if (!allowedkdfs) {
TRACE_DEVEL("POLICY: No KDF restrictions\n");
pp->allowedkdfs = ~0u;
+ pp->allowedvendorkdfs = ~0u;
} else if (!confignode_hastype(allowedkdfs, CT_BARELIST)) {
TRACE_ERROR("POLICY: allowedkdfs has wrong type!\n");
OCK_SYSLOG(LOG_ERR, "POLICY: allowedkdfs has wrong type!\n");
diff --git a/usr/lib/api/statistics.c b/usr/lib/api/statistics.c
index 0830bbeb..e34dfcee 100644
--- a/usr/lib/api/statistics.c
+++ b/usr/lib/api/statistics.c
@@ -110,7 +110,8 @@ static CK_RV statistics_increment(struct statistics *statistics,
if (mech->pParameter == NULL ||
mech->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS))
return CKR_MECHANISM_PARAM_INVALID;
- if (((CK_ECDH1_DERIVE_PARAMS *)mech->pParameter)->kdf == CKD_NULL)
+ if (((CK_ECDH1_DERIVE_PARAMS *)mech->pParameter)->kdf == CKD_NULL ||
+ ((CK_ECDH1_DERIVE_PARAMS *)mech->pParameter)->kdf == CKD_IBM_HYBRID_NULL)
break;
rc = digest_from_kdf(((CK_ECDH1_DERIVE_PARAMS *)mech->pParameter)->kdf,
&implicit_mech.mechanism);
@@ -156,6 +157,23 @@ static CK_RV statistics_increment(struct statistics *statistics,
break;
}
break;
+ case CKM_IBM_KYBER:
+ /* Only KEM uses a parameter, KeyGen, Encrypt/Decrypt don't */
+ if (mech->ulParameterLen != sizeof(CK_IBM_KYBER_PARAMS))
+ break;
+ if (((CK_IBM_KYBER_PARAMS *)mech->pParameter)->kdf == CKD_NULL ||
+ ((CK_IBM_KYBER_PARAMS *)mech->pParameter)->kdf == CKD_IBM_HYBRID_NULL)
+ break;
+ rc = digest_from_kdf(((CK_IBM_KYBER_PARAMS *)mech->pParameter)->kdf,
+ &implicit_mech.mechanism);
+ if (rc != CKR_OK)
+ return rc;
+ rc = statistics_increment(statistics, slot, &implicit_mech,
+ POLICY_STRENGTH_IDX_0);
+ if (rc != CKR_OK)
+ return rc;
+ break;
+
default:
break;
}
diff --git a/usr/lib/common/kdf_translation.c b/usr/lib/common/kdf_translation.c
index 707cb912..f563234f 100644
--- a/usr/lib/common/kdf_translation.c
+++ b/usr/lib/common/kdf_translation.c
@@ -55,6 +55,36 @@ CK_RV translate_string_to_kdf(const char *str, size_t len, CK_ULONG* kdf)
return CKR_OK;
}
return CKR_FUNCTION_FAILED;
+ case 19:
+ if (strcmp("CKD_IBM_HYBRID_NULL", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_NULL;
+ return CKR_OK;
+ }
+ return CKR_FUNCTION_FAILED;
+ case 23:
+ if (strcmp("CKD_IBM_HYBRID_SHA1_KDF", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_SHA1_KDF;
+ return CKR_OK;
+ }
+ return CKR_FUNCTION_FAILED;
+ case 25:
+ if (strcmp("CKD_IBM_HYBRID_SHA224_KDF", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_SHA224_KDF;
+ return CKR_OK;
+ }
+ if (strcmp("CKD_IBM_HYBRID_SHA256_KDF", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_SHA256_KDF;
+ return CKR_OK;
+ }
+ if (strcmp("CKD_IBM_HYBRID_SHA384_KDF", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_SHA384_KDF;
+ return CKR_OK;
+ }
+ if (strcmp("CKD_IBM_HYBRID_SHA512_KDF", str) == 0) {
+ *kdf = CKD_IBM_HYBRID_SHA512_KDF;
+ return CKR_OK;
+ }
+ return CKR_FUNCTION_FAILED;
default:
return CKR_FUNCTION_FAILED;
}
diff --git a/usr/lib/common/utility_common.c b/usr/lib/common/utility_common.c
index 8d03c699..49ab609f 100644
--- a/usr/lib/common/utility_common.c
+++ b/usr/lib/common/utility_common.c
@@ -169,18 +169,23 @@ CK_RV digest_from_kdf(CK_EC_KDF_TYPE kdf, CK_MECHANISM_TYPE *mech)
{
switch (kdf) {
case CKD_SHA1_KDF:
+ case CKD_IBM_HYBRID_SHA1_KDF:
*mech = CKM_SHA_1;
break;
case CKD_SHA224_KDF:
+ case CKD_IBM_HYBRID_SHA224_KDF:
*mech = CKM_SHA224;
break;
case CKD_SHA256_KDF:
+ case CKD_IBM_HYBRID_SHA256_KDF:
*mech = CKM_SHA256;
break;
case CKD_SHA384_KDF:
+ case CKD_IBM_HYBRID_SHA384_KDF:
*mech = CKM_SHA384;
break;
case CKD_SHA512_KDF:
+ case CKD_IBM_HYBRID_SHA512_KDF:
*mech = CKM_SHA512;
break;
default:
--
2.16.2.windows.1

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +0,0 @@
From 3f8b4270a7601b42f15f13f54b9b5fc207a14723 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 8 Nov 2022 16:46:26 +0100
Subject: [PATCH 30/34] p11sak: Support additional Dilithium variants
Support the following Dilithium versions to be specified with the
generate-key command: r2_65 (as of today), r2_87, r3_44, r3_65, r3_87.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
man/man1/p11sak.1.in | 12 ++++++++++-
usr/sbin/p11sak/p11sak.c | 53 ++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/man/man1/p11sak.1.in b/man/man1/p11sak.1.in
index a2c2b879..6938b203 100644
--- a/man/man1/p11sak.1.in
+++ b/man/man1/p11sak.1.in
@@ -262,7 +262,7 @@ Use the
command and key argument to generate an IBM Dilithium key, where
.I VERSION
specifies the version of the IBM Dilithium keypair. The following arguments can be used for respective keys:
-.B r2_65
+.B r2_65 | r2_87 | r3_44 | r3_65 | r3_87
.PP
The
.B \-\-slot
@@ -368,6 +368,16 @@ to select the EC curve used to generate the key.
.
.
+.SS "r2_6|r2_87|r3_44|r3_65|r3_875"
+the
+.B ibm-dilithium
+argument has to be followed by either of these
+.I VERSION
+to select the IBM dilithium version used to generate the key.
+.PP
+.
+.
+.
.SH OPTIONS
.SS "\-\-slot SLOTID"
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 8cfcb21d..5ceb145b 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -387,7 +387,7 @@ static void print_gen_help(void)
printf(" brainpoolP320r1 | brainpoolP320t1 | brainpoolP384r1 | brainpoolP384t1 | \n");
printf(" brainpoolP512r1 | brainpoolP512t1 | curve25519 | curve448 | ed25519 | \n");
printf(" ed448]\n");
- printf(" ibm-dilithium [r2_65]\n");
+ printf(" ibm-dilithium [r2_65 | r2_87 | r3_44 | r3_65 | r3_87]\n");
printf("\n Options:\n");
printf(
" --slot SLOTID openCryptoki repository token SLOTID.\n");
@@ -526,6 +526,10 @@ static void print_gen_ibm_dilithium_help(void)
printf("\n Usage: p11sak generate-key ibm-dilithium [ARGS] [OPTIONS]\n");
printf("\n Args:\n");
printf(" r2_65\n");
+ printf(" r2_87\n");
+ printf(" r3_44\n");
+ printf(" r3_65\n");
+ printf(" r3_87\n");
printf("\n Options:\n");
printf(
" --slot SLOTID openCryptoki repository token SLOTID.\n");
@@ -764,6 +768,35 @@ static CK_RV read_ec_args(const char *ECcurve, CK_ATTRIBUTE *pubattr,
return CKR_OK;
}
+/**
+ * Builds the CKA_IBM_DILITHIUM_KEYFORM attribute from the given version.
+ */
+static CK_RV read_dilithium_args(const char *dilithium_ver, CK_ULONG *keyform,
+ CK_ATTRIBUTE *pubattr, CK_ULONG *pubcount)
+{
+ if (strcasecmp(dilithium_ver, "r2_65") == 0) {
+ *keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_65;
+ } else if (strcasecmp(dilithium_ver, "r2_87") == 0) {
+ *keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND2_87;
+ } else if (strcasecmp(dilithium_ver, "r3_44") == 0) {
+ *keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_44;
+ } else if (strcasecmp(dilithium_ver, "r3_65") == 0) {
+ *keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_65;
+ } else if (strcasecmp(dilithium_ver, "r3_87") == 0) {
+ *keyform = CK_IBM_DILITHIUM_KEYFORM_ROUND3_87;
+ } else {
+ fprintf(stderr, "Unexpected case while parsing dilithium version.\n");
+ fprintf(stderr, "Note: not all tokens support all versions.\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ pubattr[*pubcount].type = CKA_IBM_DILITHIUM_KEYFORM;
+ pubattr[*pubcount].ulValueLen = sizeof(CK_ULONG);
+ pubattr[*pubcount].pValue = keyform;
+ (*pubcount)++;
+
+ return CKR_OK;
+}
/**
* Builds two CKA_LABEL attributes from given label.
*/
@@ -1096,6 +1129,8 @@ static CK_RV key_pair_gen(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
if (rc != CKR_OK) {
if (is_rejected_by_policy(rc, session))
fprintf(stderr, "Key pair generation rejected by policy\n");
+ else if (kt == kt_IBM_DILITHIUM && rc == CKR_KEY_SIZE_RANGE)
+ fprintf(stderr, "IBM Dilithum version is not supported\n");
else
fprintf(stderr, "Key pair generation failed (error code 0x%lX: %s)\n", rc,
p11_get_ckr(rc));
@@ -1845,11 +1880,15 @@ static CK_RV check_args_gen_key(p11sak_kt *kt, CK_ULONG keylength,
case kt_IBM_DILITHIUM:
if (dilithium_ver == NULL) {
fprintf(stderr,
- "Cipher key type [%d] supported but Dilithium version not set in arguments. Try adding argument <r2_65>\n",
+ "Cipher key type [%d] supported but Dilithium version not set in arguments. Try adding argument <r2_65>, <r2_87>, <r3_44>, <r3_65>, or <r3_87>\n",
*kt);
return CKR_ARGUMENTS_BAD;
}
- if (strcasecmp(dilithium_ver, "r2_65") == 0) {
+ if (strcasecmp(dilithium_ver, "r2_65") == 0 ||
+ strcasecmp(dilithium_ver, "r2_87") == 0 ||
+ strcasecmp(dilithium_ver, "r3_44") == 0 ||
+ strcasecmp(dilithium_ver, "r3_65") == 0 ||
+ strcasecmp(dilithium_ver, "r3_87") == 0) {
break;
} else {
fprintf(stderr, "IBM Dilithium version [%s] not supported \n", dilithium_ver);
@@ -2450,7 +2489,7 @@ static CK_RV generate_asymmetric_key(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
CK_ATTRIBUTE prv_attr[KEY_MAX_BOOL_ATTR_COUNT + 2];
CK_ULONG prv_acount = 0;
CK_MECHANISM mech;
- CK_ULONG i;
+ CK_ULONG i, keyform;
CK_RV rc;
const char separator = ':';
@@ -2475,6 +2514,12 @@ static CK_RV generate_asymmetric_key(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
}
break;
case kt_IBM_DILITHIUM:
+ rc = read_dilithium_args(dilithium_ver, &keyform,
+ pub_attr, &pub_acount);
+ if (rc) {
+ fprintf(stderr, "Error parsing Dilithium parameters!\n");
+ goto done;
+ }
printf("Generating Dilithium keypair with %s\n", dilithium_ver);
break;
default:
--
2.16.2.windows.1

View File

@ -1,551 +0,0 @@
From d257df88500b3e55156d198ec305042799e2bff9 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue, 8 Nov 2022 17:03:11 +0100
Subject: [PATCH 31/34] p11sak: Add support for IBM Kyber key type
Support the following Kyber versions to be specified with the
generate-key command: r2_768, r2_1024.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
man/man1/p11sak.1.in | 65 ++++++++++++--
usr/sbin/p11sak/p11sak.c | 141 +++++++++++++++++++++++++-----
usr/sbin/p11sak/p11sak.h | 1 +
usr/sbin/p11sak/p11sak_defined_attrs.conf | 6 +-
4 files changed, 183 insertions(+), 30 deletions(-)
diff --git a/man/man1/p11sak.1.in b/man/man1/p11sak.1.in
index 6938b203..2b75b117 100644
--- a/man/man1/p11sak.1.in
+++ b/man/man1/p11sak.1.in
@@ -16,7 +16,7 @@ p11sak \- generate and list token keys in an openCryptoki token repository.
.SH DESCRIPTION
.B p11sak can be used to generate, list and delete the token keys in an openCryptoki token repository.
-The utility provides a flexible key management tool in openCryptoki to list and generate symmetric (DES; 3DES, AES) and asymetric (RSA, EC) keys.
+The utility provides a flexible key management tool in openCryptoki to list and generate symmetric (DES, 3DES, AES) and asymmetric (RSA, EC, IBM Dilithium, IBM Kyber) keys.
This tool is especially capable of a well defined listing of keys with their PKCS #11 attributes.
.
.
@@ -282,11 +282,54 @@ attribute of the key and
can be used to set the binary attributes of the key (see below for detailed description of the attributes).
.
.PP
+.SS "Generating IBM Kyber keys"
+.
+.B p11sak
+.BR generate-key | gen-key | gen
+.BR ibm-kyber
+.BR VERSION
+.B \-\-slot
+.IR SLOTID
+.B \-\-pin
+.IR PIN
+.B \-\-label
+.IR LABEL
+.B \-\-attr
+.I [M R L S E D G V W U A X N T]
+.B \-\-help | \-h
+.PP
+Use the
+.B generate-key
+.B ibm-kyber
+.B VERSION
+command and key argument to generate an IBM Kyber key, where
+.I VERSION
+specifies the version of the IBM Kyber keypair. The following arguments can be used for respective keys:
+.B r2_768 | r2_1024
+.PP
+The
+.B \-\-slot
+.IR SLOTID
+and
+.B \-\-pin
+.IR PIN
+options are required to set the token to
+.IR SLOTID
+and the token PIN. The
+.B \-\-label
+option allows the user to set the
+.IR LABEL
+attribute of the key and
+.B \-\-attr
+.I [M R L S E D G V W U A X N T]
+can be used to set the binary attributes of the key (see below for detailed description of the attributes).
+.
+.PP
.SS "Listing symmetric and asymmetric keys"
.
.B p11sak
.BR list-key | ls-key | ls
-.BR des | 3des | aes | rsa | ec | ibm-dilithium | public | private | secret | all
+.BR des | 3des | aes | rsa | ec | ibm-dilithium | ibm-kyber | public | private | secret | all
.B \-\-slot
.IR SLOTID
.B \-\-pin
@@ -298,14 +341,14 @@ can be used to set the binary attributes of the key (see below for detailed desc
.PP
Use the
.B list-key | ls-key | ls
-command and key argument to list DES, 3DES, AES, RSA, EC, or IBM Dilithium keys, respectively. Public, private, secret, or all keys can also be listed irrespective of key type.
+command and key argument to list DES, 3DES, AES, RSA, EC, IBM Dilithium, or IBM Kyber keys, respectively. Public, private, secret, or all keys can also be listed irrespective of key type.
.
.PP
.SS "Deleting symmetric and asymmetric keys"
.
.B p11sak
.BR remove-key | rm-key | rm
-.BR des | 3des | aes | rsa | ec | ibm-dilithium
+.BR des | 3des | aes | rsa | ec | ibm-dilithium | ibm-kyber
.B \-\-slot
.IR SLOTID
.B \-\-pin
@@ -317,7 +360,7 @@ command and key argument to list DES, 3DES, AES, RSA, EC, or IBM Dilithium keys,
.PP
Use the
.B remove-key | rm-key | rm
-command and key argument to delete DES, 3DES, AES, RSA, EC, or IBM Dilithium keys, respectively. All specified cipher keys will be prompted to be deleted unless
+command and key argument to delete DES, 3DES, AES, RSA, EC, IBM Dilithium, or IBM Kyber keys, respectively. All specified cipher keys will be prompted to be deleted unless
a specific key with the
.B \-\-label
.IR LABEL
@@ -331,7 +374,7 @@ option.
.
.SH ARGS
.
-.SS "des | 3des | aes | rsa | ec | ibm-dilithium | public | private | secret | all"
+.SS "des | 3des | aes | rsa | ec | ibm-dilithium | ibm-kyber | public | private | secret | all"
selects the respective symmetric or asymetric key to be generated or listed. The
.B public|private|secret|all
@@ -378,6 +421,16 @@ to select the IBM dilithium version used to generate the key.
.
.
.
+.SS "r2_768|r2_1024"
+the
+.B ibm-kyber
+argument has to be followed by either of these
+.I VERSION
+to select the IBM kyber version used to generate the key.
+.PP
+.
+.
+.
.SH OPTIONS
.SS "\-\-slot SLOTID"
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 5ceb145b..38564155 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -130,6 +130,8 @@ static const char* kt2str(p11sak_kt ktype)
return "EC";
case kt_IBM_DILITHIUM:
return "IBM DILITHIUM";
+ case kt_IBM_KYBER:
+ return "IBM KYBER";
case kt_GENERIC:
return "GENERIC";
case kt_SECRET:
@@ -170,6 +172,9 @@ static CK_RV kt2CKK(p11sak_kt ktype, CK_KEY_TYPE *a_key_type)
case kt_IBM_DILITHIUM:
*a_key_type = CKK_IBM_PQC_DILITHIUM;
break;
+ case kt_IBM_KYBER:
+ *a_key_type = CKK_IBM_PQC_KYBER;
+ break;
case kt_GENERIC:
*a_key_type = CKK_GENERIC_SECRET;
break;
@@ -277,6 +282,8 @@ static const char* CKK2a(CK_KEY_TYPE t)
return "EC";
case CKK_IBM_PQC_DILITHIUM:
return "IBM DILILTHIUM";
+ case CKK_IBM_PQC_KYBER:
+ return "IBM KYBER";
case CKK_RSA:
return "RSA";
case CKK_DH:
@@ -358,6 +365,7 @@ static void print_listkeys_help(void)
printf(" rsa\n");
printf(" ec\n");
printf(" ibm-dilithium\n");
+ printf(" ibm-kyber\n");
printf(" public\n");
printf(" private\n");
printf(" secret\n");
@@ -388,6 +396,7 @@ static void print_gen_help(void)
printf(" brainpoolP512r1 | brainpoolP512t1 | curve25519 | curve448 | ed25519 | \n");
printf(" ed448]\n");
printf(" ibm-dilithium [r2_65 | r2_87 | r3_44 | r3_65 | r3_87]\n");
+ printf(" ibm-kyber [r2_768 | r2_1024]\n");
printf("\n Options:\n");
printf(
" --slot SLOTID openCryptoki repository token SLOTID.\n");
@@ -415,6 +424,7 @@ static void print_removekeys_help(void)
printf(" rsa\n");
printf(" ec\n");
printf(" ibm-dilithium\n");
+ printf(" ibm-kyber\n");
printf("\n Options:\n");
printf(
" --slot SLOTID openCryptoki repository token SLOTID.\n");
@@ -545,6 +555,25 @@ static void print_gen_ibm_dilithium_help(void)
printf(" -h, --help Show this help\n\n");
}
+static void print_gen_ibm_kyber_help(void)
+{
+ printf("\n Usage: p11sak generate-key ibm-kyber [ARGS] [OPTIONS]\n");
+ printf("\n Args:\n");
+ printf(" r2_768\n");
+ printf(" r2_1024\n");
+ printf("\n Options:\n");
+ printf(" --slot SLOTID openCryptoki repository token SLOTID.\n");
+ printf(" --pin PIN pkcs11 user PIN\n");
+ printf(" --force-pin-prompt enforce user PIN prompt\n");
+ printf(" --label LABEL key label LABEL to be listed\n");
+ printf(" --label PUB_LABEL:PRIV_LABEL\n");
+ printf(" for asymmetric keys: set individual labels for public and private key\n");
+ printf(" --attr [M R L S E D G V W U A X N] set key attributes\n");
+ printf(" --attr [[pub_attrs]:[priv_attrs]] \n");
+ printf(" for asymmetric keys: set individual key attributes, values see above\n");
+ printf(" -h, --help Show this help\n\n");
+}
+
/**
* Print help for generate-key command
*/
@@ -572,6 +601,9 @@ static CK_RV print_gen_keys_help(p11sak_kt *kt)
case kt_IBM_DILITHIUM:
print_gen_ibm_dilithium_help();
break;
+ case kt_IBM_KYBER:
+ print_gen_ibm_kyber_help();
+ break;
case no_key_type:
print_gen_help();
break;
@@ -797,6 +829,29 @@ static CK_RV read_dilithium_args(const char *dilithium_ver, CK_ULONG *keyform,
return CKR_OK;
}
+/**
+ * Builds the CKA_IBM_KYBER_KEYFORM attribute from the given version.
+ */
+static CK_RV read_kyber_args(const char *kyber_ver, CK_ULONG *keyform,
+ CK_ATTRIBUTE *pubattr, CK_ULONG *pubcount)
+{
+ if (strcasecmp(kyber_ver, "r2_768") == 0) {
+ *keyform = CK_IBM_KYBER_KEYFORM_ROUND2_768;
+ } else if (strcasecmp(kyber_ver, "r2_1024") == 0) {
+ *keyform = CK_IBM_KYBER_KEYFORM_ROUND2_1024;
+ } else {
+ fprintf(stderr, "Unexpected case while parsing kyber version.\n");
+ fprintf(stderr, "Note: not all tokens support all versions.\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ pubattr[*pubcount].type = CKA_IBM_KYBER_KEYFORM;
+ pubattr[*pubcount].ulValueLen = sizeof(CK_ULONG);
+ pubattr[*pubcount].pValue = keyform;
+ (*pubcount)++;
+
+ return CKR_OK;
+}
/**
* Builds two CKA_LABEL attributes from given label.
*/
@@ -860,6 +915,9 @@ static CK_RV key_pair_gen_mech(p11sak_kt kt, CK_MECHANISM *pmech)
case kt_IBM_DILITHIUM:
pmech->mechanism = CKM_IBM_DILITHIUM;
break;
+ case kt_IBM_KYBER:
+ pmech->mechanism = CKM_IBM_KYBER;
+ break;
default:
return CKR_MECHANISM_INVALID;
break;
@@ -1131,6 +1189,8 @@ static CK_RV key_pair_gen(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
fprintf(stderr, "Key pair generation rejected by policy\n");
else if (kt == kt_IBM_DILITHIUM && rc == CKR_KEY_SIZE_RANGE)
fprintf(stderr, "IBM Dilithum version is not supported\n");
+ else if (kt == kt_IBM_KYBER && rc == CKR_KEY_SIZE_RANGE)
+ fprintf(stderr, "IBM Kyber version is not supported\n");
else
fprintf(stderr, "Key pair generation failed (error code 0x%lX: %s)\n", rc,
p11_get_ckr(rc));
@@ -1191,6 +1251,7 @@ static CK_RV tok_key_list_init(CK_SESSION_HANDLE session, p11sak_kt kt,
case kt_RSAPKCS:
case kt_EC:
case kt_IBM_DILITHIUM:
+ case kt_IBM_KYBER:
tmplt[count].type = CKA_KEY_TYPE;
tmplt[count].pValue = &a_key_type;
tmplt[count].ulValueLen = sizeof(CK_KEY_TYPE);
@@ -1871,27 +1932,42 @@ static CK_RV tok_key_get_key_type(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE hk
* Check args for gen_key command.
*/
static CK_RV check_args_gen_key(p11sak_kt *kt, CK_ULONG keylength,
- char *ECcurve, char *dilithium_ver)
+ char *ECcurve, char *pqc_ver)
{
switch (*kt) {
case kt_DES:
case kt_3DES:
break;
case kt_IBM_DILITHIUM:
- if (dilithium_ver == NULL) {
+ if (pqc_ver == NULL) {
fprintf(stderr,
"Cipher key type [%d] supported but Dilithium version not set in arguments. Try adding argument <r2_65>, <r2_87>, <r3_44>, <r3_65>, or <r3_87>\n",
*kt);
return CKR_ARGUMENTS_BAD;
}
- if (strcasecmp(dilithium_ver, "r2_65") == 0 ||
- strcasecmp(dilithium_ver, "r2_87") == 0 ||
- strcasecmp(dilithium_ver, "r3_44") == 0 ||
- strcasecmp(dilithium_ver, "r3_65") == 0 ||
- strcasecmp(dilithium_ver, "r3_87") == 0) {
+ if (strcasecmp(pqc_ver, "r2_65") == 0 ||
+ strcasecmp(pqc_ver, "r2_87") == 0 ||
+ strcasecmp(pqc_ver, "r3_44") == 0 ||
+ strcasecmp(pqc_ver, "r3_65") == 0 ||
+ strcasecmp(pqc_ver, "r3_87") == 0) {
break;
} else {
- fprintf(stderr, "IBM Dilithium version [%s] not supported \n", dilithium_ver);
+ fprintf(stderr, "IBM Dilithium version [%s] not supported \n", pqc_ver);
+ return CKR_ARGUMENTS_BAD;
+ }
+ break;
+ case kt_IBM_KYBER:
+ if (pqc_ver == NULL) {
+ fprintf(stderr,
+ "Cipher key type [%d] supported but Kyber version not set in arguments. Try adding argument <r2_1024> or <r2_1024>\n",
+ *kt);
+ return CKR_ARGUMENTS_BAD;
+ }
+ if (strcasecmp(pqc_ver, "r2_768") == 0 ||
+ strcasecmp(pqc_ver, "r2_1024") == 0) {
+ break;
+ } else {
+ fprintf(stderr, "IBM Kyber version [%s] not supported \n", pqc_ver);
return CKR_ARGUMENTS_BAD;
}
break;
@@ -1947,6 +2023,7 @@ static CK_RV check_args_list_key(p11sak_kt *kt)
case kt_3DES:
case kt_EC:
case kt_IBM_DILITHIUM:
+ case kt_IBM_KYBER:
case kt_GENERIC:
case kt_SECRET:
case kt_PUBLIC:
@@ -1973,6 +2050,7 @@ static CK_RV check_args_remove_key(p11sak_kt *kt)
case kt_RSAPKCS:
case kt_EC:
case kt_IBM_DILITHIUM:
+ case kt_IBM_KYBER:
case kt_GENERIC:
case kt_SECRET:
case kt_PUBLIC:
@@ -2069,6 +2147,8 @@ static CK_RV parse_list_key_args(char *argv[], int argc, p11sak_kt *kt,
*kt = kt_EC;
} else if (strcasecmp(argv[i], "ibm-dilithium") == 0) {
*kt = kt_IBM_DILITHIUM;
+ } else if (strcasecmp(argv[i], "ibm-kyber") == 0) {
+ *kt = kt_IBM_KYBER;
} else if (strcasecmp(argv[i], "generic") == 0) {
*kt = kt_GENERIC;
} else if (strcasecmp(argv[i], "secret") == 0) {
@@ -2158,7 +2238,7 @@ static CK_RV parse_gen_key_args(char *argv[], int argc, p11sak_kt *kt,
CK_ULONG *keylength, char **ECcurve,
CK_SLOT_ID *slot, const char **pin,
CK_ULONG *exponent, char **label,
- char **attr_string, char **dilithium_ver,
+ char **attr_string, char **pqc_ver,
int *force_pin_prompt)
{
CK_RV rc;
@@ -2190,7 +2270,11 @@ static CK_RV parse_gen_key_args(char *argv[], int argc, p11sak_kt *kt,
i++;
} else if (strcasecmp(argv[i], "ibm-dilithium") == 0) {
*kt = kt_IBM_DILITHIUM;
- *dilithium_ver = get_string_arg(i + 1, argv, argc);
+ *pqc_ver = get_string_arg(i + 1, argv, argc);
+ i++;
+ } else if (strcasecmp(argv[i], "ibm-kyber") == 0) {
+ *kt = kt_IBM_KYBER;
+ *pqc_ver = get_string_arg(i + 1, argv, argc);
i++;
/* Get options */
} else if (strcmp(argv[i], "--slot") == 0) {
@@ -2281,7 +2365,7 @@ static CK_RV parse_gen_key_args(char *argv[], int argc, p11sak_kt *kt,
}
/* Check args */
- rc = check_args_gen_key(kt, *keylength, *ECcurve, *dilithium_ver);
+ rc = check_args_gen_key(kt, *keylength, *ECcurve, *pqc_ver);
/* Check required options */
if (*label == NULL) {
@@ -2331,6 +2415,8 @@ static CK_RV parse_remove_key_args(char *argv[], int argc, p11sak_kt *kt,
*kt = kt_EC;
} else if (strcasecmp(argv[i], "ibm-dilithium") == 0) {
*kt = kt_IBM_DILITHIUM;
+ } else if (strcasecmp(argv[i], "ibm-kyber") == 0) {
+ *kt = kt_IBM_KYBER;
/* Get options */
} else if (strcmp(argv[i], "--slot") == 0) {
if (i + 1 < argc) {
@@ -2415,7 +2501,7 @@ static CK_RV parse_cmd_args(p11sak_cmd cmd, char *argv[], int argc,
CK_SLOT_ID *slot, const char **pin,
CK_ULONG *exponent, char **label,
char **attr_string, int *long_print, int *full_uri,
- CK_BBOOL *forceAll, char **dilithium_ver,
+ CK_BBOOL *forceAll, char **pqc_ver,
int *force_pin_prompt)
{
CK_RV rc;
@@ -2423,7 +2509,7 @@ static CK_RV parse_cmd_args(p11sak_cmd cmd, char *argv[], int argc,
switch (cmd) {
case gen_key:
rc = parse_gen_key_args(argv, argc, kt, keylength, ECcurve, slot, pin,
- exponent, label, attr_string, dilithium_ver, force_pin_prompt);
+ exponent, label, attr_string, pqc_ver, force_pin_prompt);
break;
case list_key:
rc = parse_list_key_args(argv, argc, kt, keylength, slot, pin,
@@ -2481,7 +2567,7 @@ done:
static CK_RV generate_asymmetric_key(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
p11sak_kt kt, CK_ULONG keylength,
CK_ULONG exponent, char *ECcurve,
- char *label, char *attr_string, char *dilithium_ver)
+ char *label, char *attr_string, char *pqc_ver)
{
CK_OBJECT_HANDLE pub_keyh, prv_keyh;
CK_ATTRIBUTE pub_attr[KEY_MAX_BOOL_ATTR_COUNT + 2];
@@ -2514,13 +2600,21 @@ static CK_RV generate_asymmetric_key(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
}
break;
case kt_IBM_DILITHIUM:
- rc = read_dilithium_args(dilithium_ver, &keyform,
+ rc = read_dilithium_args(pqc_ver, &keyform,
pub_attr, &pub_acount);
if (rc) {
fprintf(stderr, "Error parsing Dilithium parameters!\n");
goto done;
}
- printf("Generating Dilithium keypair with %s\n", dilithium_ver);
+ printf("Generating Dilithium keypair with %s\n", pqc_ver);
+ break;
+ case kt_IBM_KYBER:
+ rc = read_kyber_args(pqc_ver, &keyform, pub_attr, &pub_acount);
+ if (rc) {
+ fprintf(stderr, "Error parsing Kyber parameters!\n");
+ goto done;
+ }
+ printf("Generating Kyber keypair with %s\n", pqc_ver);
break;
default:
fprintf(stderr, "The key type %d is not yet supported.\n", kt);
@@ -2626,7 +2720,7 @@ done:
static CK_RV generate_ckey(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
p11sak_kt kt, CK_ULONG keylength, char *ECcurve,
CK_ULONG exponent, char *label, char *attr_string,
- char *dilithium_ver)
+ char *pqc_ver)
{
switch (kt) {
case kt_DES:
@@ -2637,8 +2731,9 @@ static CK_RV generate_ckey(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
case kt_RSAPKCS:
case kt_EC:
case kt_IBM_DILITHIUM:
+ case kt_IBM_KYBER:
return generate_asymmetric_key(session, slot, kt, keylength, exponent,
- ECcurve, label, attr_string, dilithium_ver);
+ ECcurve, label, attr_string, pqc_ver);
default:
fprintf(stderr, "Error: cannot create a key of type %i (%s)\n", kt, kt2str(kt));
return CKR_ARGUMENTS_BAD;
@@ -3030,13 +3125,13 @@ static CK_RV execute_cmd(CK_SESSION_HANDLE session, CK_SLOT_ID slot,
p11sak_cmd cmd, p11sak_kt kt, CK_ULONG keylength,
CK_ULONG exponent, char *ECcurve, char *label,
char *attr_string, int long_print, int full_uri,
- CK_BBOOL *forceAll, char *dilithium_ver)
+ CK_BBOOL *forceAll, char *pqc_ver)
{
CK_RV rc;
switch (cmd) {
case gen_key:
rc = generate_ckey(session, slot, kt, keylength, ECcurve, exponent,
- label, attr_string, dilithium_ver);
+ label, attr_string, pqc_ver);
break;
case list_key:
rc = list_ckey(session, slot, kt, long_print, label, full_uri);
@@ -3177,7 +3272,7 @@ int main(int argc, char *argv[])
char *ECcurve = NULL;
char *attr_string = NULL;
CK_ULONG keylength = 0;
- char *dilithium_ver = NULL;
+ char *pqc_ver = NULL;
CK_RV rc = CKR_OK;
CK_SESSION_HANDLE session;
const char *pin = NULL;
@@ -3203,7 +3298,7 @@ int main(int argc, char *argv[])
/* Parse command args */
rc = parse_cmd_args(cmd, argv, argc, &kt, &keylength, &ECcurve, &slot, &pin,
&exponent, &label, &attr_string, &long_print, &full_uri, &forceAll,
- &dilithium_ver, &force_pin_prompt);
+ &pqc_ver, &force_pin_prompt);
if (rc != CKR_OK) {
goto done;
}
@@ -3240,7 +3335,7 @@ int main(int argc, char *argv[])
/* Execute command */
rc = execute_cmd(session, slot, cmd, kt, keylength, exponent, ECcurve,
- label, attr_string, long_print, full_uri, &forceAll, dilithium_ver);
+ label, attr_string, long_print, full_uri, &forceAll, pqc_ver);
if (rc == CKR_CANCEL) {
fprintf(stderr, "Cancel execution: p11sak %s command (error code 0x%lX: %s)\n", cmd2str(cmd), rc,
p11_get_ckr(rc));
diff --git a/usr/sbin/p11sak/p11sak.h b/usr/sbin/p11sak/p11sak.h
index 2b7e9c64..9d5a461a 100644
--- a/usr/sbin/p11sak/p11sak.h
+++ b/usr/sbin/p11sak/p11sak.h
@@ -25,6 +25,7 @@ typedef enum {
kt_RSAPKCS,
kt_EC,
kt_IBM_DILITHIUM,
+ kt_IBM_KYBER,
kt_GENERIC,
kt_SECRET,
kt_PUBLIC,
diff --git a/usr/sbin/p11sak/p11sak_defined_attrs.conf b/usr/sbin/p11sak/p11sak_defined_attrs.conf
index 520d28d5..53080ef5 100644
--- a/usr/sbin/p11sak/p11sak_defined_attrs.conf
+++ b/usr/sbin/p11sak/p11sak_defined_attrs.conf
@@ -33,10 +33,14 @@ attribute {
id = 0x00000120
type = CK_BYTE
}
-
attribute {
name = CKA_IBM_DILITHIUM_KEYFORM
id = 0x800d0001
type = CK_ULONG
}
+attribute {
+ name = CKA_IBM_KYBER_KEYFORM
+ id = 0x800d0009
+ type = CK_ULONG
+}
--
2.16.2.windows.1

View File

@ -1,111 +0,0 @@
From 3247a4f1d1d8a9b8d7f3bc6c1dd85234dd184cbb Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 9 Nov 2022 09:45:21 +0100
Subject: [PATCH 32/34] testcase: Enhance p11sak testcase to generate IBM Kyber
keys
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
testcases/misc_tests/p11sak_test.sh | 44 +++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/testcases/misc_tests/p11sak_test.sh b/testcases/misc_tests/p11sak_test.sh
index a0d3c644..b3374c6a 100755
--- a/testcases/misc_tests/p11sak_test.sh
+++ b/testcases/misc_tests/p11sak_test.sh
@@ -38,6 +38,9 @@ P11SAK_EC_POST=p11sak-ec-post.out
P11SAK_IBM_DIL_PRE=p11sak-ibm-dil-pre.out
P11SAK_IBM_DIL_LONG=p11sak-ibm-dil-long.out
P11SAK_IBM_DIL_POST=p11sak-ibm-dil-post.out
+P11SAK_IBM_KYBER_PRE=p11sak-ibm-kyber-pre.out
+P11SAK_IBM_KYBER_LONG=p11sak-ibm-kyber-long.out
+P11SAK_IBM_KYBER_POST=p11sak-ibm-kyber-post.out
P11SAK_ALL_PINOPT=p11sak-all-pinopt
P11SAK_ALL_PINENV=p11sak-all-pinenv
P11SAK_ALL_PINCON=p11sak-all-pincon
@@ -83,6 +86,12 @@ if [[ -n $( pkcsconf -m -c $SLOT | grep CKM_IBM_DILITHIUM) ]]; then
else
echo "Skip generating ibm-dilithium keys, slot does not support CKM_IBM_DILITHIUM"
fi
+# ibm-kyber
+if [[ -n $( pkcsconf -m -c $SLOT | grep CKM_IBM_KYBER) ]]; then
+ p11sak generate-key ibm-kyber r2_1024 --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ibm-kyber
+else
+ echo "Skip generating ibm-kyber keys, slot does not support CKM_IBM_KYBER"
+fi
echo "** Now list keys and redirect output to pre-files - 'p11sak_test.sh'"
@@ -102,6 +111,7 @@ p11sak list-key aes --slot $SLOT --pin $PKCS11_USER_PIN --long &> $P11SAK_AES_LO
p11sak list-key rsa --slot $SLOT --pin $PKCS11_USER_PIN --long &> $P11SAK_RSA_LONG
p11sak list-key ec --slot $SLOT --pin $PKCS11_USER_PIN --long &> $P11SAK_EC_LONG
p11sak list-key ibm-dilithium --slot $SLOT --pin $PKCS11_USER_PIN --long &> $P11SAK_IBM_DIL_LONG
+p11sak list-key ibm-kyber --slot $SLOT --pin $PKCS11_USER_PIN --long &> $P11SAK_IBM_KYBER_LONG
p11sak list-key all --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_ALL_PINOPT
RC_P11SAK_PINOPT=$?
@@ -143,6 +153,9 @@ p11sak remove-key ec --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ec-secp5
# remove ibm dilithium keys
p11sak remove-key ibm-dilithium --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ibm-dilithium:pub -f
p11sak remove-key ibm-dilithium --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ibm-dilithium:prv -f
+# remove ibm kyber keys
+p11sak remove-key ibm-kyber --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ibm-kyber:pub -f
+p11sak remove-key ibm-kyber --slot $SLOT --pin $PKCS11_USER_PIN --label p11sak-ibm-kyber:prv -f
echo "** Now list keys and rediirect to post-files - 'p11sak_test.sh'"
@@ -155,6 +168,7 @@ p11sak list-key aes --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_AES_POST
p11sak list-key rsa --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_RSA_POST
p11sak list-key ec --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_EC_POST
p11sak list-key ibm-dilithium --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_IBM_DIL_POST
+p11sak list-key ibm-kyber --slot $SLOT --pin $PKCS11_USER_PIN &> $P11SAK_IBM_KYBER_POST
echo "** Now checking output files to determine PASS/FAIL of tests - 'p11sak_test.sh'"
@@ -670,6 +684,33 @@ else
echo "* TESTCASE list-key ibm-dilithium SKIP Listed random ibm-dilithium public keys CK_BYTE attribute"
fi
+if [[ -n $( pkcsconf -m -c $SLOT | grep CKM_IBM_KYBER) ]]; then
+ # CK_BBOOL
+ if [[ $(grep -A 35 'p11sak-ibm-kyber' $P11SAK_IBM_KYBER_LONG | grep -c 'CK_TRUE') == "12" ]]; then
+ echo "* TESTCASE list-key ibm-kyber PASS Listed random ibm-kyber public keys CK_BBOOL attribute"
+ else
+ echo "* TESTCASE list-key ibm-kyber FAIL Failed to list ibm-kyber public keys CK_BBOOL attribute"
+ status=1
+ fi
+ # CK_ULONG
+ if [[ $(grep -A 35 'p11sak-ibm-kyber' $P11SAK_IBM_KYBER_LONG | grep -c 'CKA_MODULUS_BITS:') == "0" ]]; then
+ echo "* TESTCASE list-key ibm-kyber PASS Listed random ibm-kyber public keys CK_ULONG attribute"
+ else
+ echo "* TESTCASE list-key ibm-kyber FAIL Failed to list ibm-kyber public keys CK_ULONG attribute"
+ status=1
+ fi
+ # CK_BYTE
+ if [[ $(grep -A 35 'p11sak-ibm-kyber' $P11SAK_IBM_KYBER_LONG | grep -c 'CKA_MODULUS:') == "0" ]]; then
+ echo "* TESTCASE list-key ibm-kyber PASS Listed random ibm-kyber public keys CK_BYTE attribute"
+ else
+ echo "* TESTCASE list-key ibm-kyber FAIL Failed to list ibm-kyber public keys CK_BYTE attribute"
+ status=1
+ fi
+else
+ echo "* TESTCASE list-key ibm-kyber SKIP Listed random ibm-kyber public keys CK_BBOOL attribute"
+ echo "* TESTCASE list-key ibm-kyber SKIP Listed random ibm-kyber public keys CK_ULONG attribute"
+ echo "* TESTCASE list-key ibm-kyber SKIP Listed random ibm-kyber public keys CK_BYTE attribute"
+fi
# check token pin handling
if [ $RC_P11SAK_PINOPT = 0 ]; then
@@ -724,6 +765,9 @@ rm -f $P11SAK_EC_POST
rm -f $P11SAK_IBM_DIL_PRE
rm -f $P11SAK_IBM_DIL_LONG
rm -f $P11SAK_IBM_DIL_POST
+rm -f $P11SAK_IBM_KYBER_PRE
+rm -f $P11SAK_IBM_KYBER_LONG
+rm -f $P11SAK_IBM_KYBER_POST
rm -f $P11SAK_ALL_PINOPT
rm -f $P11SAK_ALL_PINENV
rm -f $P11SAK_ALL_PINCON
--
2.16.2.windows.1

View File

@ -1,356 +0,0 @@
From df874a780108fa1390e4cb99144b9acb0667f76b Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 4 Nov 2022 11:33:50 +0100
Subject: [PATCH 33/34] EP11: Supply CKA_PUBLIC_KEY_INFO with
CKM_IBM_BTC_DERIVE of private key
When deriving a private EC key with the CKM_IBM_BTC_DERIVE mechanism,
also supply the SPKI in the CKA_PUBLIC_KEY_INFO attribute.
To get the SPKI, use m_GetAttributeValue() with CKA_PUBLIC_KEY_INFO.
On newer EP11 host libraries this returns the SPKI of the corresponding
public key of the private key blob. In case the EP11 host library fails
to get the SPKI from the blob, ignore and do not supply an SPKI.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 266 +++++++++++++++++++++++--------------
1 file changed, 168 insertions(+), 98 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 9efce053..d4ece223 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -5316,7 +5316,148 @@ static CK_RV ep11tok_kyber_mech_post_process(STDLL_TokData_t *tokdata,
return CKR_OK;
}
-CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
+static CK_RV ep11tok_btc_mech_pre_process(STDLL_TokData_t *tokdata,
+ OBJECT *key_obj,
+ CK_ATTRIBUTE **new_attrs,
+ CK_ULONG *new_attrs_len)
+{
+ CK_ATTRIBUTE *ec_params;
+ CK_ULONG i, privlen;
+ CK_RV rc;
+
+ UNUSED(tokdata);
+
+ /*
+ * CKM_IBM_BTC_DERIVE requires CKA_VALUE_LEN to specify the byte length
+ * of the to be derived EC key. CKA_VALUE_LEN is dependent on the
+ * curve used.
+ * CKA_VALUE_LEN can not be already in the user supplied template,
+ * since this is not allowed by the key template check routines.
+ */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_EC_PARAMS,
+ &ec_params);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("CKA_EC_PARAMS is required in derive template\n");
+ return rc;
+ }
+
+ for (i = 0; i < NUMEC; i++) {
+ if (der_ec_supported[i].data_size == ec_params->ulValueLen &&
+ memcmp(ec_params->pValue, der_ec_supported[i].data,
+ ec_params->ulValueLen) == 0) {
+ privlen = (der_ec_supported[i].len_bits + 7) / 8;
+ rc = add_to_attribute_array(new_attrs, new_attrs_len,
+ CKA_VALUE_LEN,
+ (CK_BYTE_PTR)&privlen,
+ sizeof(privlen));
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Adding attribute failed type=CKA_VALUE_LEN "
+ "rc=0x%lx\n", rc);
+ return rc;
+ }
+ break;
+ }
+ }
+
+ return CKR_OK;
+}
+
+static CK_RV ep11tok_btc_mech_post_process(STDLL_TokData_t *tokdata,
+ SESSION *session, CK_MECHANISM *mech,
+ CK_ULONG class, CK_ULONG ktype,
+ OBJECT *key_obj,
+ CK_BYTE *blob, CK_ULONG bloblen,
+ CK_BYTE *csum, CK_ULONG cslen)
+{
+ CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
+ CK_BYTE *spki = NULL;
+ CK_ULONG spki_length = 0;
+ CK_BYTE buf[MAX_BLOBSIZE];
+ CK_ATTRIBUTE get_attr[1] = {{ CKA_PUBLIC_KEY_INFO, &buf, sizeof(buf) }};
+ CK_ATTRIBUTE *spki_attr = NULL;
+ CK_BBOOL allocated = FALSE;
+ CK_RV rc = CKR_OK;
+
+ if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
+ mech->pParameter == NULL) {
+ TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
+ __func__, ep11_get_ckm(tokdata, mech->mechanism),
+ mech->ulParameterLen);
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
+
+ if (btc_params != NULL && btc_params->pChainCode != NULL &&
+ cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
+ memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
+ btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
+ }
+
+ switch (class) {
+ case CKO_PUBLIC_KEY:
+ /* Derived blob is an SPKI, extract public EC key attributes */
+ rc = ecdsa_priv_unwrap_get_data(key_obj->template, blob, bloblen);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s ecdsa_priv_unwrap_get_data failed with "
+ "rc=0x%lx\n", __func__, rc);
+ return rc;
+ }
+
+ /* Extract the SPKI and add CKA_PUBLIC_KEY_INFO to key */
+ rc = publ_key_get_spki(key_obj->template, ktype, FALSE,
+ &spki, &spki_length);
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("publ_key_get_spki failed\n");
+ return rc;
+ }
+
+ allocated = TRUE;
+ break;
+
+ case CKO_PRIVATE_KEY:
+ RETRY_START(rc, tokdata)
+ rc = dll_m_GetAttributeValue(blob, bloblen, get_attr, 1,
+ target_info->target);
+ RETRY_END(rc, tokdata, session)
+
+ /* Only newer EP11 libs support this, ignore if error */
+ if (rc != CKR_OK)
+ return CKR_OK;
+
+ spki = get_attr[0].pValue;
+ spki_length = get_attr[0].ulValueLen;
+ break;
+
+ default:
+ /* do nothing */
+ return CKR_OK;
+ }
+
+ rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spki_length,
+ &spki_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ goto out;
+ }
+
+ rc = template_update_attribute(key_obj->template, spki_attr);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
+ __func__, rc);
+ free(spki_attr);
+ goto out;
+ }
+
+out:
+ if (allocated && spki != NULL)
+ free(spki);
+
+ return rc;
+}
+
+CK_RV ep11tok_derive_key(STDLL_TokData_t *tokdata, SESSION *session,
CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE hBaseKey,
CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs,
CK_ULONG attrs_len)
@@ -5345,17 +5486,12 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
CK_ULONG ecpoint_len, field_len, key_len = 0;
CK_ATTRIBUTE *new_attrs1 = NULL, *new_attrs2 = NULL;
CK_ULONG new_attrs1_len = 0, new_attrs2_len = 0;
- CK_ULONG privlen, i;
+ CK_ULONG privlen;
int curve_type;
CK_BBOOL allocated = FALSE;
ep11_target_info_t* target_info;
CK_ULONG used_firmware_API_version;
CK_MECHANISM_PTR mech_orig = mech;
- CK_ATTRIBUTE *ec_params;
- CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
- CK_BYTE *spki = NULL;
- CK_ULONG spki_length = 0;
- CK_ATTRIBUTE *spki_attr = NULL;
struct EP11_KYBER_MECH mech_ep11;
OBJECT *kyber_secret_obj = NULL;
@@ -5476,18 +5612,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
}
- if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
- if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
- mech->pParameter == NULL) {
- TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
- __func__, ep11_get_ckm(tokdata, mech->mechanism),
- mech->ulParameterLen);
- return CKR_MECHANISM_PARAM_INVALID;
- }
-
- btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
- }
-
rc = h_opaque_2_blob(tokdata, hBaseKey, &keyblob, &keyblobsize,
&base_key_obj, READ_LOCK);
if (rc != CKR_OK) {
@@ -5605,46 +5729,24 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
goto error;
}
- if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
- /*
- * CKM_IBM_BTC_DERIVE requires CKA_VALUE_LEN to specify the byte length
- * of the to be derived EC key. CKA_VALUE_LEN is dependent on the
- * curve used.
- * CKA_VALUE_LEN can not be already in the user supplied template,
- * since this is not allowed by the key template check routines.
- */
- rc = template_attribute_get_non_empty(key_obj->template, CKA_EC_PARAMS,
- &ec_params);
- if (rc != CKR_OK) {
- TRACE_ERROR("CKA_EC_PARAMS is required in derive template\n");
+ switch (mech->mechanism) {
+ case CKM_IBM_BTC_DERIVE:
+ rc = ep11tok_btc_mech_pre_process(tokdata, key_obj, &new_attrs2,
+ &new_attrs2_len);
+ if (rc != CKR_OK)
goto error;
- }
-
- for (i = 0; i < NUMEC; i++) {
- if (der_ec_supported[i].data_size == ec_params->ulValueLen &&
- memcmp(ec_params->pValue, der_ec_supported[i].data,
- ec_params->ulValueLen) == 0) {
- privlen = (der_ec_supported[i].len_bits + 7) / 8;
- rc = add_to_attribute_array(&new_attrs2, &new_attrs2_len,
- CKA_VALUE_LEN,
- (CK_BYTE_PTR)&privlen,
- sizeof(privlen));
- if (rc != CKR_OK) {
- TRACE_ERROR("Adding attribute failed type=CKA_VALUE_LEN "
- "rc=0x%lx\n", rc);
- goto error;
- }
- break;
- }
- }
- }
+ break;
- if (mech->mechanism == CKM_IBM_KYBER) {
+ case CKM_IBM_KYBER:
rc = ep11tok_kyber_mech_pre_process(tokdata, mech, &mech_ep11,
&kyber_secret_obj);
if (rc != CKR_OK)
goto error;
mech = &mech_ep11.mech;
+ break;
+
+ default:
+ break;
}
trace_attributes(__func__, "Derive:", new_attrs2, new_attrs2_len);
@@ -5695,47 +5797,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
opaque_attr = NULL;
- if (mech->mechanism == CKM_IBM_BTC_DERIVE &&
- btc_params != NULL && btc_params->pChainCode != NULL &&
- cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
- memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
- btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
- }
-
- if (mech->mechanism == CKM_IBM_BTC_DERIVE && class == CKO_PUBLIC_KEY) {
- /* Derived blob is an SPKI, extract public EC key attributes */
- rc = ecdsa_priv_unwrap_get_data(key_obj->template,
- newblob, newblobsize);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s ecdsa_priv_unwrap_get_data failed with rc=0x%lx\n",
- __func__, rc);
- goto error;
- }
-
- /* Extract the SPKI and add CKA_PUBLIC_KEY_INFO to key */
- rc = publ_key_get_spki(key_obj->template, ktype, FALSE,
- &spki, &spki_length);
- if (rc != CKR_OK) {
- TRACE_DEVEL("publ_key_get_spki failed\n");
- goto error;
- }
-
- rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spki_length, &spki_attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n",
- __func__, rc);
- goto error;
- }
-
- rc = template_update_attribute(key_obj->template, spki_attr);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s template_update_attribute failed with "
- "rc=0x%lx\n", __func__, rc);
- goto error;
- }
- spki_attr = NULL;
- }
-
if (class == CKO_SECRET_KEY || class == CKO_PRIVATE_KEY) {
rc = update_ep11_attrs_from_blob(tokdata, session, key_obj->template);
if (rc != CKR_OK) {
@@ -5745,10 +5806,23 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
}
}
- if (mech->mechanism == CKM_IBM_KYBER) {
+ switch (mech->mechanism) {
+ case CKM_IBM_BTC_DERIVE:
+ rc = ep11tok_btc_mech_post_process(tokdata, session, mech, class, ktype,
+ key_obj, newblob, newblobsize,
+ csum, cslen);
+ if (rc != CKR_OK)
+ goto error;
+ break;
+
+ case CKM_IBM_KYBER:
rc = ep11tok_kyber_mech_post_process(tokdata, mech_orig, csum, cslen);
if (rc != CKR_OK)
goto error;
+ break;
+
+ default:
+ break;
}
if (class == CKO_SECRET_KEY && cslen >= EP11_CSUMSIZE) {
@@ -5792,10 +5866,6 @@ error:
free(opaque_attr);
if (chk_attr != NULL)
free(chk_attr);
- if (spki_attr != NULL)
- free(spki_attr);
- if (spki != NULL)
- free(spki);
if (new_attrs)
free_attribute_array(new_attrs, new_attrs_len);
if (new_attrs1)
--
2.16.2.windows.1

View File

@ -1,46 +0,0 @@
From 45bc6dd09fb59d78ce9b2bca7125cfc2275f9bd1 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Wed, 25 Jan 2023 13:21:44 +0100
Subject: [PATCH 34/34] EP11: Fix setting unknown CPs to ON
The very last control point must also be applied from the queried bits to
the combined bits. Otherwise the very last control point is always treated
as being ON, although it might be OFF, and this can lead to mechanisms being
used that are disabled by that control point.
Fixes https://github.com/opencryptoki/opencryptoki/commit/97248f73495695436f11fafd74c2ec41a5a6f796
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
usr/lib/ep11_stdll/ep11_specific.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index d5d3de91..25ce82fe 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -11340,8 +11340,8 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
if (data->first) {
data->first_adapter = adapter;
data->first_domain = domain;
- /* Apply CP bits 0 to max_cp_index-1 only */
- for (i = 0; i < max_cp_index; i++) {
+ /* Apply CP bits 0 to max_cp_index only */
+ for (i = 0; i <= max_cp_index; i++) {
data->combined_cp[CP_BYTE_NO(i)] &=
(cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
}
@@ -11362,8 +11362,8 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
data->first_domain);
}
- for (i = 0; i < max_cp_index; i++) {
- /* Apply CP bits 0 to max_cp_index-1 only */
+ for (i = 0; i <= max_cp_index; i++) {
+ /* Apply CP bits 0 to max_cp_index only */
data->combined_cp[CP_BYTE_NO(i)] &=
(cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
}
--
2.16.2.windows.1

View File

@ -1,31 +0,0 @@
diff -up opencryptoki-3.11.0/usr/lib/api/shrd_mem.c.in.me opencryptoki-3.11.0/usr/lib/api/shrd_mem.c.in
--- opencryptoki-3.11.0/usr/lib/api/shrd_mem.c.in.me 2019-01-31 10:42:23.325797012 +0100
+++ opencryptoki-3.11.0/usr/lib/api/shrd_mem.c.in 2019-01-31 10:52:17.585191667 +0100
@@ -55,9 +55,11 @@ void *attach_shared_memory()
int shmid;
char *shmp;
struct stat statbuf;
+#if 0
struct group *grp;
struct passwd *pw, *epw;
uid_t uid, euid;
+#endif
#if !(MMAP)
// Really should fstat the tok_path, since it will be the actual
@@ -69,6 +71,7 @@ void *attach_shared_memory()
return NULL;
}
+#if 0
uid = getuid();
euid = geteuid();
// only check group membership if not root user
@@ -102,6 +105,7 @@ void *attach_shared_memory()
return NULL;
}
}
+#endif
Anchor->shm_tok = ftok(TOK_PATH, 'b');

View File

@ -1,21 +0,0 @@
diff -up opencryptoki-3.18.0/Makefile.am.me opencryptoki-3.18.0/Makefile.am
--- opencryptoki-3.18.0/Makefile.am.me 2022-05-09 22:25:07.980238715 +0200
+++ opencryptoki-3.18.0/Makefile.am 2022-05-09 22:25:29.292722755 +0200
@@ -78,7 +78,7 @@ if ENABLE_EP11TOK
endif
if ENABLE_P11SAK
test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true
- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -g pkcs11 -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true
+ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true
endif
if ENABLE_ICATOK
cd $(DESTDIR)$(libdir)/opencryptoki/stdll && \
@@ -129,7 +129,7 @@ endif
if ENABLE_DAEMON
test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true
test -f $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || $(INSTALL) -m 644 $(srcdir)/usr/sbin/pkcsslotd/opencryptoki.conf $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || true
- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -g pkcs11 -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true
+ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true
if ENABLE_SYSTEMD
mkdir -p $(DESTDIR)/usr/lib/tmpfiles.d
cp $(srcdir)/misc/tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d/opencryptoki.conf

View File

@ -1,51 +0,0 @@
commit cb4d7b125c7166602cb9094497a201b2f5a56985
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Oct 4 13:21:32 2022 +0200
pkcsicsf: Fix memory leak
Use confignode_deepfree() to also free appended config nodes.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/pkcsicsf/pkcsicsf.c b/usr/sbin/pkcsicsf/pkcsicsf.c
index 44f5ef34..b02d1fe5 100644
--- a/usr/sbin/pkcsicsf/pkcsicsf.c
+++ b/usr/sbin/pkcsicsf/pkcsicsf.c
@@ -129,7 +129,8 @@ static void add_token_config_entry(struct ConfigIdxStructNode *s, char *key, cha
return;
v = confignode_allocstringvaldumpable(key, value, 0, NULL);
- confignode_append(s->value, &v->base);
+ if (v != NULL)
+ confignode_append(s->value, &v->base);
}
static int add_token_config(const char *configname,
@@ -150,7 +151,7 @@ static int add_token_config(const char *configname,
confignode_freeeoc(eoc1);
confignode_freeeoc(eoc2);
}
- confignode_freeidxstruct(s);
+ confignode_deepfree(&s->base);
fprintf(stderr, "Failed to add an entry for %s token\n", token.name);
return -1;
}
@@ -179,7 +180,7 @@ static int add_token_config(const char *configname,
if (tfp == NULL) {
fprintf(stderr, "fopen failed, line %d: %s\n",
__LINE__, strerror(errno));
- confignode_freeidxstruct(s);
+ confignode_deepfree(&s->base);
return -1;
}
@@ -188,7 +189,7 @@ static int add_token_config(const char *configname,
confignode_dump(tfp, &s->base, NULL, 2);
fclose(tfp);
- confignode_freeidxstruct(s);
+ confignode_deepfree(&s->base);
return 0;
}

View File

@ -0,0 +1,27 @@
diff -up opencryptoki-3.21.0/misc/pkcsslotd.service.in.me opencryptoki-3.21.0/misc/pkcsslotd.service.in
--- opencryptoki-3.21.0/misc/pkcsslotd.service.in.me 2023-05-16 20:50:08.128841932 +0200
+++ opencryptoki-3.21.0/misc/pkcsslotd.service.in 2023-05-16 21:19:35.208570589 +0200
@@ -22,17 +22,17 @@ PrivateUsers=no
PrivateNetwork=no
RestrictAddressFamilies=AF_UNIX AF_NETLINK
IPAddressDeny=any
-ProtectClock=yes
+#ProtectClock=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
-ProtectKernelLogs=yes
+#ProtectKernelLogs=yes
ProtectControlGroups=yes
ProtectHome=yes
-ProtectHostname=yes
-ProtectProc=default
+#ProtectHostname=yes
+#ProtectProc=default
ProtectSystem=strict
-ReadWritePaths=@localstatedir@
-ProcSubset=all
+ReadWritePaths=@localstatedir@ /run
+#ProcSubset=all
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictNamespaces=yes

View File

@ -0,0 +1,34 @@
commit 2ba0f41ef5e14d4b509c8854e27cf98e3ee89445
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jul 10 13:22:48 2023 +0200
p11sak: Fix parsing of slot number 0
Running command 'p11sak list-key aes --slot 0' may result in
'p11sak: Invalid argument '0' for option '-s/--slot''
This is because of the error checking after strtoul() within function
process_number_argument(). In case errno is not zero, it treats a
parsed value of zero as an error.
Under certain circumstances, errno is non-zero already before calling
strtoul(), and stays non-zero in case of strtoul() succeeds. This leads to
an incorrect error checking, and it is treated as error.
Initialize errno to zero before calling strtoul() to avoid such false error
detection.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 6e11cb41..38665bbd 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -1712,6 +1712,7 @@ static CK_RV process_number_argument(const struct p11sak_arg *arg, char *val)
{
char *endptr;
+ errno = 0;
*arg->value.number = strtoul(val, &endptr, 0);
if ((errno == ERANGE && *arg->value.number == ULONG_MAX) ||

View File

@ -0,0 +1,52 @@
commit 4ff774568e334a719fc8de16fe2309e2070f0da8
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon May 22 11:40:01 2023 +0200
p11sak: Fix user confirmation prompt behavior when stdin is closed
Treat any error during user confirmation prompt as 'cancel' and skip all
operations.
One can for example close stdin during a user prompt via CTRL+D. This was
erroneously treated as positive confirmation and therefore caused the
operation to be performed on the current key object and all further objects
matching the filter as well, instead of canceling the operation entirely.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index d75d8343..5b54b538 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -4736,6 +4736,7 @@ static CK_RV handle_key_remove(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -4825,6 +4826,7 @@ static CK_RV handle_key_set_attr(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -4974,6 +4976,7 @@ static CK_RV handle_key_copy(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;
@@ -6983,6 +6986,7 @@ static CK_RV handle_key_export(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS class,
data->num_skipped++;
return CKR_OK;
case 'c':
+ case '\0':
data->skip_all = true;
data->num_skipped++;
return CKR_OK;

View File

@ -0,0 +1,96 @@
commit 92999f344a3ad99a67a1bcfd9ad28f28c33e51bc
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jul 10 10:19:13 2023 +0200
p11sak: Fix listing of key objects when other object types are present
A command like 'p11sak list-key all --slot N ...' fails with
p11sak: Attribute CKA_KEY_TYPE is not available in key object
p11sak: Failed to iterate over key objects for key type All: 0xD0: CKR_TEMPLATE_INCOMPLETE
p11sak: Failed to perform the 'list-key' command: CKR_TEMPLATE_INCOMPLETE
when the object repository contains other, non-key objects, e.g. certificates.
When 'all' is used as key type, then no filter for CKA_KEY_TYPE is used
with C_FindObjects(), and thus other non-key objects also match the filter.
When a specific key type is specified, then only such objects match that
have the desired CKA_KEY_TYPE attribute value.
Fix this by checking the object class in get_key_infos() and skip the object,
if it is not a key object.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index a6213720..6e11cb41 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -3403,6 +3403,16 @@ static CK_RV get_key_infos(CK_OBJECT_HANDLE key, CK_OBJECT_CLASS *class,
}
}
+ switch (class_val) {
+ case CKO_PUBLIC_KEY:
+ case CKO_PRIVATE_KEY:
+ case CKO_SECRET_KEY:
+ break;
+ default:
+ free(attrs[0].pValue);
+ return CKR_KEY_NEEDED;
+ }
+
for (i = 0; i < num_attrs; i++) {
if (attrs[i].ulValueLen == CK_UNAVAILABLE_INFORMATION) {
warnx("Attribute %s is not available in key object",
@@ -3614,6 +3624,10 @@ static CK_RV iterate_key_objects(const struct p11sak_keytype *keytype,
if (manual_filtering) {
rc = get_key_infos(keys[i], NULL, NULL, NULL, &label,
NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ goto next;
+ }
if (rc != CKR_OK)
break;
@@ -3672,6 +3686,10 @@ done_find:
for (i = 0; i < num_matched_keys; i++) {
rc = get_key_infos(matched_keys[i], &class, &ktype, &keysize,
&label, &typestr, &type);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ goto next2;
+ }
if (rc != CKR_OK)
break;
@@ -3680,6 +3698,7 @@ done_find:
if (rc != CKR_OK)
break;
+next2:
if (label != NULL)
free(label);
label = NULL;
@@ -4480,10 +4499,20 @@ static CK_RV p11sak_list_key_compare(CK_OBJECT_HANDLE key1,
*result = 0;
rc = get_key_infos(key1, &class1, &ktype1, &keysize1, &label1, NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ *result = 1; /* non-key objects are always greater than key objects */
+ goto done;
+ }
if (rc != CKR_OK)
goto done;
rc = get_key_infos(key2, &class2, &ktype2, &keysize2, &label2, NULL, NULL);
+ if (rc == CKR_KEY_NEEDED) {
+ rc = CKR_OK;
+ *result = -1; /* key objects are always smaller than non-key objects */
+ goto done;
+ }
if (rc != CKR_OK)
goto done;

View File

@ -0,0 +1,84 @@
commit f4166214552a92d8d66de8011ab11c9c2c6bb0a4
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon May 22 13:31:21 2023 +0200
pkcsstats: Fix handling of user name
The struct passwd returned by getpwuid() is a pointer to a static area, that
may get overwritten by subsequent calls to getpwuid() or similar.
Actually, C_Initialize() itself is using getpwuid() internally, and thus will
interfere with the getpwuid() usage in pkcsstats.
Make a copy of the returned user name before calling C_Initialize() in
init_ock() to ensure to work with the desired user name, and not with anything
left over from previous calls.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/pkcsstats/pkcsstats.c b/usr/sbin/pkcsstats/pkcsstats.c
index c2444cf5..a842a295 100644
--- a/usr/sbin/pkcsstats/pkcsstats.c
+++ b/usr/sbin/pkcsstats/pkcsstats.c
@@ -783,6 +783,7 @@ int main(int argc, char **argv)
int opt = 0;
struct passwd *pswd = NULL;
int user_id = -1;
+ char *user_name = NULL;
bool summary = false, all_users = false, all_mechs = false;
bool reset = false, reset_all = false;
bool delete = false, delete_all = false;
@@ -903,19 +904,27 @@ int main(int argc, char **argv)
}
}
+ user_name = strdup(pswd->pw_name);
+ if (user_name == NULL) {
+ warnx("Failed to get current user name");
+ exit(EXIT_FAILURE);
+ }
+
if (delete) {
if (slot_id_specified) {
warnx("Options -s/--slot and -d/--delete can not be specified together");
+ free(user_name);
exit(EXIT_FAILURE);
}
- rc = delete_shm(user_id, pswd->pw_name);
+ rc = delete_shm(user_id, user_name);
goto done;
}
if (delete_all) {
if (slot_id_specified) {
warnx("Options -s/--slot and -D/--delete-all can not be specified together");
+ free(user_name);
exit(EXIT_FAILURE);
}
@@ -932,7 +941,7 @@ int main(int argc, char **argv)
goto done;
if (reset) {
- rc = reset_shm(user_id, pswd->pw_name, num_slots, slots,
+ rc = reset_shm(user_id, user_name, num_slots, slots,
slot_id_specified, slot_id);
goto done;
}
@@ -968,7 +977,7 @@ int main(int argc, char **argv)
rc = display_summary(&dd);
goto done;
} else {
- rc = display_stats(user_id, pswd->pw_name, &dd);
+ rc = display_stats(user_id, user_name, &dd);
goto done;
}
@@ -984,5 +993,7 @@ done:
dlclose(dll);
}
+ free(user_name);
+
return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@ -0,0 +1,37 @@
commit f8ddcd5ba7e5b0bab00dedc89021147ec55b41b3
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue May 23 15:07:02 2023 +0200
p11sak: Fix segfault in PEM_write_bio() on OpenSSL 1.1.1
On OpenSSL version before 1.1.1r function PEM_write_bio() segfaults when the
'header' argument is NULL. This was fixed in OpenSSL 1.1.1r with commit
https://github.com/openssl/openssl/commit/3b9082c844913d3a0efada9fac0bd2924ce1a8f2
As a workaround, specify an empty string instead of NULL, which results in the
same output.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/sbin/p11sak/p11sak.c b/usr/sbin/p11sak/p11sak.c
index 5b54b538..3baae560 100644
--- a/usr/sbin/p11sak/p11sak.c
+++ b/usr/sbin/p11sak/p11sak.c
@@ -6794,7 +6794,7 @@ static CK_RV p11sak_export_spki(const struct p11sak_keytype *keytype,
return rc;
}
- ret = PEM_write_bio(bio, PEM_STRING_PUBLIC, NULL,
+ ret = PEM_write_bio(bio, PEM_STRING_PUBLIC, "",
attr.pValue, attr.ulValueLen);
if (ret <= 0) {
warnx("Failed to write SPKI of %s key object \"%s\" to PEM file '%s'.",
@@ -6888,7 +6888,7 @@ static CK_RV p11sak_export_asym_key(const struct p11sak_keytype *keytype,
ret = PEM_write_bio(bio, private ?
keytype->pem_name_private :
keytype->pem_name_public,
- NULL, data, data_len);
+ "", data, data_len);
if (ret <= 0) {
warnx("Failed to write %s key object \"%s\" to PEM file '%s'.",
typestr, label, opt_file);

View File

@ -0,0 +1,37 @@
diff -up opencryptoki-3.21.0/Makefile.am.me opencryptoki-3.21.0/Makefile.am
--- opencryptoki-3.21.0/Makefile.am.me 2023-05-15 17:01:04.932616030 +0200
+++ opencryptoki-3.21.0/Makefile.am 2023-05-15 17:00:45.732131601 +0200
@@ -39,15 +39,8 @@ include tools/tools.mk
include doc/doc.mk
install-data-hook:
- getent group $(pkcs_group) > /dev/null || $(GROUPADD) -r $(pkcs_group)
- getent passwd $(pkcsslotd_user) >/dev/null || $(USERADD) -r -g $(pkcs_group) -d /run/opencryptoki -s /sbin/nologin -c "Opencryptoki pkcsslotd user" $(pkcsslotd_user)
$(MKDIR_P) $(DESTDIR)/run/opencryptoki/
- $(CHOWN) $(pkcsslotd_user):$(pkcs_group) $(DESTDIR)/run/opencryptoki/
- $(CHGRP) $(pkcs_group) $(DESTDIR)/run/opencryptoki/
- $(CHMOD) 0710 $(DESTDIR)/run/opencryptoki/
$(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/opencryptoki
- $(CHGRP) $(pkcs_group) $(DESTDIR)$(localstatedir)/lib/opencryptoki
- $(CHMOD) 0770 $(DESTDIR)$(localstatedir)/lib/opencryptoki
if ENABLE_LIBRARY
$(MKDIR_P) $(DESTDIR)$(libdir)/opencryptoki/stdll
$(MKDIR_P) $(DESTDIR)$(libdir)/pkcs11
@@ -100,7 +93,7 @@ if ENABLE_EP11TOK
endif
if ENABLE_P11SAK
test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true
- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -g $(pkcs_group) -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true
+ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true
endif
if ENABLE_ICATOK
cd $(DESTDIR)$(libdir)/opencryptoki/stdll && \
@@ -151,7 +144,7 @@ endif
if ENABLE_DAEMON
test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true
test -f $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || $(INSTALL) -m 644 $(srcdir)/usr/sbin/pkcsslotd/opencryptoki.conf $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || true
- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -g $(pkcs_group) -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true
+ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true
endif
$(MKDIR_P) $(DESTDIR)/etc/ld.so.conf.d
echo "$(libdir)/opencryptoki" >\

View File

@ -0,0 +1,153 @@
commit f931d6e47bf2fb26aa9cf52e231d13edc1c837a1
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Tue Dec 12 17:16:56 2023 +0100
COMMON: Update rsa_parse_block_type_2() to not leak the message length
Take the implementation of OpenSSL function RSA_padding_check_PKCS1_type_2()
in crypto/rsa/rsa_pk1.c instead of ossl_rsa_padding_check_PKCS1_type_2(), since
the latter leaks the message size.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
index 326c5795..7bab1a84 100644
--- a/usr/lib/common/mech_rsa.c
+++ b/usr/lib/common/mech_rsa.c
@@ -29,6 +29,7 @@
#include "constant_time.h"
#include <openssl/crypto.h>
+#include <openssl/rsa.h>
CK_BBOOL is_rsa_mechanism(CK_MECHANISM_TYPE mech)
{
@@ -293,13 +294,16 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
CK_BYTE *out_data,
CK_ULONG *out_data_len)
{
- unsigned int ok = 0, found, zero;
- size_t zero_index = 0, msg_index, mlen;
- size_t i, j;
+ int i;
+ unsigned char *em = NULL;
+ unsigned int good, found_zero_byte, mask, equals0;
+ int zero_index = 0, msg_index, mlen = -1;
+ int out_len = *out_data_len;
+ int rsa_size = in_data_len;
/*
* The implementation of this function is copied from OpenSSL's function
- * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
+ * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
*
* The OpenSSL code is licensed under the Apache License 2.0.
@@ -324,55 +328,86 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
* section 7.2.2.
*/
- if (in_data_len < 11) {
+ if (rsa_size < RSA_PKCS1_PADDING_SIZE) {
TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
- ok = constant_time_is_zero(in_data[0]);
- ok &= constant_time_eq(in_data[1], 2);
+ em = malloc(rsa_size);
+ if (em == NULL) {
+ TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY));
+ return CKR_HOST_MEMORY;
+ }
+
+ /* in_data_len is always equal to rsa_size */
+ memcpy(em, in_data, rsa_size);
+
+ good = constant_time_is_zero(em[0]);
+ good &= constant_time_eq(em[1], 2);
/* scan over padding data */
- found = 0;
- for (i = 2; i < in_data_len; i++) {
- zero = constant_time_is_zero(in_data[i]);
+ found_zero_byte = 0;
+ for (i = 2; i < rsa_size; i++) {
+ equals0 = constant_time_is_zero(em[i]);
- zero_index = constant_time_select_int(~found & zero, i, zero_index);
- found |= zero;
+ zero_index = constant_time_select_int(~found_zero_byte & equals0,
+ i, zero_index);
+ found_zero_byte |= equals0;
}
/*
- * PS must be at least 8 bytes long, and it starts two bytes into |enc_msg|.
+ * PS must be at least 8 bytes long, and it starts two bytes into |em|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
- ok &= constant_time_ge(zero_index, 2 + 8);
+ good &= constant_time_ge(zero_index, 2 + 8);
/*
* Skip the zero byte. This is incorrect if we never found a zero-byte
* but in this case we also do not copy the message out.
*/
msg_index = zero_index + 1;
- mlen = in_data_len - msg_index;
+ mlen = rsa_size - msg_index;
/*
* For good measure, do this check in constant time as well.
*/
- ok &= constant_time_ge(*out_data_len, mlen);
+ good &= constant_time_ge(out_len, mlen);
/*
- * since at this point the |msg_index| does not provide the signal
- * indicating if the padding check failed or not, we don't have to worry
- * about leaking the length of returned message, we still need to ensure
- * that we read contents of both buffers so that cache accesses don't leak
- * the value of |good|
+ * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen|
+ * bytes to the left.
+ * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to
+ * |out_data|. Otherwise leave |out_data| unchanged.
+ * Copy the memory back in a way that does not reveal the size of
+ * the data being copied via a timing side channel. This requires copying
+ * parts of the buffer multiple times based on the bits set in the real
+ * length. Clear bits do a non-copy with identical access pattern.
+ * The loop below has overall complexity of O(N*log(N)).
*/
- for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len; i++, j++)
- out_data[j] = constant_time_select_8(ok, in_data[i], out_data[j]);
+ out_len = constant_time_select_int(
+ constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len),
+ rsa_size - RSA_PKCS1_PADDING_SIZE,
+ out_len);
+ for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE;
+ msg_index <<= 1) {
+ mask = ~constant_time_eq(
+ msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0);
+ for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++)
+ em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]);
+ }
+ for (i = 0; i < out_len; i++) {
+ mask = good & constant_time_lt(i, mlen);
+ out_data[i] = constant_time_select_8(
+ mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]);
+ }
+
+ OPENSSL_cleanse(em, rsa_size);
+ free(em);
- *out_data_len = j;
+ *out_data_len = constant_time_select_int(good, mlen, 0);
- return constant_time_select_int(ok, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
+ return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
}
CK_RV rsa_parse_block(CK_BYTE *in_data,

View File

@ -0,0 +1,737 @@
commit 5f1a4f8641306ee192b70c8a32c9ee8a0fe9be5f
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon Jan 15 12:53:37 2024 +0100
common: Add support for implicit rejection for RSA PKCS#1 v1.5 de-padding
Implicit rejection returns a pseudo random message in case the RSA PKCS#1 v1.5
padding is incorrect, but returns no error. The pseudo random message is based
on static secret data (the private exponent) and the provided ciphertext, so
that the attacker cannot determine that the returned value is randomly generated
instead of the result of decryption and de-padding.
The implicit rejection algorithm is the same as used by OpenSSL.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/COPYRIGHTS b/COPYRIGHTS
index 2bb3dffe..21b6b702 100644
--- a/COPYRIGHTS
+++ b/COPYRIGHTS
@@ -12,19 +12,29 @@ For code originating from OpenSSL:
* Note that in OpenSSL the file crypto/bn/rsa_sup_mul.c does no longer
* exist, it was removed with commit https://github.com/openssl/openssl/commit/4209ce68d8fe8b1506494efa03d378d05baf9ff8
* - usr/lib/common/constant_time.h: Copied unchanged from OpenSSL from
- include/internal/constant_time.h
+ * include/internal/constant_time.h
* - The implementation of function rsa_parse_block_type_2() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
* See comment in function rsa_parse_block_type_2() for a list of changes.
+ * - The implementation of function openssl_specific_rsa_derive_kdk() in
+ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function
+ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to
+ * the OpenCryptoki environment. See comment in function
+ * openssl_specific_rsa_derive_kdk() for a list of changes.
+ * - The implementation of function openssl_specific_rsa_prf() in
+ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function
+ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to
+ * the OpenCryptoki environment. See comment in function
+ * openssl_specific_rsa_prf() for a list of changes.
* - The implementation of function decode_eme_oaep() in
* usr/lib/common/mech_rsa.c is copied from OpenSSL's function
* RSA_padding_check_PKCS1_OAEP_mgf1() in crypto/rsa/rsa_oaep.c and is
* slightly modified to fit to the OpenCryptoki environment. See comment in
* function decode_eme_oaep() for a list of changes.
*
- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* The OpenSSL code is licensed under the Apache License 2.0 (the "License").
* You can obtain a copy in the file LICENSE in the OpenSSL source distribution
diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h
index a88b57d0..29496d99 100644
--- a/usr/lib/common/h_extern.h
+++ b/usr/lib/common/h_extern.h
@@ -731,7 +731,8 @@ CK_RV rsa_format_block(STDLL_TokData_t *tokdata,
CK_RV rsa_parse_block(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len, CK_ULONG type);
+ CK_ULONG *out_data_len, CK_ULONG type,
+ CK_BYTE *kdk, CK_ULONG kdklen);
CK_RV get_mgf_mech(CK_RSA_PKCS_MGF_TYPE mgf, CK_MECHANISM_TYPE *mech);
@@ -3179,6 +3180,14 @@ CK_RV openssl_specific_hmac_update(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data,
CK_RV openssl_specific_hmac_final(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *signature,
CK_ULONG *sig_len, CK_BBOOL sign);
+CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ const CK_BYTE *in, CK_ULONG inlen,
+ CK_BYTE *kdk, CK_ULONG kdklen);
+CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen,
+ const char *label, CK_ULONG labellen,
+ const CK_BYTE *kdk, CK_ULONG kdklen,
+ uint16_t bitlen);
+
#include "tok_spec_struct.h"
extern token_spec_t token_specific;
diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c
index 9983fcb3..da515289 100644
--- a/usr/lib/common/mech_openssl.c
+++ b/usr/lib/common/mech_openssl.c
@@ -1154,6 +1154,7 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata,
CK_RV rc;
CK_BYTE out[MAX_RSA_KEYLEN];
CK_ULONG modulus_bytes;
+ unsigned char kdk[SHA256_HASH_SIZE] = { 0 };
modulus_bytes = in_data_len;
@@ -1163,7 +1164,16 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata,
goto done;
}
- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2);
+ rc = openssl_specific_rsa_derive_kdk(tokdata, key_obj,
+ in_data, in_data_len,
+ kdk, sizeof(kdk));
+ if (rc != CKR_OK) {
+ TRACE_DEVEL("openssl_specific_rsa_derive_kdk failed\n");
+ goto done;
+ }
+
+ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2,
+ kdk, sizeof(kdk));
done:
OPENSSL_cleanse(out, sizeof(out));
@@ -1254,7 +1264,7 @@ CK_RV openssl_specific_rsa_pkcs_verify(STDLL_TokData_t *tokdata, SESSION *sess,
}
rc = rsa_parse_block(out, modulus_bytes, out_data, &out_data_len,
- PKCS_BT_1);
+ PKCS_BT_1, NULL, 0);
if (rc == CKR_ENCRYPTED_DATA_INVALID) {
TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID));
return CKR_SIGNATURE_INVALID;
@@ -1318,7 +1328,8 @@ CK_RV openssl_specific_rsa_pkcs_verify_recover(STDLL_TokData_t *tokdata,
return rc;
}
- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1);
+ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1,
+ NULL, 0);
if (rc == CKR_ENCRYPTED_DATA_INVALID) {
TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID));
return CKR_SIGNATURE_INVALID;
@@ -4983,3 +4994,388 @@ done:
ctx->context = NULL;
return rv;
}
+
+static CK_RV calc_rsa_priv_exp(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ CK_BYTE *priv_exp, CK_ULONG priv_exp_len)
+{
+ CK_ATTRIBUTE *modulus = NULL, *pub_exp = NULL;
+ CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL;
+ BN_CTX *bn_ctx;
+ BIGNUM *n, *e, *p, *q, *d;
+ CK_RV rc;
+
+ UNUSED(tokdata);
+
+ bn_ctx = BN_CTX_secure_new();
+ if (bn_ctx == NULL) {
+ TRACE_ERROR("BN_CTX_secure_new failed\n");
+ return CKR_FUNCTION_FAILED;
+ }
+
+ /* Get modulus a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
+ &modulus);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_MODULUS\n");
+ goto done;
+ }
+
+ n = BN_CTX_get(bn_ctx);
+ if (n == NULL ||
+ BN_bin2bn(modulus->pValue, modulus->ulValueLen, n) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for modulus\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(n, BN_FLG_CONSTTIME);
+
+ /* Get public exponent a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template,
+ CKA_PUBLIC_EXPONENT, &pub_exp);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PUBLIC_EXPONENT\n");
+ goto done;
+ }
+
+ e = BN_CTX_get(bn_ctx);
+ if (e == NULL ||
+ BN_bin2bn(pub_exp->pValue, pub_exp->ulValueLen, e) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for public exponent\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(e, BN_FLG_CONSTTIME);
+
+ /* Get prime1 a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_1,
+ &prime1);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PRIME_1\n");
+ goto done;
+ }
+
+ p = BN_CTX_get(bn_ctx);
+ if (p == NULL ||
+ BN_bin2bn(prime1->pValue, prime1->ulValueLen, p) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime1\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(p, BN_FLG_CONSTTIME);
+
+ /* Get prime2 a BIGNUM */
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_2,
+ &prime2);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_PRIME_2\n");
+ goto done;
+ }
+
+ q = BN_CTX_get(bn_ctx);
+ if (q == NULL ||
+ BN_bin2bn(prime2->pValue, prime2->ulValueLen, q) == NULL) {
+ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime2\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(q, BN_FLG_CONSTTIME);
+
+ d = BN_CTX_get(bn_ctx);
+ if (d == NULL) {
+ TRACE_ERROR("BN_CTX_get failed to get d\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+ BN_set_flags(d, BN_FLG_CONSTTIME);
+
+ /*
+ * phi(n) = (p - 1 )(q - 1) = n - p - q + 1
+ * d = e ^{-1} mod phi(n).
+ */
+ if (BN_copy(d, n) == NULL ||
+ BN_sub(d, d, p) == 0 ||
+ BN_sub(d, d, q) == 0 ||
+ BN_add_word(d, 1) == 0 ||
+ BN_mod_inverse(d, e, d, bn_ctx) == NULL) {
+ TRACE_ERROR("Failed to calculate private key part d\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+
+ if (BN_bn2binpad(d, priv_exp, priv_exp_len) <= 0) {
+ TRACE_ERROR("BN_bn2binpad failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto done;
+ }
+
+done:
+ BN_CTX_free(bn_ctx);
+
+ return rc;
+}
+
+CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
+ const CK_BYTE *in, CK_ULONG inlen,
+ CK_BYTE *kdk, CK_ULONG kdklen)
+{
+ CK_ATTRIBUTE *priv_exp_attr = NULL, *modulus = NULL;
+ CK_BYTE *priv_exp = NULL, *buf = NULL;
+ EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *mdctx = NULL;
+ const EVP_MD *md = NULL;
+ size_t md_len;
+ unsigned char d_hash[SHA256_HASH_SIZE] = { 0 };
+ CK_RV rc;
+
+ /*
+ * The implementation of this function is copied from OpenSSL's function
+ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to
+ * the OpenCryptoki environment.
+ * Changes include:
+ * - Different variable and define names.
+ * - Usage of TRACE_ERROR to report errors and issue debug messages.
+ * - Different return codes.
+ * - Different code to get the private key component 'd'.
+ * - Use of the EVP APIs instead of the internal APIs for Digest and HMAC
+ * operations.
+ */
+
+ if (kdklen != SHA256_HASH_SIZE) {
+ TRACE_ERROR("KDK length is wrong\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS,
+ &modulus);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("Failed to get CKA_MODULUS\n");
+ return rc;
+ }
+
+ buf = calloc(1, modulus->ulValueLen);
+ if (buf == NULL) {
+ TRACE_ERROR("Failed to allocate a buffer for private exponent\n");
+ return CKR_HOST_MEMORY;
+ }
+
+ rc = template_attribute_get_non_empty(key_obj->template,
+ CKA_PRIVATE_EXPONENT, &priv_exp_attr);
+ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) {
+ TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n");
+ goto out;
+ }
+
+ if (priv_exp_attr == NULL) {
+ rc = calc_rsa_priv_exp(tokdata, key_obj, buf, modulus->ulValueLen);
+ if (rc != CKR_OK) {
+ TRACE_ERROR("calc_rsa_priv_exp failed\n");
+ goto out;
+ }
+ priv_exp = buf;
+ } else {
+ if (priv_exp_attr->ulValueLen < modulus->ulValueLen) {
+ memcpy(buf + modulus->ulValueLen - priv_exp_attr->ulValueLen,
+ priv_exp_attr->pValue, priv_exp_attr->ulValueLen);
+ priv_exp = buf;
+ } else {
+ priv_exp = (CK_BYTE *)priv_exp_attr->pValue +
+ priv_exp_attr->ulValueLen - modulus->ulValueLen;
+ }
+ }
+
+ /*
+ * we use hardcoded hash so that migrating between versions that use
+ * different hash doesn't provide a Bleichenbacher oracle:
+ * if the attacker can see that different versions return different
+ * messages for the same ciphertext, they'll know that the message is
+ * synthetically generated, which means that the padding check failed
+ */
+ md = EVP_sha256();
+ if (md == NULL) {
+ TRACE_ERROR("EVP_sha256 failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (EVP_Digest(priv_exp, modulus->ulValueLen, d_hash, NULL,
+ md, NULL) <= 0) {
+ TRACE_ERROR("EVP_Digest failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, d_hash, sizeof(d_hash));
+ if (pkey == NULL) {
+ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ mdctx = EVP_MD_CTX_create();
+ if (mdctx == NULL) {
+ TRACE_ERROR("EVP_MD_CTX_create() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey) != 1) {
+ TRACE_ERROR("EVP_DigestSignInit failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ if (inlen < modulus->ulValueLen) {
+ memset(buf, 0, modulus->ulValueLen - inlen);
+ if (EVP_DigestSignUpdate(mdctx, buf, modulus->ulValueLen - inlen)!= 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ }
+ if (EVP_DigestSignUpdate(mdctx, in, inlen) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ md_len = kdklen;
+ if (EVP_DigestSignFinal(mdctx, kdk, &md_len) != 1 ||
+ md_len != kdklen) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ rc = CKR_OK;
+
+out:
+ if (buf != NULL)
+ free(buf);
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ if (mdctx != NULL)
+ EVP_MD_CTX_free(mdctx);
+
+ return rc;
+}
+
+CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen,
+ const char *label, CK_ULONG labellen,
+ const CK_BYTE *kdk, CK_ULONG kdklen,
+ uint16_t bitlen)
+{
+ CK_RV rc;
+ CK_ULONG pos;
+ uint16_t iter = 0;
+ unsigned char be_iter[sizeof(iter)];
+ unsigned char be_bitlen[sizeof(bitlen)];
+ EVP_PKEY *pkey = NULL;
+ EVP_MD_CTX *mdctx = NULL;
+ unsigned char hmac_out[SHA256_HASH_SIZE];
+ size_t md_len;
+
+ /*
+ * The implementation of this function is copied from OpenSSL's function
+ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to
+ * the providers environment.
+ * Changes include:
+ * - Different variable and define names.
+ * - Usage of TRACE_ERROR report errors and issue debug messages.
+ * - Different return codes.
+ * - Use of the EVP API instead of the internal APIs for HMAC operations.
+ */
+
+ if (kdklen != SHA256_HASH_SIZE) {
+ TRACE_ERROR("invalid kdklen\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+ if (outlen * 8 != bitlen) {
+ TRACE_ERROR("invalid outlen\n");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ be_bitlen[0] = (bitlen >> 8) & 0xff;
+ be_bitlen[1] = bitlen & 0xff;
+
+ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, kdk, kdklen);
+ if (pkey == NULL) {
+ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ mdctx = EVP_MD_CTX_create();
+ if (mdctx == NULL) {
+ TRACE_ERROR("EVP_MD_CTX_create() failed.\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ /*
+ * we use hardcoded hash so that migrating between versions that use
+ * different hash doesn't provide a Bleichenbacher oracle:
+ * if the attacker can see that different versions return different
+ * messages for the same ciphertext, they'll know that the message is
+ * synthetically generated, which means that the padding check failed
+ */
+ for (pos = 0; pos < outlen; pos += SHA256_HASH_SIZE, iter++) {
+ if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) {
+ TRACE_ERROR("EVP_DigestSignInit failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ be_iter[0] = (iter >> 8) & 0xff;
+ be_iter[1] = iter & 0xff;
+
+ if (EVP_DigestSignUpdate(mdctx, be_iter, sizeof(be_iter)) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ if (EVP_DigestSignUpdate(mdctx, (unsigned char *)label, labellen) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ if (EVP_DigestSignUpdate(mdctx, be_bitlen, sizeof(be_bitlen)) != 1) {
+ TRACE_ERROR("EVP_DigestSignUpdate failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ /*
+ * HMAC_Final requires the output buffer to fit the whole MAC
+ * value, so we need to use the intermediate buffer for the last
+ * unaligned block
+ */
+ md_len = SHA256_HASH_SIZE;
+ if (pos + SHA256_HASH_SIZE > outlen) {
+ md_len = sizeof(hmac_out);
+ if (EVP_DigestSignFinal(mdctx, hmac_out, &md_len) != 1) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ memcpy(out + pos, hmac_out, outlen - pos);
+ } else {
+ md_len = outlen - pos;
+ if (EVP_DigestSignFinal(mdctx, out + pos, &md_len) != 1) {
+ TRACE_ERROR("EVP_DigestSignFinal failed\n");
+ rc = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+ }
+ }
+
+ rc = CKR_OK;
+
+out:
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ if (mdctx != NULL)
+ EVP_MD_CTX_free(mdctx);
+
+ return rc;
+}
+
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
index 7bab1a84..7dc9589a 100644
--- a/usr/lib/common/mech_rsa.c
+++ b/usr/lib/common/mech_rsa.c
@@ -289,21 +289,34 @@ static CK_RV rsa_parse_block_type_1(CK_BYTE *in_data,
return rc;
}
+#define MAX_LEN_GEN_TRIES 128
+
static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len)
+ CK_ULONG *out_data_len,
+ CK_BYTE *kdk, CK_ULONG kdklen)
{
- int i;
- unsigned char *em = NULL;
- unsigned int good, found_zero_byte, mask, equals0;
- int zero_index = 0, msg_index, mlen = -1;
- int out_len = *out_data_len;
- int rsa_size = in_data_len;
+ unsigned int good = 0, found_zero_byte, equals0;
+ size_t zero_index = 0, msg_index;
+ unsigned char *synthetic = NULL;
+ int synthetic_length;
+ uint16_t len_candidate;
+ unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)];
+ uint16_t len_mask;
+ uint16_t max_sep_offset;
+ int synth_msg_index = 0;
+ size_t i, j;
+ CK_RV rc;
+
+ if (kdk == NULL || kdklen == 0) {
+ TRACE_DEVEL("%s\n", ock_err(ERR_ARGUMENTS_BAD));
+ return CKR_ARGUMENTS_BAD;
+ }
/*
* The implementation of this function is copied from OpenSSL's function
- * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
+ * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c
* and is slightly modified to fit to the OpenCryptoki environment.
*
* The OpenSSL code is licensed under the Apache License 2.0.
@@ -328,27 +341,67 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
* section 7.2.2.
*/
- if (rsa_size < RSA_PKCS1_PADDING_SIZE) {
+ if (in_data_len < RSA_PKCS1_PADDING_SIZE) {
TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED));
return CKR_FUNCTION_FAILED;
}
- em = malloc(rsa_size);
- if (em == NULL) {
- TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY));
+ /* Generate a random message to return in case the padding checks fail. */
+ synthetic = calloc(1, in_data_len);
+ if (synthetic == NULL) {
+ TRACE_ERROR("Failed to allocate synthetic buffer");
return CKR_HOST_MEMORY;
}
- /* in_data_len is always equal to rsa_size */
- memcpy(em, in_data, rsa_size);
+ rc = openssl_specific_rsa_prf(synthetic, in_data_len, "message", 7,
+ kdk, kdklen, in_data_len * 8);
+ if (rc != CKR_OK)
+ goto out;
+
+ /* decide how long the random message should be */
+ rc = openssl_specific_rsa_prf(candidate_lengths,
+ sizeof(candidate_lengths),
+ "length", 6, kdk, kdklen,
+ MAX_LEN_GEN_TRIES *
+ sizeof(len_candidate) * 8);
+ if (rc != CKR_OK)
+ goto out;
- good = constant_time_is_zero(em[0]);
- good &= constant_time_eq(em[1], 2);
+ /*
+ * max message size is the size of the modulus size minus 2 bytes for
+ * version and padding type and a minimum of 8 bytes padding
+ */
+ len_mask = max_sep_offset = in_data_len - 2 - 8;
+ /*
+ * we want a mask so let's propagate the high bit to all positions less
+ * significant than it
+ */
+ len_mask |= len_mask >> 1;
+ len_mask |= len_mask >> 2;
+ len_mask |= len_mask >> 4;
+ len_mask |= len_mask >> 8;
+
+ synthetic_length = 0;
+ for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate);
+ i += sizeof(len_candidate)) {
+ len_candidate = (candidate_lengths[i] << 8) |
+ candidate_lengths[i + 1];
+ len_candidate &= len_mask;
+
+ synthetic_length = constant_time_select_int(
+ constant_time_lt(len_candidate, max_sep_offset),
+ len_candidate, synthetic_length);
+ }
+
+ synth_msg_index = in_data_len - synthetic_length;
+
+ good = constant_time_is_zero(in_data[0]);
+ good &= constant_time_eq(in_data[1], 2);
/* scan over padding data */
found_zero_byte = 0;
- for (i = 2; i < rsa_size; i++) {
- equals0 = constant_time_is_zero(em[i]);
+ for (i = 2; i < in_data_len; i++) {
+ equals0 = constant_time_is_zero(in_data[i]);
zero_index = constant_time_select_int(~found_zero_byte & equals0,
i, zero_index);
@@ -356,7 +409,7 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
}
/*
- * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+ * PS must be at least 8 bytes long, and it starts two bytes into |in_data|.
* If we never found a 0-byte, then |zero_index| is 0 and the check
* also fails.
*/
@@ -367,53 +420,41 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data,
* but in this case we also do not copy the message out.
*/
msg_index = zero_index + 1;
- mlen = rsa_size - msg_index;
/*
- * For good measure, do this check in constant time as well.
+ * old code returned an error in case the decrypted message wouldn't fit
+ * into the |out_data|, since that would leak information, return the
+ * synthetic message instead
*/
- good &= constant_time_ge(out_len, mlen);
+ good &= constant_time_ge(*out_data_len, in_data_len - msg_index);
+
+ msg_index = constant_time_select_int(good, msg_index, synth_msg_index);
/*
- * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen|
- * bytes to the left.
- * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to
- * |out_data|. Otherwise leave |out_data| unchanged.
- * Copy the memory back in a way that does not reveal the size of
- * the data being copied via a timing side channel. This requires copying
- * parts of the buffer multiple times based on the bits set in the real
- * length. Clear bits do a non-copy with identical access pattern.
- * The loop below has overall complexity of O(N*log(N)).
+ * since at this point the |msg_index| does not provide the signal
+ * indicating if the padding check failed or not, we don't have to worry
+ * about leaking the length of returned message, we still need to ensure
+ * that we read contents of both buffers so that cache accesses don't leak
+ * the value of |good|
*/
- out_len = constant_time_select_int(
- constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len),
- rsa_size - RSA_PKCS1_PADDING_SIZE,
- out_len);
- for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE;
- msg_index <<= 1) {
- mask = ~constant_time_eq(
- msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0);
- for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++)
- em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]);
- }
- for (i = 0; i < out_len; i++) {
- mask = good & constant_time_lt(i, mlen);
- out_data[i] = constant_time_select_8(
- mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]);
- }
+ for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len;
+ i++, j++)
+ out_data[j] = constant_time_select_8(good, in_data[i], synthetic[i]);
- OPENSSL_cleanse(em, rsa_size);
- free(em);
+ *out_data_len = j;
- *out_data_len = constant_time_select_int(good, mlen, 0);
+out:
+ if (synthetic != NULL)
+ free(synthetic);
- return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID);
+ return rc;
}
CK_RV rsa_parse_block(CK_BYTE *in_data,
CK_ULONG in_data_len,
CK_BYTE *out_data,
- CK_ULONG *out_data_len, CK_ULONG type)
+ CK_ULONG *out_data_len, CK_ULONG type,
+ CK_BYTE *kdk, CK_ULONG kdklen)
{
switch (type) {
case PKCS_BT_1:
@@ -421,7 +462,7 @@ CK_RV rsa_parse_block(CK_BYTE *in_data,
out_data, out_data_len);
case PKCS_BT_2:
return rsa_parse_block_type_2(in_data, in_data_len,
- out_data, out_data_len);
+ out_data, out_data_len, kdk, kdklen);
}
return CKR_ARGUMENTS_BAD;

View File

@ -0,0 +1,387 @@
commit e2b496f58a84c2f537667655fe08a0d4923f0c70
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Jan 12 09:36:27 2024 +0100
Constant time fixes for C_Decrypt return code handling
Return code handling of C_Decrypt, C_DecryptUpdate, and C_DecryptFinal must
be performed in a constant time manner for RSA mechanisms. Otherwise it
may cause a timing side channel that may be used to perform a Bleichenbacher
style attack.
Handling of error situations with CKR_BUFFER_TOO_SMALL or size-query calls,
where the output buffer is NULL and the required size of the output buffer
is to be returned, do not need to be performed in constant time, since
these cases are shortcut anyway, and the result is only dependent on the
modulus size of the RSA key (which is public information anyway).
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c
index 8a1e8723..bbb0f601 100644
--- a/usr/lib/common/new_host.c
+++ b/usr/lib/common/new_host.c
@@ -47,6 +47,7 @@
#include "trace.h"
#include "slotmgr.h"
#include "attributes.h"
+#include "constant_time.h"
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -2345,6 +2346,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2377,11 +2379,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt(tokdata, sess, length_only, &sess->decr_ctx,
pEncryptedData, ulEncryptedDataLen, pData,
pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2404,6 +2414,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2436,11 +2447,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt_update(tokdata, sess, length_only,
&sess->decr_ctx, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2462,6 +2480,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2493,11 +2512,19 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = decr_mgr_decrypt_final(tokdata, sess, length_only, &sess->decr_ctx,
pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("decr_mgr_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 073b349f..6d08b95e 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -9552,10 +9552,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
@@ -9611,10 +9613,12 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
@@ -9676,10 +9680,12 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
rc = constant_time_select(constant_time_eq(rc, CKR_OK),
ep11_error_to_pkcs11_error(rc, session),
rc);
- if (rc != CKR_OK) {
- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
- } else {
- TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ if (!is_rsa_mechanism(ctx->mech.mechanism)) {
+ if (rc != CKR_OK) {
+ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
+ } else {
+ TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
+ }
}
done:
diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c
index 55e34c18..299a1d3c 100644
--- a/usr/lib/ep11_stdll/new_host.c
+++ b/usr/lib/ep11_stdll/new_host.c
@@ -38,6 +38,7 @@
#include "slotmgr.h"
#include "attributes.h"
#include "ep11_specific.h"
+#include "constant_time.h"
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -2466,6 +2467,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2513,17 +2515,29 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
length_only, sess->decr_ctx.key,
pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_single() failed.\n");
} else {
rc = ep11tok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt() failed.\n");
}
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2545,6 +2559,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
{
SESSION *sess = NULL;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2596,11 +2611,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = ep11tok_decrypt_update(tokdata, sess, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -2622,6 +2644,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -2670,10 +2693,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
}
rc = ep11tok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("ep11tok_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c
index 6c419750..d8064559 100644
--- a/usr/lib/icsf_stdll/new_host.c
+++ b/usr/lib/icsf_stdll/new_host.c
@@ -35,6 +35,8 @@
#include "slotmgr.h"
#include "attributes.h"
#include "icsf_specific.h"
+#include "constant_time.h"
+
#include "../api/apiproto.h"
#include "../api/policy.h"
@@ -1768,6 +1770,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1801,11 +1804,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = icsftok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -1827,6 +1838,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
{
SESSION *sess = NULL;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1857,11 +1869,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
rc = icsftok_decrypt_update(tokdata, sess, pEncryptedPart,
ulEncryptedPartLen, pPart, pulPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt_update() failed.\n");
done:
- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) {
+ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}
@@ -1883,6 +1902,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
SESSION *sess = NULL;
CK_BBOOL length_only = FALSE;
CK_RV rc = CKR_OK;
+ unsigned int mask;
if (tokdata->initialized == FALSE) {
TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED));
@@ -1915,10 +1935,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession,
length_only = TRUE;
rc = icsftok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen);
- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK)
+ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */
+ mask = ~constant_time_is_zero(
+ is_rsa_mechanism(sess->decr_ctx.mech.mechanism));
+ mask &= ~constant_time_eq(rc, CKR_OK);
+ if (mask)
TRACE_DEVEL("icsftok_decrypt_final() failed.\n");
done:
- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) {
+ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */
+ mask = ~constant_time_eq(rc, CKR_OK);
+ mask |= constant_time_is_zero(length_only);
+ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL);
+ if (mask) {
if (sess)
decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
commit d756ba1ec270a289950e66398c7e8be59c4a594d
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri Feb 9 14:07:34 2024 +0100
COMMON: Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT
An RSA key object that has no CKA_PRIVATE_EXPONENT may either don't have that
attribute at all, or may have an empty CKA_PRIVATE_EXPONENT attribute.
Both situations should be handed the same, and the private exponent of the
key needs to be calculated from the other key components.
Note that RSA key objects generated with a current soft or ICA token will
always have a valid CKA_PRIVATE_EXPONENT attribute, since this is provided
during key generation.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c
index da515289..14c82e2d 100644
--- a/usr/lib/common/mech_openssl.c
+++ b/usr/lib/common/mech_openssl.c
@@ -5160,7 +5160,8 @@ CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj,
rc = template_attribute_get_non_empty(key_obj->template,
CKA_PRIVATE_EXPONENT, &priv_exp_attr);
- if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) {
+ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE &&
+ rc != CKR_ATTRIBUTE_VALUE_INVALID) {
TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n");
goto out;
}

View File

@ -1,56 +1,40 @@
Name: opencryptoki
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0
Version: 3.19.0
Release: 2%{?dist}
Version: 3.21.0
Release: 10%{?dist}.alma.1
License: CPL
Group: System Environment/Base
URL: https://github.com/opencryptoki/opencryptoki
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
# https://bugzilla.redhat.com/show_bug.cgi?id=732756
Patch0: opencryptoki-3.11.0-group.patch
# bz#1373833, change tmpfiles snippets from /var/lock/* to /run/lock/*
Patch1: opencryptoki-3.11.0-lockdir.patch
# add missing p11sak_defined_attrs.conf
Patch2: opencryptoki-3.18.0-p11sak.patch
Patch2: opencryptoki-3.21.0-p11sak.patch
# comment some unsupported sandbox options and add /run to ReadWritePaths to exclude
# /run directory from being made read-only on rhel8
Patch3: opencryptoki-3.21-sandboxing.patch
# upstream patches
Patch100: opencryptoki-3.19.0-fix-memory-leak.patch
Patch101: 0001-EP11-Unify-key-pair-generation-functions.patch
Patch102: 0002-EP11-Do-not-report-DSA-DH-parameter-generation-as-be.patch
Patch103: 0003-EP11-Do-not-pass-empty-CKA_PUBLIC_KEY_INFO-to-EP11-h.patch
Patch104: 0004-Mechtable-CKM_IBM_DILITHIUM-can-also-be-used-for-key.patch
Patch105: 0005-EP11-Remove-DSA-DH-parameter-generation-mechanisms-f.patch
Patch106: 0006-EP11-Pass-back-chain-code-for-CKM_IBM_BTC_DERIVE.patch
Patch107: 0007-EP11-Supply-CKA_PUBLIC_KEY_INFO-with-CKM_IBM_BTC_DER.patch
Patch108: 0008-EP11-Supply-CKA_PUBLIC_KEY_INFO-when-importing-priva.patch
Patch109: 0009-EP11-Fix-memory-leak-introduced-with-recent-commit.patch
Patch110: 0010-p11sak-Fix-segfault-when-dilithium-version-is-not-sp.patch
Patch111: 0011-EP11-remove-dead-code-and-unused-variables.patch
Patch112: 0012-EP11-Update-EP11-host-library-header-files.patch
Patch113: 0013-EP11-Support-EP11-host-library-version-4.patch
Patch114: 0014-EP11-Add-new-control-points.patch
Patch115: 0015-EP11-Default-unknown-CPs-to-ON.patch
Patch116: 0016-COMMON-Add-defines-for-Dilithium-round-2-and-3-varia.patch
Patch117: 0017-COMMON-Add-defines-for-Kyber.patch
Patch118: 0018-COMMON-Add-post-quantum-algorithm-OIDs.patch
Patch119: 0019-COMMON-Dilithium-key-BER-encoding-decoding-allow-dif.patch
Patch120: 0020-COMMON-EP11-Add-CKA_VALUE-holding-SPKI-PKCS-8-of-key.patch
Patch121: 0021-COMMON-EP11-Allow-to-select-Dilithium-variant-via-mo.patch
Patch122: 0022-EP11-Query-supported-PQC-variants-and-restrict-usage.patch
Patch123: 0023-POLICY-Dilithium-strength-and-signature-size-depends.patch
Patch124: 0024-TESTCASES-Test-Dilithium-variants.patch
Patch125: 0025-COMMON-EP11-Add-Kyber-key-type-and-mechanism.patch
Patch126: 0026-EP11-Add-support-for-generating-and-importing-Kyber-.patch
Patch127: 0027-EP11-Add-support-for-encrypt-decrypt-and-KEM-operati.patch
Patch128: 0028-POLICY-STATISTICS-Check-for-Kyber-KEM-KDFs-and-count.patch
Patch129: 0029-TESTCASES-Add-tests-for-CKM_IBM_KYBER.patch
Patch130: 0030-p11sak-Support-additional-Dilithium-variants.patch
Patch131: 0031-p11sak-Add-support-for-IBM-Kyber-key-type.patch
Patch132: 0032-testcase-Enhance-p11sak-testcase-to-generate-IBM-Kyb.patch
Patch133: 0033-EP11-Supply-CKA_PUBLIC_KEY_INFO-with-CKM_IBM_BTC_DER.patch
Patch134: 0034-EP11-Fix-setting-unknown-CPs-to-ON.patch
# pkcsstats: Fix handling of user name
Patch100: opencryptoki-3.21.0-f4166214552a92d8d66de8011ab11c9c2c6bb0a4.patch
# p11sak: Fix user confirmation prompt behavior when stdin is closed
Patch101: opencryptoki-3.21.0-4ff774568e334a719fc8de16fe2309e2070f0da8.patch
# p11sak: Fix segfault in PEM_write_bio() on OpenSSL 1.1.1
Patch102: opencryptoki-3.21.0-f8ddcd5ba7e5b0bab00dedc89021147ec55b41b3.patch
# p11sak fails as soon as there reside non-key objects
Patch103: opencryptoki-3.21.0-92999f344a3ad99a67a1bcfd9ad28f28c33e51bc.patch
# opencryptoki p11sak tool: slot option does not accept argument 0 for slot index 0
Patch104: opencryptoki-3.21.0-2ba0f41ef5e14d4b509c8854e27cf98e3ee89445.patch
# CVE-2024-0914 opencryptoki: timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts
Patch20: opencryptoki-CVE-2024-0914-part1.patch
Patch21: opencryptoki-CVE-2024-0914-part2.patch
Patch22: opencryptoki-CVE-2024-0914-part3.patch
Patch23: opencryptoki-CVE-2024-0914-part4.patch
Patch24: opencryptoki-CVE-2024-0914-part5.patch
Requires(pre): coreutils diffutils
Requires: (selinux-policy >= 3.14.3-70 if selinux-policy-targeted)
Requires: (selinux-policy >= 3.14.3-121 if selinux-policy-targeted)
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: openssl-devel >= 1.1.1
@ -59,7 +43,7 @@ BuildRequires: openldap-devel
BuildRequires: autoconf automake libtool
BuildRequires: bison flex
BuildRequires: systemd-devel
BuildRequires: libitm-devel
BuildRequires: libcap-devel
BuildRequires: expect
BuildRequires: make
%ifarch s390 s390x
@ -224,6 +208,7 @@ configured with Enterprise PKCS#11 (EP11) firmware.
./bootstrap.sh
%configure --with-systemd=%{_unitdir} \
--with-pkcsslotd-user=pkcsslotd --with-pkcs-group=pkcs11 \
%ifarch s390 s390x
--enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate
%else
@ -272,6 +257,7 @@ fi
%pre libs
getent group pkcs11 >/dev/null || groupadd -r pkcs11
getent passwd pkcsslotd >/dev/null || useradd -r -g pkcs11 -d /run/opencryptoki -s /sbin/nologin -c "Opencryptoki pkcsslotd user" pkcsslotd
exit 0
%post
@ -294,6 +280,8 @@ fi
%postun
%systemd_postun_with_restart pkcsslotd.service
%triggerun -- opencryptoki < 3.21.0-1
/usr/bin/systemctl daemon-reload
%files
%doc ChangeLog FAQ README.md
@ -301,7 +289,7 @@ fi
%doc doc/README.token_data
%doc %{_docdir}/%{name}/*.conf
%dir %{_sysconfdir}/%{name}
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
%verify(not md5 size mtime) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
%attr(0640, root, pkcs11) %config(noreplace) %{_sysconfdir}/%{name}/p11sak_defined_attrs.conf
%attr(0640, root, pkcs11) %config(noreplace) %{_sysconfdir}/%{name}/strength.conf
%{_tmpfilesdir}/%{name}.conf
@ -311,10 +299,12 @@ fi
%{_sbindir}/pkcsconf
%{_sbindir}/pkcsslotd
%{_sbindir}/pkcsstats
%{_sbindir}/pkcshsm_mk_change
%{_mandir}/man1/p11sak.1*
%{_mandir}/man1/pkcstok_migrate.1*
%{_mandir}/man1/pkcsconf.1*
%{_mandir}/man1/pkcsstats.1*
%{_mandir}/man1/pkcshsm_mk_change.1*
%{_mandir}/man5/policy.conf.5*
%{_mandir}/man5/strength.conf.5*
%{_mandir}/man5/%{name}.conf.5*
@ -324,9 +314,10 @@ fi
%{_libdir}/opencryptoki/methods
%{_libdir}/pkcs11/methods
%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}
%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/HSM_MK_CHANGE
%ghost %dir %attr(770,root,pkcs11) %{_rundir}/lock/%{name}
%ghost %dir %attr(770,root,pkcs11) %{_rundir}/lock/%{name}/*
%dir %attr(770,root,pkcs11) %{_localstatedir}/log/opencryptoki
%dir %attr(710,pkcsslotd,pkcs11) /run/%{name}
%files libs
%license LICENSE
@ -342,6 +333,7 @@ fi
%{_libdir}/pkcs11/libopencryptoki.so
%{_libdir}/pkcs11/PKCS11_API.so
%{_libdir}/pkcs11/stdll
%dir %attr(770,root,pkcs11) %{_localstatedir}/log/opencryptoki
%files devel
%{_includedir}/%{name}/
@ -400,6 +392,51 @@ fi
%changelog
* Wed Apr 03 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 3.21.0-10.alma.1
- timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts (Marvin) (CVE-2024-0914)
* Tue Jul 18 2023 Than Ngo <than@redhat.com> - 3.21.0-9
- Resolves: #2223588, FTBFS
* Tue Jul 18 2023 Than Ngo <than@redhat.com> - 3.21.0-8
- Related: #2222595, add triggerun to reload daemon
* Fri Jul 14 2023 Than Ngo <than@redhat.com> - 3.21.0-7
- Resolves: #2222595, p11sak tool: slot option does not accept argument 0 for slot index 0
- Resolves: #2222594, p11sak fails as soon as there reside non-key objects
* Tue Jul 04 2023 Than Ngo <than@redhat.com> - 3.21.0-6
- add workaround for segfault in PEM_write_bio() on OpenSSL 1.1.1
Related: #2159741
* Tue Jun 13 2023 Than Ngo <than@redhat.com> - 3.21.0-5
- add requirement on selinux-policy >= 3.14.3-121 for pkcsslotd policy sandboxing
Related: #2159697
* Thu May 25 2023 Than Ngo <than@redhat.com> - 3.21.0-4
- add verify attributes for opencryptoki.conf to ignore the verification
Related: #2159697
* Mon May 22 2023 Than Ngo <than@redhat.com> - 3.21.0-3
- pkcsstats: Fix handling of user name
- p11sak: Fix user confirmation prompt behavior when stdin is closed
Related: #2159697
* Tue May 16 2023 Than Ngo <than@redhat.com> - 3.21.0-2
- add missing /var/lib/opencryptoki/HSM_MK_CHANGE
- disable unsupported sandbox options and add /run to ReadWritePaths to exclude
/run directory from being made read-only on rhel8
Related: #2159697
* Mon May 15 2023 Than Ngo <than@redhat.com> - 3.21.0-1
- Resolves: #1984865, ep11 and cca: support concurrent HSM master key changes
- Resolves: #2110500, ep11 token: PKCS #11 3.0 - support AES_XTS
- Resolves: #2111011, cca token: protected key support
- Resolves: #2159697, update to 3.21.0
- Resolves: #2159740, pkcsslotd hardening
- Resolves: #2159741, p11sak support Dilithium and Kyber keys
- Resolves: #2159742, ica and soft tokens: PKCS #11 3.0 - support AES_XTS
* Mon Jan 30 2023 Than Ngo <than@redhat.com> - 3.19.0-2
- Resolves: #2043856, Support of ep11 token for new IBM Z Hardware (IBM z16)