Blame SOURCES/opencryptoki-3.11.0-bedf46da28da6231607a12e35414cd59b4432f9f.patch

ca735d
commit bedf46da28da6231607a12e35414cd59b4432f9f
ca735d
Author: Ingo Franzki <ifranzki@linux.ibm.com>
ca735d
Date:   Fri Mar 1 11:03:47 2019 +0100
ca735d
ca735d
    EP11: Created MACed-SPKIs when importing public keys
ca735d
    
ca735d
    The EP11 host library does not allow to use plain SPKIs as
ca735d
    public key blobs for encrypt operations, this requires
ca735d
    MACed-SPKIs. Create MACed-SPKIs whenever public keys are
ca735d
    imported, and store it in CKA_IBM_OPAQUE instead of the
ca735d
    plain SPKI.
ca735d
    
ca735d
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
ca735d
ca735d
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
ca735d
index 41d500a4..5416a413 100644
ca735d
--- a/usr/lib/ep11_stdll/ep11_specific.c
ca735d
+++ b/usr/lib/ep11_stdll/ep11_specific.c
ca735d
@@ -2043,6 +2043,120 @@ CK_RV ep11tok_final(STDLL_TokData_t * tokdata)
ca735d
     return CKR_OK;
ca735d
 }
ca735d
 
ca735d
+/*
ca735d
+ * Makes a public key blob which is a MACed SPKI of the public key.
ca735d
+ */
ca735d
+static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess,
ca735d
+                             OBJECT *pub_key_obj,
ca735d
+                             CK_BYTE *spki, CK_ULONG spki_len,
ca735d
+                             CK_BYTE *maced_spki, CK_ULONG *maced_spki_len)
ca735d
+{
ca735d
+    ep11_private_data_t *ep11_data = tokdata->private_data;
ca735d
+    unsigned char *ep11_pin_blob = NULL;
ca735d
+    CK_ULONG ep11_pin_blob_len = 0;
ca735d
+    ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
ca735d
+    CK_MECHANISM mech = { CKM_IBM_TRANSPORTKEY, 0, 0 };
ca735d
+    CK_ATTRIBUTE_PTR p_attrs = NULL;
ca735d
+    CK_ULONG attrs_len = 0;
ca735d
+    CK_ATTRIBUTE_PTR attr;
ca735d
+    CK_BBOOL bool_value;
ca735d
+    DL_NODE *node;
ca735d
+    CK_BYTE csum[MAX_BLOBSIZE];
ca735d
+    CK_ULONG cslen = sizeof(csum);
ca735d
+    CK_KEY_TYPE keytype;
ca735d
+    CK_RV rc;
ca735d
+
ca735d
+    rc = template_attribute_find(pub_key_obj->template, CKA_KEY_TYPE, &attr);
ca735d
+    if (rc == FALSE) {
ca735d
+        TRACE_ERROR("Could not find CKA_KEY_TYPE for the key.\n");
ca735d
+        return CKR_TEMPLATE_INCOMPLETE;
ca735d
+    }
ca735d
+    keytype = *(CK_KEY_TYPE *)attr->pValue;
ca735d
+
ca735d
+    /*
ca735d
+     * m_UnwrapKey with CKM_IBM_TRANSPORTKEY allows boolean attributes only to
ca735d
+     * be added to MACed-SPKIs
ca735d
+     */
ca735d
+    node = pub_key_obj->template->attribute_list;
ca735d
+    while (node != NULL) {
ca735d
+        attr = node->data;
ca735d
+
ca735d
+        switch (attr->type) {
ca735d
+        case CKA_ENCRYPT:
ca735d
+        case CKA_VERIFY:
ca735d
+        case CKA_VERIFY_RECOVER:
ca735d
+            /*
ca735d
+             * EP11 does not allow to restrict public RSA/DSA/EC keys with
ca735d
+             * CKA_VERIFY=FALSE and/or CKA_ENCRYPT=FALSE since it can not
ca735d
+             * technically enforce the restrictions. Therefore override these
ca735d
+             * attributes for the EP11 library, but keep the original attribute
ca735d
+             * values in the object.
ca735d
+             */
ca735d
+            if (keytype == CKK_EC || keytype == CKK_RSA || keytype == CKK_DSA)
ca735d
+                bool_value = CK_TRUE;
ca735d
+            else
ca735d
+                bool_value = *(CK_BBOOL *)attr->pValue;
ca735d
+            rc = add_to_attribute_array(&p_attrs, &attrs_len, attr->type,
ca735d
+                                        &bool_value, sizeof(bool_value));
ca735d
+            if (rc != CKR_OK) {
ca735d
+                TRACE_ERROR("%s adding attribute failed type=0x%lx rc=0x%lx\n",
ca735d
+                            __func__, attr->type, rc);
ca735d
+                goto make_maced_spki_end;
ca735d
+            }
ca735d
+            break;
ca735d
+
ca735d
+        case CKA_EXTRACTABLE:
ca735d
+        //case CKA_NEVER_EXTRACTABLE:
ca735d
+        //case CKA_MODIFIABLE:
ca735d
+        case CKA_DERIVE:
ca735d
+        case CKA_WRAP:
ca735d
+        //case CKA_LOCAL:
ca735d
+        case CKA_TRUSTED:
ca735d
+        case CKA_IBM_RESTRICTABLE:
ca735d
+        case CKA_IBM_NEVER_MODIFIABLE:
ca735d
+        case CKA_IBM_ATTRBOUND:
ca735d
+        case CKA_IBM_USE_AS_DATA:
ca735d
+            rc = add_to_attribute_array(&p_attrs, &attrs_len, attr->type,
ca735d
+                                        attr->pValue, attr->ulValueLen);
ca735d
+            if (rc != CKR_OK) {
ca735d
+                TRACE_ERROR("%s adding attribute failed type=0x%lx rc=0x%lx\n",
ca735d
+                            __func__, attr->type, rc);
ca735d
+                goto make_maced_spki_end;
ca735d
+            }
ca735d
+            break;
ca735d
+
ca735d
+        default:
ca735d
+            break;
ca735d
+        }
ca735d
+        node = node->next;
ca735d
+    }
ca735d
+
ca735d
+    ep11_get_pin_blob(ep11_session, object_is_session_object(pub_key_obj),
ca735d
+                      &ep11_pin_blob, &ep11_pin_blob_len);
ca735d
+
ca735d
+    RETRY_START
ca735d
+        rc = dll_m_UnwrapKey(spki, spki_len, NULL, 0, NULL, 0,
ca735d
+                             ep11_pin_blob, ep11_pin_blob_len, &mech,
ca735d
+                             p_attrs, attrs_len, maced_spki, maced_spki_len,
ca735d
+                             csum, &cslen,
ca735d
+                             (uint64_t) ep11_data->target_list);
ca735d
+    RETRY_END(rc, tokdata, sess)
ca735d
+
ca735d
+    if (rc != CKR_OK) {
ca735d
+        rc = ep11_error_to_pkcs11_error(rc, sess);
ca735d
+        TRACE_ERROR("%s unwrapping SPKI rc=0x%lx spki_len=0x%zx maced_spki_len=0x%zx\n",
ca735d
+                    __func__, rc, spki_len, *maced_spki_len);
ca735d
+    } else {
ca735d
+        TRACE_INFO("%s unwrapping SPKI rc=0x%lx spki_len=0x%zx maced_spki_len=0x%zx\n",
ca735d
+                   __func__, rc, spki_len, *maced_spki_len);
ca735d
+    }
ca735d
+
ca735d
+make_maced_spki_end:
ca735d
+    if (p_attrs != NULL)
ca735d
+            cleanse_and_free_attribute_array(p_attrs, attrs_len);
ca735d
+
ca735d
+    return rc;
ca735d
+}
ca735d
 
