Blob Blame History Raw
From c6d6be8b7c1c1fa346af420daada56e28da5af6d Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 4 Nov 2022 09:44:35 +0100
Subject: [PATCH 06/34] EP11: Pass back chain code for CKM_IBM_BTC_DERIVE

When deriving a key using CKM_IBM_BTC_DERIVE, the resulting chain code
must be passed back in the buffer supplied by the caller in the
mechanism parameter (field pChainCode in CK_IBM_BTC_DERIVE_PARAMS).
This chain code can then be used to derive further keys from the just
derived key.

Note that field ulChainCodeLen must be zero for any BTC master key
derivation, but pChainCode must still point to a buffer of 32 bytes
(CK_IBM_BTC_CHAINCODE_LENGTH) to receive the resulting chain code.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
 usr/lib/ep11_stdll/ep11_specific.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 432790f1..a56b5b82 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -4988,6 +4988,7 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
     CK_ULONG used_firmware_API_version;
     CK_MECHANISM_PTR mech_orig = mech;
     CK_ATTRIBUTE *ec_params;
+    CK_IBM_BTC_DERIVE_PARAMS *btc_params = NULL;
 
     memset(newblob, 0, sizeof(newblob));
 
@@ -5106,6 +5107,18 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
         }
     }
 
+    if (mech->mechanism == CKM_IBM_BTC_DERIVE) {
+        if (mech->ulParameterLen != sizeof(CK_IBM_BTC_DERIVE_PARAMS) ||
+            mech->pParameter == NULL) {
+            TRACE_ERROR("%s Param NULL or len for %s wrong: %lu\n",
+                        __func__, ep11_get_ckm(tokdata, mech->mechanism),
+                        mech->ulParameterLen);
+            return CKR_MECHANISM_PARAM_INVALID;
+        }
+
+        btc_params = (CK_IBM_BTC_DERIVE_PARAMS *)mech->pParameter;
+    }
+
     rc = h_opaque_2_blob(tokdata, hBaseKey, &keyblob, &keyblobsize,
                          &base_key_obj, READ_LOCK);
     if (rc != CKR_OK) {
@@ -5300,6 +5313,13 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
     }
     opaque_attr = NULL;
 
+    if (mech->mechanism == CKM_IBM_BTC_DERIVE &&
+        btc_params != NULL && btc_params->pChainCode != NULL &&
+        cslen >= CK_IBM_BTC_CHAINCODE_LENGTH) {
+        memcpy(btc_params->pChainCode, csum, CK_IBM_BTC_CHAINCODE_LENGTH);
+        btc_params->ulChainCodeLen = CK_IBM_BTC_CHAINCODE_LENGTH;
+    }
+
     if (mech->mechanism == CKM_IBM_BTC_DERIVE && class == CKO_PUBLIC_KEY) {
         /* Derived blob is an SPKI, extract public EC key attributes */
         rc = ecdsa_priv_unwrap_get_data(key_obj->template,
-- 
2.16.2.windows.1