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

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