Blame SOURCES/0033-EP11-Supply-CKA_PUBLIC_KEY_INFO-with-CKM_IBM_BTC_DER.patch

397a93
From df874a780108fa1390e4cb99144b9acb0667f76b Mon Sep 17 00:00:00 2001
397a93
From: Ingo Franzki <ifranzki@linux.ibm.com>
397a93
Date: Fri, 4 Nov 2022 11:33:50 +0100
397a93
Subject: [PATCH 33/34] EP11: Supply CKA_PUBLIC_KEY_INFO with
397a93
 CKM_IBM_BTC_DERIVE of private key
397a93
397a93
When deriving a private EC key with the CKM_IBM_BTC_DERIVE mechanism,
397a93
also supply the SPKI in the CKA_PUBLIC_KEY_INFO attribute.
397a93
397a93
To get the SPKI, use m_GetAttributeValue() with CKA_PUBLIC_KEY_INFO.
397a93
On newer EP11 host libraries this returns the SPKI of the corresponding
397a93
public key of the private key blob. In case the EP11 host library fails
397a93
to get the SPKI from the blob, ignore and do not supply an SPKI.
397a93
397a93
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
397a93
---
397a93
 usr/lib/ep11_stdll/ep11_specific.c | 266 +++++++++++++++++++++++--------------
397a93
 1 file changed, 168 insertions(+), 98 deletions(-)
397a93
397a93
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
397a93
index 9efce053..d4ece223 100644
397a93
--- a/usr/lib/ep11_stdll/ep11_specific.c
397a93
+++ b/usr/lib/ep11_stdll/ep11_specific.c
397a93
@@ -5316,7 +5316,148 @@ static CK_RV ep11tok_kyber_mech_post_process(STDLL_TokData_t *tokdata,
397a93
     return CKR_OK;
397a93
 }
397a93
 
