Blob Blame History Raw
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