f41ca9bf97
- Added patch for compile errors * ocki-3.19.0-0035-Fix-compile-error-error-initializer-element-is-not-c.patch - Changed spec file to use %autosetup instead of %setup. - Updated the package openCryptoki 3.19.0 (jsc#PED-616, bsc#1207760), added the following patches: * ocki-3.19.0-0001-EP11-Unify-key-pair-generation-functions.patch * ocki-3.19.0-0002-EP11-Do-not-report-DSA-DH-parameter-generation-as-be.patch * ocki-3.19.0-0003-EP11-Do-not-pass-empty-CKA_PUBLIC_KEY_INFO-to-EP11-h.patch * ocki-3.19.0-0004-Mechtable-CKM_IBM_DILITHIUM-can-also-be-used-for-key.patch * ocki-3.19.0-0005-EP11-Remove-DSA-DH-parameter-generation-mechanisms-f.patch * ocki-3.19.0-0006-EP11-Pass-back-chain-code-for-CKM_IBM_BTC_DERIVE.patch * ocki-3.19.0-0007-EP11-Supply-CKA_PUBLIC_KEY_INFO-with-CKM_IBM_BTC_DER.patch * ocki-3.19.0-0008-EP11-Supply-CKA_PUBLIC_KEY_INFO-when-importing-priva.patch * ocki-3.19.0-0009-EP11-Fix-memory-leak-introduced-with-recent-commit.patch * ocki-3.19.0-0010-p11sak-Fix-segfault-when-dilithium-version-is-not-sp.patch * ocki-3.19.0-0011-EP11-remove-dead-code-and-unused-variables.patch * ocki-3.19.0-0012-EP11-Update-EP11-host-library-header-files.patch * ocki-3.19.0-0013-EP11-Support-EP11-host-library-version-4.patch * ocki-3.19.0-0014-EP11-Add-new-control-points.patch * ocki-3.19.0-0015-EP11-Default-unknown-CPs-to-ON.patch * ocki-3.19.0-0016-COMMON-Add-defines-for-Dilithium-round-2-and-3-varia.patch * ocki-3.19.0-0017-COMMON-Add-defines-for-Kyber.patch * ocki-3.19.0-0018-COMMON-Add-post-quantum-algorithm-OIDs.patch * ocki-3.19.0-0019-COMMON-Dilithium-key-BER-encoding-decoding-allow-dif.patch * ocki-3.19.0-0020-COMMON-EP11-Add-CKA_VALUE-holding-SPKI-PKCS-8-of-key.patch * ocki-3.19.0-0021-COMMON-EP11-Allow-to-select-Dilithium-variant-via-mo.patch * ocki-3.19.0-0022-EP11-Query-supported-PQC-variants-and-restrict-usage.patch * ocki-3.19.0-0023-POLICY-Dilithium-strength-and-signature-size-depends.patch * ocki-3.19.0-0024-TESTCASES-Test-Dilithium-variants.patch * ocki-3.19.0-0025-COMMON-EP11-Add-Kyber-key-type-and-mechanism.patch * ocki-3.19.0-0026-EP11-Add-support-for-generating-and-importing-Kyber-.patch * ocki-3.19.0-0027-EP11-Add-support-for-encrypt-decrypt-and-KEM-operati.patch * ocki-3.19.0-0028-POLICY-STATISTICS-Check-for-Kyber-KEM-KDFs-and-count.patch * ocki-3.19.0-0029-TESTCASES-Add-tests-for-CKM_IBM_KYBER.patch * ocki-3.19.0-0030-p11sak-Support-additional-Dilithium-variants.patch * ocki-3.19.0-0031-p11sak-Add-support-for-IBM-Kyber-key-type.patch * ocki-3.19.0-0032-testcase-Enhance-p11sak-testcase-to-generate-IBM-Kyb.patch * ocki-3.19.0-0033-EP11-Supply-CKA_PUBLIC_KEY_INFO-with-CKM_IBM_BTC_DER.patch * ocki-3.19.0-0034-EP11-Fix-setting-unknown-CPs-to-ON.patch OBS-URL: https://build.opensuse.org/request/show/1063652 OBS-URL: https://build.opensuse.org/package/show/security/openCryptoki?expand=0&rev=128
309 lines
12 KiB
Diff
309 lines
12 KiB
Diff
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
|
|
|