From ff2bfaa612704a7b8fb5126d450b596106421244 Mon Sep 17 00:00:00 2001 From: Ingo Franzki 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 --- 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 #include #include +#include /* 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