397a93
-CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
+static CK_RV ep11tok_btc_mech_pre_process(STDLL_TokData_t *tokdata,
397a93
+                                          OBJECT *key_obj,
397a93
+                                          CK_ATTRIBUTE **new_attrs,
397a93
+                                          CK_ULONG *new_attrs_len)
397a93
+{
397a93
+    CK_ATTRIBUTE *ec_params;
397a93
+    CK_ULONG i, privlen;
397a93
+    CK_RV rc;
397a93
+
397a93
+    UNUSED(tokdata);
397a93
+
397a93
+    /*
397a93
+     * CKM_IBM_BTC_DERIVE requires CKA_VALUE_LEN to specify the byte length
397a93
+     * of the to be derived EC key. CKA_VALUE_LEN is dependent on the
397a93
+     * curve used.
397a93
+     * CKA_VALUE_LEN can not be already in the user supplied template,
397a93
+     * since this is not allowed by the key template check routines.
397a93
+     */
397a93
+    rc = template_attribute_get_non_empty(key_obj->template, CKA_EC_PARAMS,
397a93
+                                          &ec_params);
397a93
+    if (rc != CKR_OK) {
397a93
+        TRACE_ERROR("CKA_EC_PARAMS is required in derive template\n");
397a93
+        return rc;
397a93
+    }
397a93
+
397a93
+    for (i = 0; i < NUMEC; i++) {
397a93
+        if (der_ec_supported[i].data_size == ec_params->ulValueLen &&
397a93
+            memcmp(ec_params->pValue, der_ec_supported[i].data,
397a93
+                   ec_params->ulValueLen) == 0) {
397a93
+            privlen = (der_ec_supported[i].len_bits + 7) / 8;
397a93
+            rc = add_to_attribute_array(new_attrs, new_attrs_len,
397a93
+                                        CKA_VALUE_LEN,
397a93
+                                        (CK_BYTE_PTR)&privlen,
397a93
+                                        sizeof(privlen));
397a93
+            if (rc != CKR_OK) {
397a93
+                TRACE_ERROR("Adding attribute failed type=CKA_VALUE_LEN "
397a93
+                            "rc=0x%lx\n", rc);
397a93
+                return rc;
397a93
+            }
397a93
+            break;
397a93
+        }
397a93
+    }
397a93
+
397a93
+    return CKR_OK;
397a93
+}
397a93
+
397a93
+static CK_RV ep11tok_btc_mech_post_process(STDLL_TokData_t *tokdata,
397a93
+                                           SESSION *session, CK_MECHANISM *mech,
397a93
+                                           CK_ULONG class, CK_ULONG ktype,
397a93
+                                           OBJECT *key_obj,
397a93
+                                           CK_BYTE *blob, CK_ULONG bloblen,
397a93
+                                           CK_BYTE *csum, CK_ULONG cslen)
397a93
+{
397a93
+    CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
397a93
+    CK_BYTE *spki = NULL;
397a93
+    CK_ULONG spki_length = 0;
397a93
+    CK_BYTE buf[MAX_BLOBSIZE];
397a93
+    CK_ATTRIBUTE get_attr[1] = {{ CKA_PUBLIC_KEY_INFO, &buf, sizeof(buf) }};
397a93
+    CK_ATTRIBUTE *spki_attr = NULL;
397a93
+    CK_BBOOL allocated = FALSE;
397a93
+    CK_RV rc = CKR_OK;
397a93
+
397a93
+    if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
397a93
+        mech->pParameter == NULL) {
397a93
+        TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
397a93
+                    __func__, ep11_get_ckm(tokdata, mech->mechanism),
397a93
+                    mech->ulParameterLen);
397a93
+        return CKR_MECHANISM_PARAM_INVALID;
397a93
+    }
397a93
+
397a93
+    btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
397a93
+
397a93
+    if (btc_params != NULL && btc_params->pChainCode != NULL &&
397a93
+        cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
397a93
+        memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
397a93
+        btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
397a93
+    }
397a93
+
397a93
+    switch (class) {
397a93
+    case CKO_PUBLIC_KEY:
397a93
+        /* Derived blob is an SPKI, extract public EC key attributes */
397a93
+        rc = ecdsa_priv_unwrap_get_data(key_obj->template, blob, bloblen);
397a93
+        if (rc != CKR_OK) {
397a93
+            TRACE_ERROR("%s ecdsa_priv_unwrap_get_data failed with "
397a93
+                        "rc=0x%lx\n", __func__, rc);
397a93
+            return rc;
397a93
+        }
397a93
+
397a93
+        /* Extract the SPKI and add CKA_PUBLIC_KEY_INFO to key */
397a93
+        rc = publ_key_get_spki(key_obj->template, ktype, FALSE,
397a93
+                               &spki, &spki_length);
397a93
+        if (rc != CKR_OK) {
397a93
+            TRACE_DEVEL("publ_key_get_spki failed\n");
397a93
+            return rc;
397a93
+        }
397a93
+
397a93
+        allocated = TRUE;
397a93
+        break;
397a93
+
397a93
+    case CKO_PRIVATE_KEY:
397a93
+        RETRY_START(rc, tokdata)
397a93
+            rc = dll_m_GetAttributeValue(blob, bloblen, get_attr, 1,
397a93
+                                         target_info->target);
397a93
+        RETRY_END(rc, tokdata, session)
397a93
+
397a93
+        /* Only newer EP11 libs support this, ignore if error */
397a93
+        if (rc != CKR_OK)
397a93
+            return CKR_OK;
397a93
+
397a93
+        spki = get_attr[0].pValue;
397a93
+        spki_length = get_attr[0].ulValueLen;
397a93
+        break;
397a93
+
397a93
+    default:
397a93
+        /* do nothing */
397a93
+        return CKR_OK;
397a93
+    }
397a93
+
397a93
+    rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spki_length,
397a93
+                         &spki_attr);
397a93
+    if (rc != CKR_OK) {
397a93
+        TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n",
397a93
+                    __func__, rc);
397a93
+        goto out;
397a93
+    }
397a93
+
397a93
+    rc = template_update_attribute(key_obj->template, spki_attr);
397a93
+    if (rc != CKR_OK) {
397a93
+        TRACE_ERROR("%s template_update_attribute failed with rc=0x%lx\n",
397a93
+                    __func__, rc);
397a93
+        free(spki_attr);
397a93
+        goto out;
397a93
+    }
397a93
+
397a93
+out:
397a93
+    if (allocated && spki != NULL)
397a93
+        free(spki);
397a93
+
397a93
+    return rc;
397a93
+}
397a93
+
397a93
+CK_RV ep11tok_derive_key(STDLL_TokData_t *tokdata, SESSION *session,
397a93
                          CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE hBaseKey,
397a93
                          CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs,
397a93
                          CK_ULONG attrs_len)
