Blob Blame History Raw
commit bedf46da28da6231607a12e35414cd59b4432f9f
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date:   Fri Mar 1 11:03:47 2019 +0100

    EP11: Created MACed-SPKIs when importing public keys
    
    The EP11 host library does not allow to use plain SPKIs as
    public key blobs for encrypt operations, this requires
    MACed-SPKIs. Create MACed-SPKIs whenever public keys are
    imported, and store it in CKA_IBM_OPAQUE instead of the
    plain SPKI.
    
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

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