Blame SOURCES/0008-EP11-Supply-CKA_PUBLIC_KEY_INFO-when-importing-priva.patch

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