397a93
@@ -5345,17 +5486,12 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
     CK_ULONG ecpoint_len, field_len, key_len = 0;
397a93
     CK_ATTRIBUTE *new_attrs1 = NULL, *new_attrs2 = NULL;
397a93
     CK_ULONG new_attrs1_len = 0, new_attrs2_len = 0;
397a93
-    CK_ULONG privlen, i;
397a93
+    CK_ULONG privlen;
397a93
     int curve_type;
397a93
     CK_BBOOL allocated = FALSE;
397a93
     ep11_target_info_t* target_info;
397a93
     CK_ULONG used_firmware_API_version;
397a93
     CK_MECHANISM_PTR mech_orig = mech;
397a93
-    CK_ATTRIBUTE *ec_params;
397a93
-    CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
397a93
-    CK_BYTE *spki = NULL;
397a93
-    CK_ULONG spki_length = 0;
397a93
-    CK_ATTRIBUTE *spki_attr = NULL;
397a93
     struct EP11_KYBER_MECH mech_ep11;
397a93
     OBJECT *kyber_secret_obj = NULL;
397a93
 
397a93
@@ -5476,18 +5612,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
         }
397a93
     }
397a93
 
397a93
-    if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
397a93
-        if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
397a93
-            mech->pParameter == NULL) {
397a93
-            TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
397a93
-                        __func__, ep11_get_ckm(tokdata, mech->mechanism),
397a93
-                        mech->ulParameterLen);
397a93
-            return CKR_MECHANISM_PARAM_INVALID;
397a93
-        }
397a93
-
397a93
-        btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
397a93
-    }
397a93
-
397a93
     rc = h_opaque_2_blob(tokdata, hBaseKey, &keyblob, &keyblobsize,
397a93
                          &base_key_obj, READ_LOCK);
397a93
     if (rc != CKR_OK) {
397a93
@@ -5605,46 +5729,24 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
         goto error;
397a93
     }
397a93
 
397a93
-    if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
397a93
-        /*
397a93
-         * CKM_IBM_BTC_DERIVE requires CKA_VALUE_LEN to specify the byte length
397a93
-         * of the to be derived EC key. CKA_VALUE_LEN is dependent on the
397a93
-         * curve used.
397a93
-         * CKA_VALUE_LEN can not be already in the user supplied template,
397a93
-         * since this is not allowed by the key template check routines.
397a93
-         */
397a93
-        rc = template_attribute_get_non_empty(key_obj->template, CKA_EC_PARAMS,
397a93
-                                              &ec_params);
397a93
-        if (rc != CKR_OK) {
397a93
-            TRACE_ERROR("CKA_EC_PARAMS is required in derive template\n");
397a93
+    switch (mech->mechanism) {
397a93
+    case CKM_IBM_BTC_DERIVE:
397a93
+        rc = ep11tok_btc_mech_pre_process(tokdata, key_obj, &new_attrs2,
397a93
+                                          &new_attrs2_len);
397a93
+        if (rc != CKR_OK)
397a93
             goto error;
397a93
-        }
397a93
-
397a93
-        for (i = 0; i < NUMEC; i++) {
397a93
-            if (der_ec_supported[i].data_size == ec_params->ulValueLen &&
397a93
-                memcmp(ec_params->pValue, der_ec_supported[i].data,
397a93
-                       ec_params->ulValueLen) == 0) {
397a93
-                privlen = (der_ec_supported[i].len_bits + 7) / 8;
397a93
-                rc = add_to_attribute_array(&new_attrs2, &new_attrs2_len,
397a93
-                                            CKA_VALUE_LEN,
397a93
-                                            (CK_BYTE_PTR)&privlen,
397a93
-                                            sizeof(privlen));
397a93
-                if (rc != CKR_OK) {
397a93
-                    TRACE_ERROR("Adding attribute failed type=CKA_VALUE_LEN "
397a93
-                                "rc=0x%lx\n", rc);
397a93
-                    goto error;
397a93
-                }
397a93
-                break;
397a93
-            }
397a93
-        }
397a93
-    }
397a93
+        break;
397a93
 
397a93
-    if (mech->mechanism == CKM_IBM_KYBER) {
397a93
+    case CKM_IBM_KYBER:
397a93
         rc = ep11tok_kyber_mech_pre_process(tokdata, mech, &mech_ep11,
397a93
                                             &kyber_secret_obj);
397a93
         if (rc != CKR_OK)
397a93
             goto error;
397a93
         mech = &mech_ep11.mech;
397a93
+        break;
397a93
+
397a93
+    default:
397a93
+        break;
397a93
     }