ca735d
 /*
ca735d
  * makes blobs for private imported RSA keys and
ca735d
@@ -2140,10 +2254,15 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
ca735d
         }
ca735d
 
ca735d
         /* save the SPKI as blob although it is not a blob.
ca735d
-         * The card expects SPKIs as public keys.
ca735d
+         * The card expects MACed-SPKIs as public keys.
ca735d
          */
ca735d
-        memcpy(blob, data, data_len);
ca735d
-        *blob_size = data_len;
ca735d
+        rc = make_maced_spki(tokdata, sess, rsa_key_obj, data, data_len,
ca735d
+                             blob, blob_size);
ca735d
+        if (rc != CKR_OK) {
ca735d
+            TRACE_ERROR("%s failed to make a MACed-SPKI rc=0x%lx\n",
ca735d
+                        __func__, rc);
ca735d
+            goto import_RSA_key_end;
ca735d
+        }
ca735d
 
ca735d
     } else {
ca735d
 
ca735d
@@ -2331,10 +2450,15 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
ca735d
         }
ca735d
 
ca735d
         /* save the SPKI as blob although it is not a blob.
ca735d
-         * The card expects SPKIs as public keys.
ca735d
+         * The card expects MACed-SPKIs as public keys.
ca735d
          */
ca735d
-        memcpy(blob, data, data_len);
ca735d
-        *blob_size = data_len;
ca735d
+        rc = make_maced_spki(tokdata, sess, ec_key_obj, data, data_len,
ca735d
+                             blob, blob_size);
ca735d
+        if (rc != CKR_OK) {
ca735d
+            TRACE_ERROR("%s failed to make a MACed-SPKI rc=0x%lx\n",
ca735d
+                        __func__, rc);
ca735d
+            goto import_EC_key_end;
ca735d
+        }
ca735d
 
ca735d
     } else {
ca735d
 
ca735d
@@ -2531,10 +2655,15 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
ca735d
         }
ca735d
 
ca735d
         /* save the SPKI as blob although it is not a blob.
ca735d
-         * The card expects SPKIs as public keys.
ca735d
+         * The card expects MACed-SPKIs as public keys.
ca735d
          */
ca735d
-        memcpy(blob, data, data_len);
ca735d
-        *blob_size = data_len;
ca735d
+        rc = make_maced_spki(tokdata, sess, dsa_key_obj, data, data_len,
ca735d
+                             blob, blob_size);
ca735d
+        if (rc != CKR_OK) {
ca735d
+            TRACE_ERROR("%s failed to make a MACed-SPKI rc=0x%lx\n",
ca735d
+                        __func__, rc);
ca735d
+            goto import_DSA_key_end;
ca735d
+        }
ca735d
 
ca735d
     } else {
ca735d
 
ca735d
@@ -2723,10 +2852,15 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
ca735d
         }
ca735d
 
ca735d
         /* save the SPKI as blob although it is not a blob.
ca735d
-         * The card expects SPKIs as public keys.
ca735d
+         * The card expects MACed-SPKIs as public keys.
ca735d
          */
ca735d
-        memcpy(blob, data, data_len);
ca735d
-        *blob_size = data_len;
ca735d
+        rc = make_maced_spki(tokdata, sess, dh_key_obj, data, data_len,
ca735d
+                             blob, blob_size);
ca735d
+        if (rc != CKR_OK) {
ca735d
+            TRACE_ERROR("%s failed to make a MACed-SPKI rc=0x%lx\n",
ca735d
+                        __func__, rc);
ca735d
+            goto import_DH_key_end;
ca735d
+        }
ca735d
 
ca735d
     } else {
ca735d