397a93
 
397a93
     trace_attributes(__func__, "Derive:", new_attrs2, new_attrs2_len);
397a93
@@ -5695,47 +5797,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
     }
397a93
     opaque_attr = NULL;
397a93
 
397a93
-    if (mech->mechanism == CKM_IBM_BTC_DERIVE &&
397a93
-        btc_params != NULL && btc_params->pChainCode != NULL &&
397a93
-        cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
397a93
-        memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
397a93
-        btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
397a93
-    }
397a93
-
397a93
-    if (mech->mechanism == CKM_IBM_BTC_DERIVE && class == CKO_PUBLIC_KEY) {
397a93
-        /* Derived blob is an SPKI, extract public EC key attributes */
397a93
-        rc = ecdsa_priv_unwrap_get_data(key_obj->template,
397a93
-                                        newblob, newblobsize);
397a93
-        if (rc != CKR_OK) {
397a93
-            TRACE_ERROR("%s ecdsa_priv_unwrap_get_data failed with rc=0x%lx\n",
397a93
-                        __func__, rc);
397a93
-            goto error;
397a93
-        }
397a93
-
397a93
-        /* Extract the SPKI and add CKA_PUBLIC_KEY_INFO to key */
397a93
-        rc = publ_key_get_spki(key_obj->template, ktype, FALSE,
397a93
-                               &spki, &spki_length);
397a93
-        if (rc != CKR_OK) {
397a93
-            TRACE_DEVEL("publ_key_get_spki failed\n");
397a93
-            goto error;
397a93
-        }
397a93
-
397a93
-        rc = build_attribute(CKA_PUBLIC_KEY_INFO, spki, spki_length, &spki_attr);
397a93
-        if (rc != CKR_OK) {
397a93
-            TRACE_ERROR("%s build_attribute failed with rc=0x%lx\n",
397a93
-                        __func__, rc);
397a93
-            goto error;
397a93
-        }
397a93
-
397a93
-        rc = template_update_attribute(key_obj->template, spki_attr);
397a93
-        if (rc != CKR_OK) {
397a93
-            TRACE_ERROR("%s template_update_attribute failed with "
397a93
-                        "rc=0x%lx\n", __func__, rc);
397a93
-            goto error;
397a93
-        }
397a93
-        spki_attr = NULL;
397a93
-    }
397a93
-
397a93
     if (class == CKO_SECRET_KEY || class == CKO_PRIVATE_KEY) {
397a93
         rc = update_ep11_attrs_from_blob(tokdata, session, key_obj->template);
397a93
         if (rc != CKR_OK) {
397a93
@@ -5745,10 +5806,23 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
397a93
         }
397a93
     }
397a93
 
397a93
-    if (mech->mechanism == CKM_IBM_KYBER) {
397a93
+    switch (mech->mechanism) {
397a93
+    case CKM_IBM_BTC_DERIVE:
397a93
+        rc = ep11tok_btc_mech_post_process(tokdata, session, mech, class, ktype,
397a93
+                                           key_obj, newblob, newblobsize,
397a93
+                                           csum, cslen);
397a93
+        if (rc != CKR_OK)
397a93
+            goto error;
397a93
+        break;
397a93
+
397a93
+    case CKM_IBM_KYBER:
397a93
         rc = ep11tok_kyber_mech_post_process(tokdata, mech_orig, csum, cslen);
397a93
         if (rc != CKR_OK)
397a93
             goto error;
397a93
+        break;
397a93
+
397a93
+    default:
397a93
+        break;
397a93
     }
397a93
 
397a93
     if (class == CKO_SECRET_KEY && cslen >= EP11_CSUMSIZE) {
397a93
@@ -5792,10 +5866,6 @@ error:
397a93
         free(opaque_attr);
397a93
     if (chk_attr != NULL)
397a93
         free(chk_attr);
397a93
-    if (spki_attr != NULL)
397a93
-        free(spki_attr);
397a93
-    if (spki != NULL)
397a93
-        free(spki);
397a93
     if (new_attrs)
397a93
         free_attribute_array(new_attrs, new_attrs_len);
397a93
     if (new_attrs1)
397a93
-- 
397a93
2.16.2.windows.1
397a93