From 86274e85231b750ab75683822adafe512d0592a5 Mon Sep 17 00:00:00 2001 From: Than Ngo Date: Mon, 23 Aug 2021 13:00:44 +0200 Subject: [PATCH] Resolves: #1989138, Support for OpenSSL 3.0 --- ...6c4d7e221d29f0d385bd48ae4d6023a6e874.patch | 24 + ...3055b22d590bd3c197908b0ff63f6fd3c520.patch | 123 + ...696d478a1694ef314659a3d374f03f75c1b1.patch | 30 + ...6d49359a5eb91ad7f1483c64650c7874a513.patch | 38 + ...8fc3ae0f25b256dda2033d538f88c9b4f903.patch | 322 ++ ...f06823696c74eea90a77e16b28da1f79cd47.patch | 3420 +++++++++++++++++ ...dea6897d1bc0af13490f1c89248c52e7a73b.patch | 147 + ...d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch | 174 + ...ead028ec8e0c244b01d38c9096c96d98f96b.patch | 84 + ...2bcd98672c5d0ff8a2c926f3103110e91ed7.patch | 226 ++ ...37f08391415cdf8d8610c501516c3d3ed29c.patch | 193 + ...c12214688b287b9591133445e593da633caa.patch | 1085 ++++++ ...77e8557887d196ce77a129d457e817f8cc59.patch | 870 +++++ ...8f53d918fe6c7452da076b95081fb6aa9aef.patch | 1847 +++++++++ ...ceae6194e8213e9d3ffb7447ccd04d469b9d.patch | 115 + ...3eb904238d20cb34a4c7661ffac04901283c.patch | 37 + ...fe2ef89dad185397df46227f9392a6317d35.patch | 49 + ...1404e84ae35931cd6c7398c825378ee052b6.patch | 853 ++++ opencryptoki.spec | 28 +- 19 files changed, 9659 insertions(+), 6 deletions(-) create mode 100644 opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch create mode 100644 opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch create mode 100644 opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch create mode 100644 opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch create mode 100644 opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch create mode 100644 opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch create mode 100644 opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch create mode 100644 opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch create mode 100644 opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch create mode 100644 opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch create mode 100644 opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch create mode 100644 opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch create mode 100644 opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch create mode 100644 opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch create mode 100644 opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch create mode 100644 opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch create mode 100644 opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch create mode 100644 opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch diff --git a/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch b/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch new file mode 100644 index 0000000..3448bff --- /dev/null +++ b/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch @@ -0,0 +1,24 @@ +commit 11196c4d7e221d29f0d385bd48ae4d6023a6e874 +Author: Ingo Franzki +Date: Wed Jun 30 10:56:17 2021 +0200 + + CONFIGURE: fix configure.ac for --with-openssl + + The openSSL include files are in /include while + the libraries are in directly. + + Signed-off-by: Ingo Franzki + +diff --git a/configure.ac b/configure.ac +index e2cc537a..d3374476 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -272,7 +272,7 @@ OPENSSL_CFLAGS= + OPENSSL_LIBS= + if test "x$with_openssl" != "xno"; then + if test "x$with_openssl" != "xyes" -a "x$with_openssl" != "xcheck"; then +- OPENSSL_CFLAGS="-I$with_openssl" ++ OPENSSL_CFLAGS="-I$with_openssl/include" + OPENSSL_LIBS="-L$with_openssl" + fi + old_cflags="$CFLAGS" diff --git a/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch b/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch new file mode 100644 index 0000000..996eb6a --- /dev/null +++ b/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch @@ -0,0 +1,123 @@ +commit 11a53055b22d590bd3c197908b0ff63f6fd3c520 +Author: Ingo Franzki +Date: Tue Jun 29 17:35:18 2021 +0200 + + COMMON: mech_ec: Remove deprecated OpenSSL functions + + All low level EC_KEY functions are deprecated in OpenSSL 3.0. + Update the code to not use any of those. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/ec_defs.h b/usr/lib/common/ec_defs.h +index 1f48794b..897cf891 100644 +--- a/usr/lib/common/ec_defs.h ++++ b/usr/lib/common/ec_defs.h +@@ -14,13 +14,6 @@ + #include + #include "ec_curves.h" + +-/* OpenSSL compat */ +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +-# define EC_POINT_get_affine_coordinates EC_POINT_get_affine_coordinates_GFp +-# define EC_POINT_set_compressed_coordinates \ +- EC_POINT_set_compressed_coordinates_GFp +-#endif +- + // Elliptic Curve type + // + #define PRIME_CURVE 0x00 +diff --git a/usr/lib/common/mech_ec.c b/usr/lib/common/mech_ec.c +index b54e2db9..a0a06302 100644 +--- a/usr/lib/common/mech_ec.c ++++ b/usr/lib/common/mech_ec.c +@@ -32,34 +32,6 @@ + #include "openssl/obj_mac.h" + #include + +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-/* +- * Older OpenSLL versions do not have BN_bn2binpad, so implement it here +- */ +-static int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) +-{ +- int len, pad; +- unsigned char *buf; +- +- len = BN_num_bytes(a); +- buf = (unsigned char *)malloc(len); +- if (buf == NULL) +- return -1; +- BN_bn2bin(a, buf); +- +- if (len >= tolen) { +- memcpy(to, buf, tolen); +- } else { +- pad = tolen - len; +- memset(to, 0, pad); +- memcpy(to + pad, buf, len); +- } +- +- free(buf); +- return tolen; +-} +-#endif +- + #ifndef NID_brainpoolP160r1 + /* + * Older OpenSLL versions may not have the brainpool NIDs defined, define them +@@ -1522,9 +1494,8 @@ CK_RV ec_point_from_priv_key(CK_BYTE *parms, CK_ULONG parms_len, + CK_BYTE *d, CK_ULONG d_len, + CK_BYTE **point, CK_ULONG *point_len) + { +- EC_KEY *eckey = NULL; + EC_POINT *pub_key = NULL; +- const EC_GROUP *group = NULL; ++ EC_GROUP *group = NULL; + int nid, p_len; + BIGNUM *bn_d = NULL, *bn_x = NULL, *bn_y = NULL; + CK_RV rc = CKR_OK; +@@ -1541,17 +1512,7 @@ CK_RV ec_point_from_priv_key(CK_BYTE *parms, CK_ULONG parms_len, + goto done; + } + +- eckey = EC_KEY_new_by_curve_name(nid); +- if (eckey == NULL) { +- rc = CKR_FUNCTION_FAILED; +- goto done; +- } +- if (EC_KEY_set_private_key(eckey, bn_d) != 1) { +- rc = CKR_FUNCTION_FAILED; +- goto done; +- } +- +- group = EC_KEY_get0_group(eckey); ++ group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) { + rc = CKR_FUNCTION_FAILED; + goto done; +@@ -1576,7 +1537,7 @@ CK_RV ec_point_from_priv_key(CK_BYTE *parms, CK_ULONG parms_len, + rc = CKR_HOST_MEMORY; + goto done; + } +- if (!EC_POINT_get_affine_coordinates_GFp(group, pub_key, bn_x, bn_y, NULL)) { ++ if (!EC_POINT_get_affine_coordinates(group, pub_key, bn_x, bn_y, NULL)) { + rc = CKR_FUNCTION_FAILED; + goto done; + } +@@ -1599,13 +1560,13 @@ CK_RV ec_point_from_priv_key(CK_BYTE *parms, CK_ULONG parms_len, + done: + if (pub_key) + EC_POINT_free(pub_key); +- if (eckey) +- EC_KEY_free(eckey); + BN_clear_free(bn_x); + BN_clear_free(bn_y); + BN_clear_free(bn_d); + if (ec_point != NULL) + free(ec_point); ++ if (group != NULL) ++ EC_GROUP_free(group); + + return rc; + } diff --git a/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch b/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch new file mode 100644 index 0000000..9f87102 --- /dev/null +++ b/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch @@ -0,0 +1,30 @@ +commit 145a696d478a1694ef314659a3d374f03f75c1b1 +Author: Ingo Franzki +Date: Mon Jul 5 13:49:09 2021 +0200 + + CONFIGURE: Remove AC_FUNC_MALLOC and AC_FUNC_REALLOC + + The AC_FUNC_MALLOC configure check might add the rpl_malloc() entry if it + does not like the default malloc implementation. The user would need to + provide the rpl_malloc implementation. This happens depending on compiler and + OS/distro being used. Same applies for AC_FUNC_REALLOC and rpl_realloc. + It happened for me when I configured it with address sanitizer (libubsan, + libasan) activated. + + Signed-off-by: Ingo Franzki + +diff --git a/configure.ac b/configure.ac +index d3374476..286b7408 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -39,10 +39,8 @@ dnl Checks for library functions. + AC_FUNC_ALLOCA + AC_FUNC_CHOWN + AC_FUNC_FORK +-AC_FUNC_MALLOC + AC_FUNC_MKTIME + AC_FUNC_MMAP +-AC_FUNC_REALLOC + AC_FUNC_STRERROR_R + AC_CHECK_FUNCS([atexit ftruncate gettimeofday localtime_r memchr memmove \ + memset mkdir munmap regcomp select socket strchr strcspn \ diff --git a/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch b/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch new file mode 100644 index 0000000..171c080 --- /dev/null +++ b/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch @@ -0,0 +1,38 @@ +commit 2c116d49359a5eb91ad7f1483c64650c7874a513 +Author: Ingo Franzki +Date: Wed Jun 30 14:08:03 2021 +0200 + + TESTCASES: Skip test if operation state is not savable + + The sess_opstate testcase now handles the return code of CKR_STATE_UNSAVEABLE + from C_GetOperationState() and skips the test if that return code is + encountered. + + Signed-off-by: Ingo Franzki + +diff --git a/testcases/pkcs11/sess_opstate.c b/testcases/pkcs11/sess_opstate.c +index 3235b450..3d1ab9d7 100644 +--- a/testcases/pkcs11/sess_opstate.c ++++ b/testcases/pkcs11/sess_opstate.c +@@ -123,6 +123,10 @@ int sess_opstate_funcs(int loops) + opstatelen = 0; + rc = funcs->C_GetOperationState(s2, NULL, &opstatelen); + if (rc != CKR_OK) { ++ if (rc == CKR_STATE_UNSAVEABLE) { ++ testcase_skip("Get/SetOperationState digest test: state unsavable"); ++ goto out; ++ } + testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc)); + goto out; + } +@@ -135,6 +139,10 @@ int sess_opstate_funcs(int loops) + + rc = funcs->C_GetOperationState(s2, opstate, &opstatelen); + if (rc != CKR_OK) { ++ if (rc == CKR_STATE_UNSAVEABLE) { ++ testcase_skip("Get/SetOperationState digest test: state unsavable"); ++ goto out; ++ } + testcase_error("C_GetOperationState rc=%s", p11_get_ckr(rc)); + goto out; + } diff --git a/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch b/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch new file mode 100644 index 0000000..3070552 --- /dev/null +++ b/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch @@ -0,0 +1,322 @@ +commit 50408fc3ae0f25b256dda2033d538f88c9b4f903 +Author: Ingo Franzki +Date: Mon Jul 5 16:02:28 2021 +0200 + + COMMON: Fix memory leaks + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/mech_aes.c b/usr/lib/common/mech_aes.c +index 59f82482..a1241693 100644 +--- a/usr/lib/common/mech_aes.c ++++ b/usr/lib/common/mech_aes.c +@@ -2359,6 +2359,8 @@ CK_RV aes_mac_sign(STDLL_TokData_t *tokdata, + memcpy(out_data, ((AES_DATA_CONTEXT *) ctx->context)->iv, mac_len); + *out_data_len = mac_len; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + } +@@ -2497,6 +2499,8 @@ CK_RV aes_mac_sign_final(STDLL_TokData_t *tokdata, + memcpy(out_data, context->iv, mac_len); + *out_data_len = mac_len; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + +@@ -2554,8 +2558,12 @@ CK_RV aes_mac_verify(STDLL_TokData_t *tokdata, + } + + if (CRYPTO_memcmp(out_data, ((AES_DATA_CONTEXT *) ctx->context)->iv, +- out_data_len) == 0) ++ out_data_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +@@ -2685,8 +2693,12 @@ CK_RV aes_mac_verify_final(STDLL_TokData_t *tokdata, + } + } + +- if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) ++ if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +@@ -2766,6 +2778,8 @@ CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata, + memcpy(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, mac_len); + *out_data_len = mac_len; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + done: + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; +@@ -2913,6 +2927,8 @@ done: + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + +@@ -2969,9 +2985,12 @@ CK_RV aes_cmac_verify(STDLL_TokData_t *tokdata, + + if (CRYPTO_memcmp(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; + } + ++ verify_mgr_cleanup(tokdata, sess, ctx); ++ + return CKR_SIGNATURE_INVALID; + } + +@@ -3105,8 +3124,12 @@ CK_RV aes_cmac_verify_final(STDLL_TokData_t *tokdata, + return rc; + } + +- if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) ++ if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +diff --git a/usr/lib/common/mech_des3.c b/usr/lib/common/mech_des3.c +index 591ad3fa..3582102a 100644 +--- a/usr/lib/common/mech_des3.c ++++ b/usr/lib/common/mech_des3.c +@@ -2006,6 +2006,8 @@ CK_RV des3_mac_sign(STDLL_TokData_t *tokdata, + + *out_data_len = mac_len; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + } +@@ -2144,6 +2146,8 @@ CK_RV des3_mac_sign_final(STDLL_TokData_t *tokdata, + + *out_data_len = mac_len; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + +@@ -2197,8 +2201,12 @@ CK_RV des3_mac_verify(STDLL_TokData_t *tokdata, + key_obj = NULL; + + if (CRYPTO_memcmp(out_data, ((DES_DATA_CONTEXT *) ctx->context)->iv, +- out_data_len) == 0) ++ out_data_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +@@ -2328,8 +2336,12 @@ CK_RV des3_mac_verify_final(STDLL_TokData_t *tokdata, + } + } + +- if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) ++ if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +@@ -2410,6 +2422,8 @@ CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata, + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + +@@ -2553,6 +2567,8 @@ done: + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; + ++ sign_mgr_cleanup(tokdata, sess, ctx); ++ + return rc; + } + +@@ -2605,8 +2621,12 @@ CK_RV des3_cmac_verify(STDLL_TokData_t *tokdata, + + if (CRYPTO_memcmp(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; + } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); ++ + return CKR_SIGNATURE_INVALID; + } + +@@ -2739,8 +2759,12 @@ CK_RV des3_cmac_verify_final(STDLL_TokData_t *tokdata, + + ctx->context_free_func = des3_cmac_cleanup; + +- if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) ++ if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) { ++ verify_mgr_cleanup(tokdata, sess, ctx); + return CKR_OK; ++ } ++ ++ verify_mgr_cleanup(tokdata, sess, ctx); + + return CKR_SIGNATURE_INVALID; + } +diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c +index d01091f9..8bff6ada 100644 +--- a/usr/lib/common/new_host.c ++++ b/usr/lib/common/new_host.c +@@ -174,6 +174,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + if (rc != 0) { + sltp->FcnList = NULL; + detach_shm(sltp->TokData, 0); ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -186,6 +187,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + rc = load_token_data(sltp->TokData, SlotNumber); + if (rc != CKR_OK) { + sltp->FcnList = NULL; ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -218,6 +220,7 @@ done: + SC_Finalize(sltp->TokData, SlotNumber, sinfp, NULL, 0); + } else { + CloseXProcLock(sltp->TokData); ++ final_data_store(sltp->TokData); + free(sltp->TokData); + sltp->TokData = NULL; + } +diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c +index a0e7517c..45f13551 100644 +--- a/usr/lib/ep11_stdll/new_host.c ++++ b/usr/lib/ep11_stdll/new_host.c +@@ -164,6 +164,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + if (rc != 0) { + sltp->FcnList = NULL; + detach_shm(sltp->TokData, 0); ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -176,6 +177,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + rc = load_token_data(sltp->TokData, SlotNumber); + if (rc != CKR_OK) { + sltp->FcnList = NULL; ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -208,6 +210,7 @@ done: + SC_Finalize(sltp->TokData, SlotNumber, sinfp, NULL, 0); + } else { + CloseXProcLock(sltp->TokData); ++ final_data_store(sltp->TokData); + free(sltp->TokData); + sltp->TokData = NULL; + } +diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c +index 09e9d27a..eed632c3 100644 +--- a/usr/lib/icsf_stdll/new_host.c ++++ b/usr/lib/icsf_stdll/new_host.c +@@ -162,6 +162,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + if (rc != 0) { + sltp->FcnList = NULL; + detach_shm(sltp->TokData, 0); ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -174,6 +175,7 @@ CK_RV ST_Initialize(API_Slot_t *sltp, CK_SLOT_ID SlotNumber, + rc = load_token_data(sltp->TokData, SlotNumber); + if (rc != CKR_OK) { + sltp->FcnList = NULL; ++ final_data_store(sltp->TokData); + if (sltp->TokData) + free(sltp->TokData); + sltp->TokData = NULL; +@@ -206,6 +208,7 @@ done: + SC_Finalize(sltp->TokData, SlotNumber, sinfp, NULL, 0); + } else { + CloseXProcLock(sltp->TokData); ++ final_data_store(sltp->TokData); + free(sltp->TokData); + sltp->TokData = NULL; + } +diff --git a/usr/lib/tpm_stdll/tpm_specific.c b/usr/lib/tpm_stdll/tpm_specific.c +index 45bc4b78..c7557108 100644 +--- a/usr/lib/tpm_stdll/tpm_specific.c ++++ b/usr/lib/tpm_stdll/tpm_specific.c +@@ -213,6 +213,10 @@ CK_RV token_specific_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, + } + + tpm_data = (tpm_private_data_t *)calloc(1, sizeof(tpm_private_data_t)); ++ if (tpm_data == NULL) { ++ TRACE_ERROR("calloc failed\n"); ++ return CKR_HOST_MEMORY; ++ } + tokdata->private_data = tpm_data; + + tpm_data->tspContext = NULL_HCONTEXT; +@@ -221,12 +225,15 @@ CK_RV token_specific_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, + result = Tspi_Context_Create(&tpm_data->tspContext); + if (result) { + TRACE_ERROR("Tspi_Context_Create failed. rc=0x%x\n", result); ++ free(tpm_data); + return CKR_FUNCTION_FAILED; + } + + result = Tspi_Context_Connect(tpm_data->tspContext, NULL); + if (result) { + TRACE_ERROR("Tspi_Context_Connect failed. rc=0x%x\n", result); ++ Tspi_Context_Close(tpm_data->tspContext); ++ free(tpm_data); + return CKR_FUNCTION_FAILED; + } + +@@ -234,6 +241,8 @@ CK_RV token_specific_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, + &tpm_data->hDefaultPolicy); + if (result) { + TRACE_ERROR("Tspi_Context_GetDefaultPolicy failed. rc=0x%x\n", result); ++ Tspi_Context_Close(tpm_data->tspContext); ++ free(tpm_data); + return CKR_FUNCTION_FAILED; + } + diff --git a/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch b/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch new file mode 100644 index 0000000..08998cc --- /dev/null +++ b/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch @@ -0,0 +1,3420 @@ +commit 50e3f06823696c74eea90a77e16b28da1f79cd47 +Author: Ingo Franzki +Date: Wed Jun 30 14:33:33 2021 +0200 + + SOFT: Remove deprecated OpenSSL functions + + All low level RSA, EC_KEY, and DH functions are deprecated in OpenSSL 3.0. + Update the code to not use any of those. + + Change the digest operation context to store the OpenSSL digest context, + instead of the deprecated way of retrieving and restoring the digest state. + This makes the digest operation context 'non savable'. + + Also remove support for OpenSSL < v1.1.1. This code used even more + low level OpenSSL functions. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c +index 5ca22693..43fd17c3 100644 +--- a/usr/lib/soft_stdll/soft_specific.c ++++ b/usr/lib/soft_stdll/soft_specific.c +@@ -26,10 +26,6 @@ + + #include + +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +-#define NO_EC 1 +-#endif +- + #include "pkcs11types.h" + #include "defs.h" + #include "host_defs.h" +@@ -54,14 +50,10 @@ + #include + #include + #include +- +-/* +- * In order to make opencryptoki compatible with +- * OpenSSL 1.1 API Changes and backward compatible +- * we need to check for its version +- */ +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-#define OLDER_OPENSSL ++#include ++#if OPENSSL_VERSION_PREREQ(3, 0) ++#include ++#include + #endif + + #define MAX_GENERIC_KEY_SIZE 256 +@@ -76,7 +68,10 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = { + #if !(NODSA) + {CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}}, + #endif ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ /* OpenSSL 3.0 supports single-DES only with the legacy provider */ + {CKM_DES_KEY_GEN, {8, 8, CKF_GENERATE}}, ++#endif + {CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}}, + #if !(NOCDMF) + {CKM_CDMF_KEY_GEN, {0, 0, CKF_GENERATE}}, +@@ -120,10 +115,13 @@ static const MECH_LIST_ELEMENT soft_mech_list[] = { + {CKM_DH_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR}}, + #endif + /* End code contributed by Corrent corp. */ ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ /* OpenSSL 3.0 supports single-DES only with the legacy provider */ + {CKM_DES_ECB, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}}, + {CKM_DES_CBC, {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}}, + {CKM_DES_CBC_PAD, + {8, 8, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}}, ++#endif + #if !(NOCDMF) + {CKM_CDMF_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}}, + {CKM_CDMF_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}}, +@@ -286,58 +284,6 @@ CK_RV token_specific_des_ecb(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- DES_key_schedule des_key2; +- const_DES_cblock key_val_SSL, in_key_data; +- DES_cblock out_key_data; +- unsigned int i, j; +- CK_ATTRIBUTE *attr = NULL; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- // Create the key schedule +- memcpy(&key_val_SSL, attr->pValue, 8); +- DES_set_key_unchecked(&key_val_SSL, &des_key2); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // Both the encrypt and the decrypt are done 8 bytes at a time +- if (encrypt) { +- for (i = 0; i < in_data_len; i = i + 8) { +- memcpy(in_key_data, in_data + i, 8); +- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2, +- DES_ENCRYPT); +- memcpy(out_data + i, out_key_data, 8); +- } +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- +- for (j = 0; j < in_data_len; j = j + 8) { +- memcpy(in_key_data, in_data + j, 8); +- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2, +- DES_DECRYPT); +- memcpy(out_data + j, out_key_data, 8); +- } +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ecb(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -384,7 +330,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata, +@@ -394,47 +339,6 @@ CK_RV token_specific_des_cbc(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- CK_ATTRIBUTE *attr = NULL; +- DES_cblock ivec; +- DES_key_schedule des_key2; +- const_DES_cblock key_val_SSL; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- // Create the key schedule +- memcpy(&key_val_SSL, attr->pValue, 8); +- DES_set_key_unchecked(&key_val_SSL, &des_key2); +- +- memcpy(&ivec, init_v, 8); +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- +- if (encrypt) { +- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec, +- DES_ENCRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec, +- DES_DECRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_cbc(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -481,7 +385,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata, +@@ -491,80 +394,6 @@ CK_RV token_specific_tdes_ecb(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- CK_ATTRIBUTE *attr = NULL; +- CK_BYTE key_value[3 * DES_KEY_SIZE]; +- CK_KEY_TYPE keytype; +- unsigned int k, j; +- DES_key_schedule des_key1; +- DES_key_schedule des_key2; +- DES_key_schedule des_key3; +- const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data; +- DES_cblock out_key_data; +- +- UNUSED(tokdata); +- +- // get the key type +- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n"); +- return rc; +- } +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- if (keytype == CKK_DES2) { +- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE); +- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE); +- } else { +- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE); +- } +- +- // The key as passed is a 24 byte long string containing three des keys +- // pick them apart and create the 3 corresponding key schedules +- memcpy(&key_SSL1, key_value, 8); +- memcpy(&key_SSL2, key_value + 8, 8); +- memcpy(&key_SSL3, key_value + 16, 8); +- DES_set_key_unchecked(&key_SSL1, &des_key1); +- DES_set_key_unchecked(&key_SSL2, &des_key2); +- DES_set_key_unchecked(&key_SSL3, &des_key3); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // the encrypt and decrypt are done 8 bytes at a time +- if (encrypt) { +- for (k = 0; k < in_data_len; k = k + 8) { +- memcpy(in_key_data, in_data + k, 8); +- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data, +- (DES_cblock *) & out_key_data, +- &des_key1, &des_key2, &des_key3, DES_ENCRYPT); +- memcpy(out_data + k, out_key_data, 8); +- } +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- for (j = 0; j < in_data_len; j = j + 8) { +- memcpy(in_key_data, in_data + j, 8); +- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data, +- (DES_cblock *) & out_key_data, +- &des_key1, &des_key2, &des_key3, DES_DECRYPT); +- memcpy(out_data + j, out_key_data, 8); +- } +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ede3_ecb(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -624,7 +453,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata, +@@ -634,78 +462,6 @@ CK_RV token_specific_tdes_cbc(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_ATTRIBUTE *attr = NULL; +- CK_RV rc = CKR_OK; +- CK_BYTE key_value[3 * DES_KEY_SIZE]; +- CK_KEY_TYPE keytype; +- DES_key_schedule des_key1; +- DES_key_schedule des_key2; +- DES_key_schedule des_key3; +- const_DES_cblock key_SSL1, key_SSL2, key_SSL3; +- DES_cblock ivec; +- +- UNUSED(tokdata); +- +- // get the key type +- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n"); +- return rc; +- } +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- if (keytype == CKK_DES2) { +- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE); +- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE); +- } else { +- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE); +- } +- +- // The key as passed in is a 24 byte string containing 3 keys +- // pick it apart and create the key schedules +- memcpy(&key_SSL1, key_value, 8); +- memcpy(&key_SSL2, key_value + 8, 8); +- memcpy(&key_SSL3, key_value + 16, 8); +- DES_set_key_unchecked(&key_SSL1, &des_key1); +- DES_set_key_unchecked(&key_SSL2, &des_key2); +- DES_set_key_unchecked(&key_SSL3, &des_key3); +- +- memcpy(ivec, init_v, sizeof(ivec)); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // Encrypt or decrypt the data +- if (encrypt) { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_ENCRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_DECRYPT); +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -765,7 +521,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message, +@@ -795,14 +550,20 @@ CK_RV token_specific_tdes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message, + // convert from the local PKCS11 template representation to + // the underlying requirement + // returns the pointer to the local key representation +-static void *rsa_convert_public_key(OBJECT *key_obj) ++static EVP_PKEY *rsa_convert_public_key(OBJECT *key_obj) + { + CK_BBOOL rc; + CK_ATTRIBUTE *modulus = NULL; + CK_ATTRIBUTE *pub_exp = NULL; +- +- RSA *rsa; ++ EVP_PKEY *pkey = NULL; + BIGNUM *bn_mod, *bn_exp; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ EVP_PKEY_CTX *pctx = NULL; ++ OSSL_PARAM_BLD *tmpl = NULL; ++ OSSL_PARAM *params = NULL; ++#else ++ RSA *rsa; ++#endif + + rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS, + &modulus); +@@ -813,12 +574,7 @@ static void *rsa_convert_public_key(OBJECT *key_obj) + if (rc != CKR_OK) + return NULL; + +- // Create an RSA key struct to return +- rsa = RSA_new(); +- if (rsa == NULL) +- return NULL; +- +- // Create and init BIGNUM structs to stick in the RSA struct ++ // Create and init BIGNUM structs + bn_mod = BN_new(); + bn_exp = BN_new(); + +@@ -827,24 +583,74 @@ static void *rsa_convert_public_key(OBJECT *key_obj) + free(bn_mod); + if (bn_exp) + free(bn_exp); +- RSA_free(rsa); + return NULL; + } +- // Convert from strings to BIGNUMs and stick them in the RSA struct ++ // Convert from strings to BIGNUMs + BN_bin2bn((unsigned char *) modulus->pValue, modulus->ulValueLen, bn_mod); + BN_bin2bn((unsigned char *) pub_exp->pValue, pub_exp->ulValueLen, bn_exp); + +-#ifdef OLDER_OPENSSL +- rsa->n = bn_mod; +- rsa->e = bn_exp; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ // Create an RSA key struct to return ++ rsa = RSA_new(); ++ if (rsa == NULL) { ++ if (bn_mod) ++ free(bn_mod); ++ if (bn_exp) ++ free(bn_exp); ++ return NULL; ++ } ++ + RSA_set0_key(rsa, bn_mod, bn_exp, NULL); ++ ++ pkey = EVP_PKEY_new(); ++ if (pkey == NULL) { ++ RSA_free(rsa); ++ return NULL; ++ } ++ ++ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { ++ RSA_free(rsa); ++ EVP_PKEY_free(pkey); ++ return NULL; ++ } ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) ++ goto out; ++ ++ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_exp)) ++ goto out; ++ ++ params = OSSL_PARAM_BLD_to_param(tmpl); ++ if (params == NULL) ++ goto out; ++ ++ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); ++ if (pctx == NULL) ++ goto out; ++ ++ if (!EVP_PKEY_fromdata_init(pctx) || ++ !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params)) ++ goto out; ++ ++out: ++ if (pctx != NULL) ++ EVP_PKEY_CTX_free(pctx); ++ if (tmpl != NULL) ++ OSSL_PARAM_BLD_free(tmpl); ++ if (params != NULL) ++ OSSL_PARAM_free(params); ++ if (bn_mod != NULL) ++ BN_free(bn_mod); ++ if (bn_exp != NULL) ++ BN_free(bn_exp); + #endif + +- return (void *) rsa; ++ return pkey; + } + +-static void *rsa_convert_private_key(OBJECT *key_obj) ++static EVP_PKEY *rsa_convert_private_key(OBJECT *key_obj) + { + CK_ATTRIBUTE *modulus = NULL; + CK_ATTRIBUTE *pub_exp = NULL; +@@ -854,9 +660,15 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + CK_ATTRIBUTE *exp1 = NULL; + CK_ATTRIBUTE *exp2 = NULL; + CK_ATTRIBUTE *coeff = NULL; +- ++ EVP_PKEY *pkey = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ EVP_PKEY_CTX *pctx = NULL; ++ OSSL_PARAM_BLD *tmpl = NULL; ++ OSSL_PARAM *params = NULL; ++#else + RSA *rsa; + RSA_METHOD *meth; ++#endif + BIGNUM *bn_mod, *bn_pub_exp, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2, + *bn_cf; + +@@ -873,6 +685,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + if (!prime2 && !modulus) { + return NULL; + } ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) + // Create and init all the RSA and BIGNUM structs we need. + rsa = RSA_new(); + if (rsa == NULL) +@@ -884,17 +698,6 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + * Token doesn't implement RSA and, instead, calls OpenSSL for it. + * So to avoid it we set RSA methods to the default rsa methods. + */ +-#ifdef OLDER_OPENSSL +- if (rsa->engine) { +- meth = (RSA_METHOD *) rsa->meth; +- const RSA_METHOD *meth2 = RSA_PKCS1_SSLeay(); +- meth->rsa_pub_enc = meth2->rsa_pub_enc; +- meth->rsa_pub_dec = meth2->rsa_pub_dec; +- meth->rsa_priv_enc = meth2->rsa_priv_enc; +- meth->rsa_priv_dec = meth2->rsa_priv_dec; +- meth->rsa_mod_exp = meth2->rsa_mod_exp; +- meth->bn_mod_exp = meth2->bn_mod_exp; +-#else + /* + * XXX I dont see a better way than to ignore this warning for now. + * Note that the GCC pragma also works for clang. +@@ -912,8 +715,8 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + RSA_meth_set_mod_exp(meth, RSA_meth_get_mod_exp(meth2)); + RSA_meth_set_bn_mod_exp(meth, RSA_meth_get_bn_mod_exp(meth2)); + # pragma GCC diagnostic pop +-#endif + } ++#endif + + bn_mod = BN_new(); + bn_pub_exp = BN_new(); +@@ -926,33 +729,14 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + + if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) || + (bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) || +- (bn_pub_exp == NULL) || (bn_mod == NULL)) { +- if (rsa) +- RSA_free(rsa); +- if (bn_mod) +- BN_free(bn_mod); +- if (bn_pub_exp) +- BN_free(bn_pub_exp); +- if (bn_priv_exp) +- BN_free(bn_priv_exp); +- if (bn_p1) +- BN_free(bn_p1); +- if (bn_p2) +- BN_free(bn_p2); +- if (bn_e1) +- BN_free(bn_e1); +- if (bn_e2) +- BN_free(bn_e2); +- if (bn_cf) +- BN_free(bn_cf); +- return NULL; +- } ++ (bn_pub_exp == NULL) || (bn_mod == NULL)) ++ goto out; + + // CRT key? + if (prime1) { +- if (!prime2 || !exp1 || !exp2 || !coeff) { +- return NULL; +- } ++ if (!prime2 || !exp1 || !exp2 || !coeff) ++ goto out; ++ + // Even though this is CRT key, OpenSSL requires the + // modulus and exponents filled in or encrypt and decrypt will + // not work +@@ -969,20 +753,44 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + BN_bin2bn((unsigned char *) exp1->pValue, exp1->ulValueLen, bn_e1); + BN_bin2bn((unsigned char *) exp2->pValue, exp2->ulValueLen, bn_e2); + BN_bin2bn((unsigned char *) coeff->pValue, coeff->ulValueLen, bn_cf); +-#ifdef OLDER_OPENSSL +- rsa->n = bn_mod; +- rsa->d = bn_priv_exp; +- rsa->p = bn_p1; +- rsa->q = bn_p2; +- rsa->dmp1 = bn_e1; +- rsa->dmq1 = bn_e2; +- rsa->iqmp = bn_cf; +-#else ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp); ++ bn_mod = NULL; ++ bn_pub_exp = NULL; ++ bn_priv_exp = NULL; + RSA_set0_factors(rsa, bn_p1, bn_p2); ++ bn_p1 = NULL; ++ bn_p2 = NULL; + RSA_set0_crt_params(rsa, bn_e1, bn_e2, bn_cf); ++ bn_e1 = NULL; ++ bn_e2 = NULL; ++ bn_cf = NULL; ++ ++ pkey = EVP_PKEY_new(); ++ if (pkey == NULL) ++ goto out; ++ ++ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) ++ goto out; ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) ++ goto out; ++ ++ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR1, bn_p1) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR2, bn_p2) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT1, ++ bn_e1) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT2, ++ bn_e2) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, ++ bn_cf)) ++ goto out; + #endif +- return rsa; + } else { // must be a non-CRT key + if (!priv_exp) { + return NULL; +@@ -993,15 +801,90 @@ static void *rsa_convert_private_key(OBJECT *key_obj) + bn_pub_exp); + BN_bin2bn((unsigned char *) priv_exp->pValue, priv_exp->ulValueLen, + bn_priv_exp); +-#ifdef OLDER_OPENSSL +- rsa->n = bn_mod; +- rsa->d = bn_priv_exp; +-#else ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_set0_key(rsa, bn_mod, bn_pub_exp, bn_priv_exp); ++ bn_mod = NULL; ++ bn_pub_exp = NULL; ++ bn_priv_exp = NULL; ++ ++ pkey = EVP_PKEY_new(); ++ if (pkey == NULL) ++ goto out; ++ ++ if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) ++ goto out; ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) ++ goto out; ++ ++ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, bn_mod) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, bn_pub_exp) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, bn_priv_exp)) ++ goto out; + #endif + } + +- return (void *) rsa; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ params = OSSL_PARAM_BLD_to_param(tmpl); ++ if (params == NULL) ++ goto out; ++ ++ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); ++ if (pctx == NULL) ++ goto out; ++ ++ if (!EVP_PKEY_fromdata_init(pctx) || ++ !EVP_PKEY_fromdata(pctx, &pkey, EVP_PKEY_PUBLIC_KEY, params)) ++ goto out; ++ ++ EVP_PKEY_CTX_free(pctx); ++ OSSL_PARAM_BLD_free(tmpl); ++ OSSL_PARAM_free(params); ++ BN_free(bn_mod); ++ BN_free(bn_pub_exp); ++ BN_free(bn_priv_exp); ++ BN_free(bn_p1); ++ BN_free(bn_p2); ++ BN_free(bn_e1); ++ BN_free(bn_e2); ++ BN_free(bn_cf); ++#endif ++ ++ return pkey; ++out: ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ if (rsa) ++ RSA_free(rsa); ++#else ++ if (pctx != NULL) ++ EVP_PKEY_CTX_free(pctx); ++ if (tmpl != NULL) ++ OSSL_PARAM_BLD_free(tmpl); ++ if (params != NULL) ++ OSSL_PARAM_free(params); ++#endif ++ if (pkey) ++ EVP_PKEY_free(pkey); ++ if (bn_mod) ++ BN_free(bn_mod); ++ if (bn_pub_exp) ++ BN_free(bn_pub_exp); ++ if (bn_priv_exp) ++ BN_free(bn_priv_exp); ++ if (bn_p1) ++ BN_free(bn_p1); ++ if (bn_p2) ++ BN_free(bn_p2); ++ if (bn_e1) ++ BN_free(bn_e1); ++ if (bn_e2) ++ BN_free(bn_e2); ++ if (bn_cf) ++ BN_free(bn_cf); ++ ++ return NULL; + } + + static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) +@@ -1012,14 +895,16 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + CK_BBOOL flag; + CK_RV rc; + CK_ULONG BNLength; +- RSA *rsa = NULL; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ const RSA *rsa = NULL; + const BIGNUM *bignum = NULL; ++#else ++ BIGNUM *bignum = NULL; ++#endif + CK_BYTE *ssl_ptr = NULL; + BIGNUM *e = NULL; +-#ifndef OLDER_OPENSSL + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; +-#endif + + rc = template_attribute_get_ulong(publ_tmpl, CKA_MODULUS_BITS, &mod_bits); + if (rc != CKR_OK) { +@@ -1052,20 +937,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + } + BN_bin2bn(publ_exp->pValue, publ_exp->ulValueLen, e); + +-#ifdef OLDER_OPENSSL +- rsa = RSA_new(); +- if (rsa == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- return CKR_HOST_MEMORY; +- } +- +- if (!RSA_generate_key_ex(rsa, mod_bits, e, NULL)) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- goto done; +- } +- bignum = rsa->n; +-#else + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (ctx == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +@@ -1084,22 +955,36 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + rc = CKR_FUNCTION_FAILED; + goto done; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, e) != 1) { ++#else ++ if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) != 1) { ++#endif + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; + goto done; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ e = NULL; // will be freed as part of the context ++#endif + if (EVP_PKEY_keygen(ctx, &pkey) != 1) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; + goto done; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; + goto done; + } + RSA_get0_key(rsa, &bignum, NULL, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1122,12 +1007,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + } + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // Public Exponent +-#ifdef OLDER_OPENSSL +- bignum = rsa->e; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_key(rsa, NULL, &bignum, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1166,6 +1059,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + } + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // local = TRUE + // +@@ -1189,10 +1086,14 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + // to force the system to not return this for RSA keys.. + + // Add the modulus to the private key information +-#ifdef OLDER_OPENSSL +- bignum = rsa->n; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_key(rsa, &bignum, NULL, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1215,12 +1116,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + } + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // Private Exponent +-#ifdef OLDER_OPENSSL +- bignum = rsa->d; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_key(rsa, NULL, NULL, &bignum); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1245,13 +1154,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // prime #1: p +- // +-#ifdef OLDER_OPENSSL +- bignum = rsa->p; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_factors(rsa, &bignum, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1276,13 +1192,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // prime #2: q +- // +-#ifdef OLDER_OPENSSL +- bignum = rsa->q; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_factors(rsa, NULL, &bignum); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1307,13 +1230,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // exponent 1: d mod(p-1) +- // +-#ifdef OLDER_OPENSSL +- bignum = rsa->dmp1; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_crt_params(rsa, &bignum, NULL, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1338,13 +1268,20 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // exponent 2: d mod(q-1) +- // +-#ifdef OLDER_OPENSSL +- bignum = rsa->dmq1; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_crt_params(rsa, NULL, &bignum, NULL); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1369,13 +1306,21 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + // CRT coefficient: q_inverse mod(p) +- // +-#ifdef OLDER_OPENSSL +- bignum = rsa->iqmp; +-#else ++#if !OPENSSL_VERSION_PREREQ(3, 0) + RSA_get0_crt_params(rsa, NULL, NULL, &bignum); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, ++ &bignum)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } + #endif + BNLength = BN_num_bytes(bignum); + ssl_ptr = malloc(BNLength); +@@ -1400,6 +1345,10 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); + ssl_ptr = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(bignum); ++ bignum = NULL; ++#endif + + flag = TRUE; + rc = build_attribute(CKA_LOCAL, &flag, sizeof(CK_BBOOL), &attr); +@@ -1415,16 +1364,6 @@ static CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) + } + + done: +-#ifdef OLDER_OPENSSL +- if (e != NULL) +- BN_free(e); +- if (rsa != NULL) +- RSA_free(rsa); +- if (ssl_ptr != NULL) { +- OPENSSL_cleanse(ssl_ptr, BNLength); +- free(ssl_ptr); +- } +-#else + if (ssl_ptr != NULL) { + OPENSSL_cleanse(ssl_ptr, BNLength); + free(ssl_ptr); +@@ -1433,6 +1372,11 @@ done: + EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); ++ if (e != NULL) ++ BN_free(e); ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (bignum != NULL) ++ BN_free(bignum); + #endif + return rc; + } +@@ -1457,60 +1401,17 @@ static CK_RV os_specific_rsa_encrypt(CK_BYTE *in_data, + CK_ULONG in_data_len, + CK_BYTE *out_data, OBJECT *key_obj) + { +-#ifdef OLDER_OPENSSL +- CK_RV rc; +- RSA *rsa; +- int size; +- +- // Convert the local representation to an RSA representation +- rsa = (RSA *) rsa_convert_public_key(key_obj); +- if (rsa == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- return rc; +- } +- // Do an RSA public encryption +- size = +- RSA_public_encrypt(in_data_len, in_data, out_data, rsa, RSA_NO_PADDING); +- if (size == -1) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_ARGUMENTS_BAD; +- goto done; +- } +- +- rc = CKR_OK; +- +-done: +- RSA_free(rsa); +- +- return rc; +-#else + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; +- RSA *rsa = NULL; + CK_RV rc; + size_t outlen = in_data_len; + +- rsa = (RSA *)rsa_convert_public_key(key_obj); +- if (rsa == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- return rc; +- } +- +- pkey = EVP_PKEY_new(); ++ pkey = rsa_convert_public_key(key_obj); + if (pkey == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rc = CKR_HOST_MEMORY; +- goto done; +- } +- +- if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; +- goto done; ++ return rc; + } +- rsa = NULL; /* freed together with pkey */ + + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (ctx == NULL) { +@@ -1538,76 +1439,28 @@ done: + + rc = CKR_OK; + done: +- if (rsa != NULL) +- RSA_free(rsa); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + return rc; +-#endif + } + + static CK_RV os_specific_rsa_decrypt(CK_BYTE *in_data, + CK_ULONG in_data_len, + CK_BYTE *out_data, OBJECT *key_obj) + { +-#ifdef OLDER_OPENSSL +- CK_RV rc; +- RSA *rsa; +- int size; +- +- // Convert the local key representation to an RSA key representaion +- rsa = (RSA *) rsa_convert_private_key(key_obj); +- if (rsa == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- return rc; +- } +- // Do the private decryption +- size = +- RSA_private_decrypt(in_data_len, in_data, out_data, rsa, +- RSA_NO_PADDING); +- +- if (size == -1) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- goto done; +- } +- +- rc = CKR_OK; +- +-done: +- RSA_free(rsa); +- +- return rc; +-#else + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; +- RSA *rsa = NULL; + size_t outlen = in_data_len; + CK_RV rc; + +- rsa = (RSA *)rsa_convert_private_key(key_obj); +- if (rsa == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rc = CKR_FUNCTION_FAILED; +- return rc; +- } +- +- pkey = EVP_PKEY_new(); ++ pkey = rsa_convert_private_key(key_obj); + if (pkey == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rc = CKR_HOST_MEMORY; +- goto done; +- } +- +- if (EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; +- goto done; ++ return rc; + } +- rsa = NULL; /* freed together with pkey */ + + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (ctx == NULL) { +@@ -1635,14 +1488,11 @@ done: + + rc = CKR_OK; + done: +- if (rsa != NULL) +- RSA_free(rsa); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_rsa_encrypt(STDLL_TokData_t *tokdata, CK_BYTE *in_data, +@@ -2407,48 +2257,6 @@ CK_RV token_specific_aes_ecb(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- AES_KEY ssl_aes_key; +- unsigned int i; +- CK_ATTRIBUTE *attr = NULL; +- /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, +- * so this is fine */ +- CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE); +- CK_RV rc; +- +- UNUSED(tokdata); +- +- memset(&ssl_aes_key, 0, sizeof(AES_KEY)); +- +- // get key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- // AES_ecb_encrypt encrypts only a single block, so we have to break up the +- // input data here +- if (encrypt) { +- AES_set_encrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- for (i = 0; i < loops; i++) { +- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE), +- (unsigned char *) out_data + (i * AES_BLOCK_SIZE), +- &ssl_aes_key, AES_ENCRYPT); +- } +- } else { +- AES_set_decrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- for (i = 0; i < loops; i++) { +- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE), +- (unsigned char *) out_data + (i * AES_BLOCK_SIZE), +- &ssl_aes_key, AES_DECRYPT); +- } +- } +- *out_data_len = in_data_len; +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + unsigned char akey[32]; +@@ -2505,7 +2313,6 @@ done: + OPENSSL_cleanse(akey, sizeof(akey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata, +@@ -2515,38 +2322,6 @@ CK_RV token_specific_aes_cbc(STDLL_TokData_t *tokdata, + CK_ULONG *out_data_len, + OBJECT *key, CK_BYTE *init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- AES_KEY ssl_aes_key; +- CK_ATTRIBUTE *attr = NULL; +- CK_RV rc; +- +- UNUSED(tokdata); +- +- memset(&ssl_aes_key, 0, sizeof(AES_KEY)); +- +- // get key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike +- // AES_ecb_encrypt, so no looping required. +- if (encrypt) { +- AES_set_encrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data, +- in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT); +- } else { +- AES_set_decrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data, +- in_data_len, &ssl_aes_key, init_v, AES_DECRYPT); +- } +- *out_data_len = in_data_len; +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + unsigned char akey[32]; +@@ -2603,7 +2378,6 @@ done: + OPENSSL_cleanse(akey, sizeof(akey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_aes_mac(STDLL_TokData_t *tokdata, CK_BYTE *message, +@@ -2716,275 +2490,145 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata, + TEMPLATE *publ_tmpl, + TEMPLATE *priv_tmpl) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L + CK_RV rv; + CK_BBOOL rc; + CK_ATTRIBUTE *prime_attr = NULL; + CK_ATTRIBUTE *base_attr = NULL; + CK_ATTRIBUTE *temp_attr = NULL; + CK_ATTRIBUTE *value_bits_attr = NULL; +- CK_BYTE *temp_byte; ++ CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL; + CK_ULONG temp_bn_len; +- DH *dh; +- BIGNUM *bn_p; +- BIGNUM *bn_g; +- const BIGNUM *temp_bn; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ DH *dh = NULL; ++#else ++ EVP_PKEY_CTX *pctx = NULL; ++ OSSL_PARAM_BLD *tmpl = NULL; ++ OSSL_PARAM *osparams = NULL; ++#endif ++ BIGNUM *bn_p = NULL; ++ BIGNUM *bn_g = NULL; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ const BIGNUM *temp_bn = NULL; ++#else ++ BIGNUM *temp_bn = NULL; ++#endif ++ EVP_PKEY *params = NULL, *pkey = NULL; ++ EVP_PKEY_CTX *ctx = NULL; + + UNUSED(tokdata); + + rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr); + if (rv != CKR_OK) { + TRACE_ERROR("Could not find CKA_PRIME for the key.\n"); +- return rv; ++ goto done; + } + rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr); + if (rv != CKR_OK) { + TRACE_ERROR("Could not find CKA_BASE for the key.\n"); +- return rv; ++ goto done; + } + + if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) { + TRACE_ERROR("CKA_PRIME attribute value is invalid.\n"); +- return CKR_ATTRIBUTE_VALUE_INVALID; ++ rv = CKR_ATTRIBUTE_VALUE_INVALID; ++ goto done; + } + +- dh = DH_new(); +- if (dh == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- return CKR_FUNCTION_FAILED; +- } +- // Create and init BIGNUM structs to stick in the DH struct ++ // Create and init BIGNUM structs + bn_p = BN_new(); + bn_g = BN_new(); + if (bn_g == NULL || bn_p == NULL) { +- if (bn_g) +- BN_free(bn_g); +- if (bn_p) +- BN_free(bn_p); + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- return CKR_HOST_MEMORY; ++ rv = CKR_HOST_MEMORY; ++ goto done; + } +- // Convert from strings to BIGNUMs and stick them in the DH struct ++ // Convert from strings to BIGNUMs + BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen, + bn_p); + BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g); +- dh->p = bn_p; +- dh->g = bn_g; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ dh = DH_new(); ++ if (dh == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ ++ DH_set0_pqg(dh, bn_p, NULL, bn_g); ++ /* bn_p and bn_q freed together with dh */ ++ bn_p = NULL; ++ bn_g = NULL; ++ ++ params = EVP_PKEY_new(); ++ if (params == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); ++ rv = CKR_HOST_MEMORY; ++ goto done; ++ } + +- // Generate the DH Key +- if (!DH_generate_key(dh)) { ++ if (EVP_PKEY_assign_DH(params, dh) != 1) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- DH_free(dh); +- return CKR_FUNCTION_FAILED; ++ rv = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ dh = NULL; /* freed together with params */ ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) ++ goto done; ++ ++ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, bn_p) || ++ !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, bn_g)) ++ goto done; ++ ++ osparams = OSSL_PARAM_BLD_to_param(tmpl); ++ if (osparams == NULL) ++ goto done; ++ ++ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); ++ if (pctx == NULL) ++ goto done; ++ ++ if (!EVP_PKEY_fromdata_init(pctx) || ++ !EVP_PKEY_fromdata(pctx, ¶ms, EVP_PKEY_PUBLIC_KEY, osparams)) ++ goto done; ++#endif ++ ++ ctx = EVP_PKEY_CTX_new(params, NULL); ++ if (ctx == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); ++ rv = CKR_HOST_MEMORY; ++ goto done; ++ } ++ ++ if (EVP_PKEY_keygen_init(ctx) != 1 ++ || EVP_PKEY_keygen(ctx, &pkey) != 1 ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ /* dh is freed together with pkey */ ++ || (dh = (DH *)EVP_PKEY_get0_DH(pkey)) == NULL) { ++#else ++ ) { ++#endif ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto done; + } ++ + // Extract the public and private key components from the DH struct, + // and insert them in the publ_tmpl and priv_tmpl + + // + // pub_key + // +- //temp_bn = BN_new(); +- temp_bn = dh->pub_key; +- temp_bn_len = BN_num_bytes(temp_bn); +- temp_byte = malloc(temp_bn_len); +- temp_bn_len = BN_bn2bin(temp_bn, temp_byte); +- // in bytes +- rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr); +- if (rc != CKR_OK) { +- TRACE_DEVEL("build_attribute failed\n"); +- DH_free(dh); +- free(temp_byte); +- return CKR_FUNCTION_FAILED; +- } +- rc = template_update_attribute(publ_tmpl, temp_attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("template_update_attribute failed\n"); +- free(temp_attr); +- DH_free(dh); +- free(temp_byte); +- return rc; +- } +- free(temp_byte); +- +- // +- // priv_key +- // +- //temp_bn = BN_new(); +- temp_bn = dh->priv_key; +- temp_bn_len = BN_num_bytes(temp_bn); +- temp_byte = malloc(temp_bn_len); +- temp_bn_len = BN_bn2bin(temp_bn, temp_byte); +- // in bytes +- rc = build_attribute(CKA_VALUE, temp_byte, temp_bn_len, &temp_attr); +- if (rc != CKR_OK) { +- TRACE_DEVEL("build_attribute failed\n"); +- DH_free(dh); +- free(temp_byte); +- return CKR_FUNCTION_FAILED; +- } +- rc = template_update_attribute(priv_tmpl, temp_attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("template_update_attribute failed\n"); +- free(temp_attr); +- DH_free(dh); +- free(temp_byte); +- return rc; +- } +- free(temp_byte); +- +- // Update CKA_VALUE_BITS attribute in the private key +- value_bits_attr = +- (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG)); +- if (value_bits_attr == NULL) { +- TRACE_ERROR("malloc failed\n"); +- DH_free(dh); +- return CKR_HOST_MEMORY; +- } +- value_bits_attr->type = CKA_VALUE_BITS; +- value_bits_attr->ulValueLen = sizeof(CK_ULONG); +- value_bits_attr->pValue = +- (CK_BYTE *) value_bits_attr + sizeof(CK_ATTRIBUTE); +- *(CK_ULONG *) value_bits_attr->pValue = 8 * temp_bn_len; +- rc = template_update_attribute(priv_tmpl, value_bits_attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("template_update_attribute failed\n"); +- free(value_bits_attr); +- DH_free(dh); +- return rc; +- } +- +- // Add prime and base to the private key template +- rc = build_attribute(CKA_PRIME, +- (unsigned char *) prime_attr->pValue, +- prime_attr->ulValueLen, &temp_attr); // in bytes +- if (rc != CKR_OK) { +- TRACE_DEVEL("build_attribute failed\n"); +- DH_free(dh); +- return CKR_FUNCTION_FAILED; +- } +- rc = template_update_attribute(priv_tmpl, temp_attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("template_update_attribute failed\n"); +- free(temp_attr); +- DH_free(dh); +- return rc; +- } +- +- rc = build_attribute(CKA_BASE, +- (unsigned char *) base_attr->pValue, +- base_attr->ulValueLen, &temp_attr); // in bytes +- if (rc != CKR_OK) { +- TRACE_DEVEL("build_attribute failed\n"); +- DH_free(dh); +- return CKR_FUNCTION_FAILED; +- } +- rc = template_update_attribute(priv_tmpl, temp_attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("template_update_attribute failed\n"); +- free(temp_attr); +- DH_free(dh); +- return rc; +- } +- +- // Cleanup DH key +- DH_free(dh); +- +- return CKR_OK; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ DH_get0_key(dh, &temp_bn, NULL); + #else +- CK_RV rv; +- CK_BBOOL rc; +- CK_ATTRIBUTE *prime_attr = NULL; +- CK_ATTRIBUTE *base_attr = NULL; +- CK_ATTRIBUTE *temp_attr = NULL; +- CK_ATTRIBUTE *value_bits_attr = NULL; +- CK_BYTE *temp_byte = NULL, *temp_byte2 = NULL; +- CK_ULONG temp_bn_len; +- DH *dh = NULL; +- BIGNUM *bn_p = NULL; +- BIGNUM *bn_g = NULL; +- const BIGNUM *temp_bn = NULL; +- EVP_PKEY *params = NULL, *pkey = NULL; +- EVP_PKEY_CTX *ctx = NULL; +- +- UNUSED(tokdata); +- +- rv = template_attribute_get_non_empty(publ_tmpl, CKA_PRIME, &prime_attr); +- if (rv != CKR_OK) { +- TRACE_ERROR("Could not find CKA_PRIME for the key.\n"); +- goto done; +- } +- rv = template_attribute_get_non_empty(publ_tmpl, CKA_BASE, &base_attr); +- if (rv != CKR_OK) { +- TRACE_ERROR("Could not find CKA_BASE for the key.\n"); +- goto done; +- } +- +- if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) { +- TRACE_ERROR("CKA_PRIME attribute value is invalid.\n"); +- rv = CKR_ATTRIBUTE_VALUE_INVALID; +- goto done; +- } +- +- dh = DH_new(); +- if (dh == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rv = CKR_FUNCTION_FAILED; +- goto done; +- } +- // Create and init BIGNUM structs to stick in the DH struct +- bn_p = BN_new(); +- bn_g = BN_new(); +- if (bn_g == NULL || bn_p == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rv = CKR_HOST_MEMORY; +- goto done; +- } +- // Convert from strings to BIGNUMs and stick them in the DH struct +- BN_bin2bn((unsigned char *) prime_attr->pValue, prime_attr->ulValueLen, +- bn_p); +- BN_bin2bn((unsigned char *) base_attr->pValue, base_attr->ulValueLen, bn_g); +- DH_set0_pqg(dh, bn_p, NULL, bn_g); +- /* bn_p and bn_q freed together with dh */ +- bn_p = NULL; +- bn_g = NULL; +- +- params = EVP_PKEY_new(); +- if (params == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rv = CKR_HOST_MEMORY; +- goto done; +- } +- +- if (EVP_PKEY_assign_DH(params, dh) != 1) { +- TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rv = CKR_FUNCTION_FAILED; +- goto done; +- } +- dh = NULL; /* freed together with params */ +- +- ctx = EVP_PKEY_CTX_new(params, NULL); +- if (ctx == NULL) { +- TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rv = CKR_HOST_MEMORY; +- goto done; +- } +- +- if (EVP_PKEY_keygen_init(ctx) != 1 +- || EVP_PKEY_keygen(ctx, &pkey) != 1 +- /* dh is freed together with pkey */ +- || (dh = EVP_PKEY_get0_DH(pkey)) == NULL) { ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &temp_bn)) { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); +- rv = CKR_FUNCTION_FAILED; ++ rc = CKR_FUNCTION_FAILED; + goto done; + } +- +- // Extract the public and private key components from the DH struct, +- // and insert them in the publ_tmpl and priv_tmpl +- +- // +- // pub_key +- // +- DH_get0_key(dh, &temp_bn, NULL); ++#endif + + temp_bn_len = BN_num_bytes(temp_bn); + temp_byte = malloc(temp_bn_len); +@@ -3001,11 +2645,23 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata, + free(temp_attr); + goto done; + } ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(temp_bn); ++ temp_bn = NULL; ++#endif + + // + // priv_key + // ++#if !OPENSSL_VERSION_PREREQ(3, 0) + DH_get0_key(dh, NULL, &temp_bn); ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &temp_bn)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++#endif + temp_bn_len = BN_num_bytes(temp_bn); + temp_byte2 = malloc(temp_bn_len); + temp_bn_len = BN_bn2bin(temp_bn, temp_byte2); +@@ -3022,6 +2678,10 @@ CK_RV token_specific_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata, + free(temp_attr); + goto done; + } ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ BN_free(temp_bn); ++ temp_bn = NULL; ++#endif + + // Update CKA_VALUE_BITS attribute in the private key + value_bits_attr = +@@ -3086,8 +2746,17 @@ done: + EVP_PKEY_free(params); + free(temp_byte); + free(temp_byte2); +- return rv; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (pctx != NULL) ++ EVP_PKEY_CTX_free(pctx); ++ if (tmpl != NULL) ++ OSSL_PARAM_BLD_free(tmpl); ++ if (osparams != NULL) ++ OSSL_PARAM_free(osparams); ++ if (temp_bn != NULL) ++ BN_free(temp_bn); + #endif ++ return rv; + } /* end token_specific_dh_key_pair_gen() */ + #endif + /* End code contributed by Corrent corp. */ +@@ -3106,11 +2775,6 @@ CK_RV token_specific_get_mechanism_info(STDLL_TokData_t *tokdata, + return ock_generic_get_mechanism_info(tokdata, type, pInfo); + } + +-#ifdef OLDER_OPENSSL +-#define EVP_MD_meth_get_app_datasize(md) md->ctx_size +-#define EVP_MD_CTX_md_data(ctx) ctx->md_data +-#endif +- + static const EVP_MD *md_from_mech(CK_MECHANISM *mech) + { + const EVP_MD *md = NULL; +@@ -3168,16 +2832,13 @@ static const EVP_MD *md_from_mech(CK_MECHANISM *mech) + return md; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx) + { + const EVP_MD *md; + EVP_MD_CTX *md_ctx; + +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- md_ctx = EVP_MD_CTX_create(); +-#else + md_ctx = EVP_MD_CTX_new(); +-#endif + if (md_ctx == NULL) + return NULL; + +@@ -3185,11 +2846,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx) + if (md == NULL || + !EVP_DigestInit_ex(md_ctx, md, NULL)) { + TRACE_ERROR("md_from_mech or EVP_DigestInit_ex failed\n"); +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); +-#endif + return NULL; + } + +@@ -3198,11 +2855,7 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx) + ctx->context = malloc(ctx->context_len); + if (ctx->context == NULL) { + TRACE_ERROR("malloc failed\n"); +- #if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +- #else + EVP_MD_CTX_free(md_ctx); +- #endif + ctx->context_len = 0; + return NULL; + } +@@ -3221,27 +2874,60 @@ static EVP_MD_CTX *md_ctx_from_context(DIGEST_CONTEXT *ctx) + + return md_ctx; + } ++#endif ++ ++#if OPENSSL_VERSION_PREREQ(3, 0) ++static void token_specific_sha_free(STDLL_TokData_t *tokdata, SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len) ++{ ++ UNUSED(tokdata); ++ UNUSED(sess); ++ UNUSED(context_len); ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)context); ++} ++#endif + + CK_RV token_specific_sha_init(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + CK_MECHANISM *mech) + { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *md_ctx; ++#else ++ const EVP_MD *md; ++#endif + + UNUSED(tokdata); + + ctx->mech.ulParameterLen = mech->ulParameterLen; + ctx->mech.mechanism = mech->mechanism; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + md_ctx = md_ctx_from_context(ctx); + if (md_ctx == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); + return CKR_HOST_MEMORY; + } + +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); ++#else ++ ctx->context_len = 1; ++ ctx->context = (CK_BYTE *)EVP_MD_CTX_new(); ++ if (ctx->context == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); ++ return CKR_HOST_MEMORY; ++ } ++ ++ md = md_from_mech(&ctx->mech); ++ if (md == NULL || ++ !EVP_DigestInit_ex((EVP_MD_CTX *)ctx->context, md, NULL)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ ctx->state_unsaveable = CK_TRUE; ++ ctx->context_free_func = token_specific_sha_free; + #endif + + return CKR_OK; +@@ -3253,7 +2939,9 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + { + unsigned int len; + CK_RV rc = CKR_OK; ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *md_ctx; ++#endif + + UNUSED(tokdata); + +@@ -3263,6 +2951,7 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + if (!in_data || !out_data) + return CKR_ARGUMENTS_BAD; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + /* Recreate the OpenSSL MD context from the saved context */ + md_ctx = md_ctx_from_context(ctx); + if (md_ctx == NULL) { +@@ -3275,21 +2964,38 @@ CK_RV token_specific_sha(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + + if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len) || + !EVP_DigestFinal(md_ctx, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + rc = CKR_FUNCTION_FAILED; + goto out; + } + + *out_data_len = len; ++#else ++ if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL)); ++ return CKR_BUFFER_TOO_SMALL; ++ } ++ ++ len = *out_data_len; ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len) || ++ !EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ *out_data_len = len; ++#endif + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + out: +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); +-#endif + free(ctx->context); ++#else ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); ++#endif + ctx->context = NULL; + ctx->context_len = 0; ++ ctx->context_free_func = NULL; + + return rc; + } +@@ -3297,7 +3003,9 @@ out: + CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + CK_BYTE *in_data, CK_ULONG in_data_len) + { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *md_ctx; ++#endif + + UNUSED(tokdata); + +@@ -3307,6 +3015,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + if (!in_data) + return CKR_ARGUMENTS_BAD; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + /* Recreate the OpenSSL MD context from the saved context */ + md_ctx = md_ctx_from_context(ctx); + if (md_ctx == NULL) { +@@ -3315,24 +3024,24 @@ CK_RV token_specific_sha_update(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + } + + if (!EVP_DigestUpdate(md_ctx, in_data, in_data_len)) { +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); +-#endif + free(ctx->context); + ctx->context = NULL; + ctx->context_len = 0; ++ ctx->context_free_func = NULL; ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); + return CKR_FUNCTION_FAILED; + } + + /* Save context data for later use */ + memcpy(ctx->context, EVP_MD_CTX_md_data(md_ctx), ctx->context_len); + +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); ++#else ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } + #endif + + return CKR_OK; +@@ -3343,7 +3052,9 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + { + unsigned int len; + CK_RV rc = CKR_OK; ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *md_ctx; ++#endif + + UNUSED(tokdata); + +@@ -3353,6 +3064,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + if (!out_data) + return CKR_ARGUMENTS_BAD; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + /* Recreate the OpenSSL MD context from the saved context */ + md_ctx = md_ctx_from_context(ctx); + if (md_ctx == NULL) { +@@ -3370,14 +3082,30 @@ CK_RV token_specific_sha_final(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + *out_data_len = len; + + out: +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- EVP_MD_CTX_destroy(md_ctx); +-#else + EVP_MD_CTX_free(md_ctx); +-#endif + free(ctx->context); + ctx->context = NULL; + ctx->context_len = 0; ++ ctx->context_free_func = NULL; ++#else ++ if (*out_data_len < (CK_ULONG)EVP_MD_CTX_size((EVP_MD_CTX *)ctx->context)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL)); ++ return CKR_BUFFER_TOO_SMALL; ++ } ++ ++ len = *out_data_len; ++ if (!EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ *out_data_len = len; ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); ++ ctx->context = NULL; ++ ctx->context_len = 0; ++ ctx->context_free_func = NULL; ++#endif + + return rc; + } +@@ -3897,99 +3625,26 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + CK_ULONG message_len, OBJECT *key, CK_BYTE *mac, + CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx) + { +-#if OPENSSL_VERSION_NUMBER < 0x10101000L + int rc; +- CK_RV rv = CKR_OK; +- CK_ATTRIBUTE *attr = NULL; +- CK_KEY_TYPE keytype; +- CMAC_CTX *cmac_ctx; +- const EVP_CIPHER *cipher; +- size_t maclen; +- +- UNUSED(tokdata); +- +- if (first) { +- // get the key type +- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key.\n"); +- return CKR_FUNCTION_FAILED; +- } +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- switch (keytype) { +- case CKK_DES2: +- cipher = EVP_des_ede_cbc(); +- break; +- case CKK_DES3: +- cipher = EVP_des_ede3_cbc(); +- break; +- default: +- TRACE_ERROR("Invalid key type: %lu\n", keytype); +- return CKR_KEY_TYPE_INCONSISTENT; +- } +- if (cipher == NULL) { +- TRACE_ERROR("Failed to allocate cipher\n"); +- return CKR_HOST_MEMORY; +- } +- +- cmac_ctx = CMAC_CTX_new(); +- if (cmac_ctx == NULL) { +- TRACE_ERROR("Failed to allocate CMAC context\n"); +- return CKR_HOST_MEMORY; +- } +- +- rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Init failed\n"); +- CMAC_CTX_free(cmac_ctx); +- return CKR_FUNCTION_FAILED; +- } +- +- *ctx = cmac_ctx; +- } +- +- cmac_ctx = (CMAC_CTX *)*ctx; +- +- rc = CMAC_Update(cmac_ctx, message, message_len); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Update failed\n"); +- rv = CKR_FUNCTION_FAILED; +- } +- +- if (last) { +- maclen = AES_BLOCK_SIZE; +- rc = CMAC_Final(cmac_ctx, mac, &maclen); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Final failed\n"); +- rv = CKR_FUNCTION_FAILED; +- } +- } +- +- if (last || (first && rv != CKR_OK)) { +- CMAC_CTX_free(cmac_ctx); +- *ctx = NULL; +- } +- +- return rv; +-#else +- int rc; +- size_t maclen; ++ size_t maclen; + CK_RV rv = CKR_OK; + CK_ATTRIBUTE *attr = NULL; + CK_KEY_TYPE keytype; + const EVP_CIPHER *cipher; + struct cmac_ctx { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *mctx; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; ++#else ++ EVP_MAC *mac; ++ EVP_MAC_CTX *mctx; ++#endif + }; + struct cmac_ctx *cmac = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_PARAM params[2]; ++#endif + + UNUSED(tokdata); + +@@ -4031,10 +3686,11 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + cmac->mctx = EVP_MD_CTX_new(); + if (cmac->mctx == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- rv = ERR_HOST_MEMORY; ++ rv = CKR_HOST_MEMORY; + goto err; + } + +@@ -4053,6 +3709,31 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + rv = CKR_FUNCTION_FAILED; + goto err; + } ++#else ++ cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL); ++ if (cmac->mac == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto err; ++ } ++ ++ cmac->mctx = EVP_MAC_CTX_new(cmac->mac); ++ if (cmac->mctx == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); ++ rv = CKR_HOST_MEMORY; ++ goto err; ++ } ++ ++ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, ++ (char *)EVP_CIPHER_get0_name(cipher), 0); ++ params[1] = OSSL_PARAM_construct_end(); ++ ++ if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto err; ++ } ++#endif + + *ctx = cmac; + } +@@ -4064,9 +3745,17 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len); ++#else ++ rc = EVP_MAC_update(cmac->mctx, message, message_len); ++#endif + if (rc != 1 || message_len > INT_MAX) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++#else ++ TRACE_ERROR("EVP_MAC_update failed\n"); ++#endif + rv = CKR_FUNCTION_FAILED; + goto err; + } +@@ -4074,15 +3763,28 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + if (last) { + maclen = AES_BLOCK_SIZE; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen); ++#else ++ rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen); ++#endif + if (rc != 1) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + TRACE_ERROR("EVP_DigestSignFinal failed\n"); ++#else ++ TRACE_ERROR("EVP_MAC_final failed\n"); ++#endif + rv = CKR_FUNCTION_FAILED; + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX_free(cmac->mctx); /* frees pctx */ + EVP_PKEY_free(cmac->pkey); ++#else ++ EVP_MAC_CTX_free(cmac->mctx); ++ EVP_MAC_free(cmac->mac); ++#endif + free(cmac); + *ctx = NULL; + } +@@ -4090,15 +3792,21 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + return CKR_OK; + err: + if (cmac != NULL) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (cmac->mctx != NULL) + EVP_MD_CTX_free(cmac->mctx); /* frees pctx */ + if (cmac->pkey != NULL) + EVP_PKEY_free(cmac->pkey); ++#else ++ if (cmac->mctx != NULL) ++ EVP_MAC_CTX_free(cmac->mctx); ++ if (cmac->mac != NULL) ++ EVP_MAC_free(cmac->mac); ++#endif + free(cmac); + } + *ctx = NULL; + return rv; +-#endif + } + + +@@ -4106,93 +3814,25 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + CK_ULONG message_len, OBJECT *key, CK_BYTE *mac, + CK_BBOOL first, CK_BBOOL last, CK_VOID_PTR *ctx) + { +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- int rc; +- CK_RV rv = CKR_OK; +- CK_ATTRIBUTE *attr = NULL; +- CMAC_CTX *cmac_ctx; +- const EVP_CIPHER *cipher; +- size_t maclen; +- +- UNUSED(tokdata); +- +- if (first) { +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- +- switch (attr->ulValueLen * 8) { +- case 128: +- cipher = EVP_aes_128_cbc(); +- break; +- case 192: +- cipher = EVP_aes_192_cbc(); +- break; +- case 256: +- cipher = EVP_aes_256_cbc(); +- break; +- default: +- TRACE_ERROR("Invalid key size: %lu\n", attr->ulValueLen); +- return CKR_KEY_TYPE_INCONSISTENT; +- } +- if (cipher == NULL) { +- TRACE_ERROR("Failed to allocate cipher\n"); +- return CKR_HOST_MEMORY; +- } +- +- cmac_ctx = CMAC_CTX_new(); +- if (cmac_ctx == NULL) { +- TRACE_ERROR("Failed to allocate CMAC context\n"); +- return CKR_HOST_MEMORY; +- } +- +- rc = CMAC_Init(cmac_ctx, attr->pValue, attr->ulValueLen, cipher, NULL); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Init failed\n"); +- CMAC_CTX_free(cmac_ctx); +- return CKR_FUNCTION_FAILED; +- } +- +- *ctx = cmac_ctx; +- } +- +- cmac_ctx = (CMAC_CTX *)*ctx; +- +- rc = CMAC_Update(cmac_ctx, message, message_len); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Update failed\n"); +- rv = CKR_FUNCTION_FAILED; +- } +- +- if (last) { +- maclen = AES_BLOCK_SIZE; +- rc = CMAC_Final(cmac_ctx, mac, &maclen); +- if (rc != 1) { +- TRACE_ERROR("CMAC_Final failed\n"); +- rv = CKR_FUNCTION_FAILED; +- } +- } +- +- if (last || (first && rv != CKR_OK)) { +- CMAC_CTX_free(cmac_ctx); +- *ctx = NULL; +- } +- +- return rv; +-#else + int rc; + size_t maclen; + CK_RV rv = CKR_OK; + CK_ATTRIBUTE *attr = NULL; + const EVP_CIPHER *cipher; + struct cmac_ctx { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX *mctx; + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; ++#else ++ EVP_MAC *mac; ++ EVP_MAC_CTX *mctx; ++#endif + }; + struct cmac_ctx *cmac = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_PARAM params[2]; ++#endif + + UNUSED(tokdata); + +@@ -4229,6 +3869,7 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + cmac->mctx = EVP_MD_CTX_new(); + if (cmac->mctx == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +@@ -4251,6 +3892,31 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + rv = CKR_FUNCTION_FAILED; + goto err; + } ++#else ++ cmac->mac = EVP_MAC_fetch(NULL, "CMAC", NULL); ++ if (cmac->mac == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto err; ++ } ++ ++ cmac->mctx = EVP_MAC_CTX_new(cmac->mac); ++ if (cmac->mctx == NULL) { ++ TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); ++ rv = CKR_HOST_MEMORY; ++ goto err; ++ } ++ ++ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, ++ (char *)EVP_CIPHER_get0_name(cipher), 0); ++ params[1] = OSSL_PARAM_construct_end(); ++ ++ if (!EVP_MAC_init(cmac->mctx, attr->pValue, attr->ulValueLen, params)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ rv = CKR_FUNCTION_FAILED; ++ goto err; ++ } ++#endif + + *ctx = cmac; + } +@@ -4262,9 +3928,17 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = EVP_DigestSignUpdate(cmac->mctx, message, message_len); ++#else ++ rc = EVP_MAC_update(cmac->mctx, message, message_len); ++#endif + if (rc != 1 || message_len > INT_MAX) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++#else ++ TRACE_ERROR("EVP_MAC_update failed\n"); ++#endif + rv = CKR_FUNCTION_FAILED; + goto err; + } +@@ -4272,15 +3946,28 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + if (last) { + maclen = AES_BLOCK_SIZE; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = EVP_DigestSignFinal(cmac->mctx, mac, &maclen); ++#else ++ rc = EVP_MAC_final(cmac->mctx, mac, &maclen, maclen); ++#endif + if (rc != 1) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + TRACE_ERROR("EVP_DigestSignFinal failed\n"); ++#else ++ TRACE_ERROR("EVP_MAC_final failed\n"); ++#endif + rv = CKR_FUNCTION_FAILED; + goto err; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EVP_MD_CTX_free(cmac->mctx); /* frees pctx */ + EVP_PKEY_free(cmac->pkey); ++#else ++ EVP_MAC_CTX_free(cmac->mctx); ++ EVP_MAC_free(cmac->mac); ++#endif + free(cmac); + *ctx = NULL; + } +@@ -4288,37 +3975,90 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + return CKR_OK; + err: + if (cmac != NULL) { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (cmac->mctx != NULL) + EVP_MD_CTX_free(cmac->mctx); /* frees pctx */ + if (cmac->pkey != NULL) + EVP_PKEY_free(cmac->pkey); ++#else ++ if (cmac->mctx != NULL) ++ EVP_MAC_CTX_free(cmac->mctx); ++ if (cmac->mac != NULL) ++ EVP_MAC_free(cmac->mac); ++#endif + free(cmac); + } + *ctx = NULL; + return rv; +-#endif + } + + #ifndef NO_EC + +-static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len, +- EC_KEY **key) ++static int curve_nid_from_params(const CK_BYTE *params, CK_ULONG params_len) + { + const unsigned char *oid; + ASN1_OBJECT *obj = NULL; +- EC_KEY *ec_key = NULL; + int nid; +- CK_RV rc = CKR_OK; + + oid = params; + obj = d2i_ASN1_OBJECT(NULL, &oid, params_len); + if (obj == NULL) { + TRACE_ERROR("curve not supported by OpenSSL.\n"); +- rc = CKR_CURVE_NOT_SUPPORTED; +- goto out; ++ return NID_undef; + } + + nid = OBJ_obj2nid(obj); ++ ASN1_OBJECT_free(obj); ++ ++ return nid; ++} ++ ++static int ec_prime_len_from_nid(int nid) ++{ ++ EC_GROUP *group; ++ int primelen; ++ ++ group = EC_GROUP_new_by_curve_name(nid); ++ if (group == NULL) ++ return -1; ++ ++ primelen = EC_GROUP_order_bits(group); ++ ++ EC_GROUP_free(group); ++ ++ if ((primelen % 8) == 0) ++ return primelen / 8; ++ else ++ return (primelen / 8) + 1; ++} ++ ++int ec_prime_len_from_pkey(EVP_PKEY *pkey) ++{ ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ return (EC_GROUP_order_bits(EC_KEY_get0_group( ++ EVP_PKEY_get0_EC_KEY(pkey))) + 7) / 8; ++#else ++ size_t curve_len; ++ char curve[80]; ++ ++ if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, ++ curve, sizeof(curve), &curve_len)) ++ return -1; ++ ++ return ec_prime_len_from_nid(OBJ_sn2nid(curve)); ++#endif ++} ++ ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len, ++ EC_KEY **key) ++{ ++ EC_KEY *ec_key = NULL; ++ int nid; ++ CK_RV rc = CKR_OK; ++ ++ nid = curve_nid_from_params(params, params_len); + if (nid == NID_undef) { + TRACE_ERROR("curve not supported by OpenSSL.\n"); + rc = CKR_CURVE_NOT_SUPPORTED; +@@ -4333,9 +4073,6 @@ static CK_RV make_ec_key_from_params(const CK_BYTE *params, CK_ULONG params_len, + } + + out: +- if (obj != NULL) +- ASN1_OBJECT_free(obj); +- + if (rc != CKR_OK) { + if (ec_key != NULL) + EC_KEY_free(ec_key); +@@ -4347,16 +4084,97 @@ out: + + return CKR_OK; + } ++#endif ++ ++#if OPENSSL_VERSION_PREREQ(3, 0) ++static CK_RV build_pkey_from_params(OSSL_PARAM_BLD *tmpl, int selection, ++ EVP_PKEY **pkey) ++{ ++ ++ OSSL_PARAM *params = NULL; ++ EVP_PKEY_CTX *pctx = NULL; ++ CK_RV rc = CKR_OK; ++ ++ params = OSSL_PARAM_BLD_to_param(tmpl); ++ if (params == NULL) { ++ TRACE_ERROR("OSSL_PARAM_BLD_to_param failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); ++ if (pctx == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new_id failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (!EVP_PKEY_fromdata_init(pctx) || ++ !EVP_PKEY_fromdata(pctx, pkey, selection, params)) { ++ TRACE_ERROR("EVP_PKEY_fromdata failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ EVP_PKEY_CTX_free(pctx); ++ pctx = EVP_PKEY_CTX_new(*pkey, NULL); ++ if (pctx == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) { ++ if (EVP_PKEY_check(pctx) != 1) { ++ TRACE_ERROR("EVP_PKEY_check failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ } else { ++ if (EVP_PKEY_public_check(pctx) != 1) { ++ TRACE_ERROR("EVP_PKEY_public_check failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ } ++ ++out: ++ if (pctx != NULL) ++ EVP_PKEY_CTX_free(pctx); ++ if (params != NULL) ++ OSSL_PARAM_free(params); ++ ++ if (rc != 0 && *pkey != NULL) { ++ EVP_PKEY_free(*pkey); ++ *pkey = NULL; ++ } ++ ++ return rc; ++} ++#endif + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data, +- CK_ULONG data_len, CK_BBOOL allow_raw) ++ CK_ULONG data_len, CK_BBOOL allow_raw, ++ int nid, EVP_PKEY **ec_pkey) ++#else ++static CK_RV fill_ec_key_from_pubkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data, ++ CK_ULONG data_len, CK_BBOOL allow_raw, ++ int nid, EVP_PKEY **ec_pkey) ++#endif + { + CK_BYTE *ecpoint = NULL; + CK_ULONG ecpoint_len, privlen; + CK_BBOOL allocated = FALSE; ++ + CK_RV rc; + +- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8; ++ privlen = ec_prime_len_from_nid(nid); ++ if (privlen <= 0) { ++ TRACE_ERROR("ec_prime_len_from_nid failed\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; ++ goto out; ++ } + + rc = ec_point_from_public_data(data, data_len, privlen, allow_raw, + &allocated, &ecpoint, &ecpoint_len); +@@ -4365,6 +4183,7 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data, + goto out; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (!EC_KEY_oct2key(ec_key, ecpoint, ecpoint_len, NULL)) { + TRACE_ERROR("EC_KEY_oct2key failed\n"); + rc = CKR_FUNCTION_FAILED; +@@ -4377,6 +4196,34 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data, + goto out; + } + ++ *ec_pkey = EVP_PKEY_new(); ++ if (*ec_pkey == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed.\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) { ++ TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#else ++ if (!OSSL_PARAM_BLD_push_octet_string(tmpl, ++ OSSL_PKEY_PARAM_PUB_KEY, ++ ecpoint, ecpoint_len)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ rc = build_pkey_from_params(tmpl, EVP_PKEY_PUBLIC_KEY, ec_pkey); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("build_pkey_from_params failed\n"); ++ goto out; ++ } ++ #endif ++ + out: + if (allocated && ecpoint != NULL) + free(ecpoint); +@@ -4384,12 +4231,26 @@ out: + return rc; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data, +- CK_ULONG data_len) ++ CK_ULONG data_len, EVP_PKEY **ec_pkey) ++#else ++static CK_RV fill_ec_key_from_privkey(OSSL_PARAM_BLD *tmpl, const CK_BYTE *data, ++ CK_ULONG data_len, int nid, ++ EVP_PKEY **ec_pkey) ++#endif + { + EC_POINT *point = NULL; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ EC_GROUP *group = NULL; ++ BIGNUM *bn_priv = NULL; ++ unsigned char *pub_key = NULL; ++ unsigned int pub_key_len; ++ point_conversion_form_t form; ++#endif + CK_RV rc = CKR_OK; + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (!EC_KEY_oct2priv(ec_key, data, data_len)) { + TRACE_ERROR("EC_KEY_oct2priv failed\n"); + rc = CKR_FUNCTION_FAILED; +@@ -4422,18 +4283,102 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data, + goto out; + } + ++ *ec_pkey = EVP_PKEY_new(); ++ if (*ec_pkey == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed.\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!EVP_PKEY_assign_EC_KEY(*ec_pkey, ec_key)) { ++ TRACE_ERROR("EVP_PKEY_assign_EC_KEY failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#else ++ group = EC_GROUP_new_by_curve_name(nid); ++ if (group == NULL) { ++ TRACE_ERROR("EC_GROUP_new_by_curve_name failed\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ point = EC_POINT_new(group); ++ if (point == NULL) { ++ TRACE_ERROR("EC_POINT_new failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ bn_priv = BN_bin2bn(data, data_len, NULL); ++ if (bn_priv == NULL) { ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (!EC_POINT_mul(group, point, bn_priv, NULL, NULL, NULL)) { ++ TRACE_ERROR("EC_POINT_mul failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ form = EC_GROUP_get_point_conversion_form(group); ++ pub_key_len = EC_POINT_point2buf(group, point, form, &pub_key, ++ NULL); ++ if (pub_key_len == 0) { ++ TRACE_ERROR("EC_POINT_point2buf failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY, ++ pub_key, pub_key_len)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_octet_string failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, bn_priv)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_BN failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ rc = build_pkey_from_params(tmpl, EVP_PKEY_KEYPAIR, ec_pkey); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("build_pkey_from_params failed\n"); ++ goto out; ++ } ++#endif ++ + out: + if (point != NULL) + EC_POINT_free(point); ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (group != NULL) ++ EC_GROUP_free(group); ++ if (bn_priv != NULL) ++ BN_free(bn_priv); ++ if (pub_key != NULL) ++ OPENSSL_free(pub_key); ++#endif + + return rc; + } + +-static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key) ++ ++ ++static CK_RV make_ec_key_from_template(TEMPLATE *template, EVP_PKEY **pkey) + { + CK_ATTRIBUTE *attr = NULL; + CK_OBJECT_CLASS keyclass; ++ EVP_PKEY *ec_pkey = NULL; ++ int nid; ++#if !OPENSSL_VERSION_PREREQ(3, 0) + EC_KEY *ec_key = NULL; ++#else ++ OSSL_PARAM_BLD *tmpl = NULL; ++#endif + CK_RV rc; + + rc = template_attribute_get_ulong(template, CKA_CLASS, &keyclass); +@@ -4448,9 +4393,32 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key) + goto out; + } + ++ nid = curve_nid_from_params(attr->pValue, attr->ulValueLen); ++ if (nid == NID_undef) { ++ TRACE_ERROR("curve not supported by OpenSSL.\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; ++ goto out; ++ } ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key); + if (rc != CKR_OK) + goto out; ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) { ++ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME, ++ OBJ_nid2sn(nid), 0)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#endif + + switch (keyclass) { + case CKO_PUBLIC_KEY: +@@ -4460,8 +4428,13 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key) + goto out; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + rc = fill_ec_key_from_pubkey(ec_key, attr->pValue, attr->ulValueLen, +- FALSE); ++ FALSE, nid, &ec_pkey); ++#else ++ rc = fill_ec_key_from_pubkey(tmpl, attr->pValue, attr->ulValueLen, ++ FALSE, nid, &ec_pkey); ++#endif + if (rc != CKR_OK) { + TRACE_DEVEL("fill_ec_key_from_pubkey failed\n"); + goto out; +@@ -4475,7 +4448,14 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key) + goto out; + } + +- rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen); ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rc = fill_ec_key_from_privkey(ec_key, attr->pValue, attr->ulValueLen, ++ &ec_pkey); ++#else ++ rc = fill_ec_key_from_privkey(tmpl, attr->pValue, attr->ulValueLen, ++ nid, &ec_pkey); ++ ++#endif + if (rc != CKR_OK) { + TRACE_DEVEL("fill_ec_key_from_privkey failed\n"); + goto out; +@@ -4487,17 +4467,30 @@ static CK_RV make_ec_key_from_template(TEMPLATE *template, EC_KEY **key) + goto out; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ ec_key = NULL; ++#endif ++ + rc = CKR_OK; + + out: ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (tmpl != NULL) ++ OSSL_PARAM_BLD_free(tmpl); ++#endif ++ + if (rc != CKR_OK) { ++ if (ec_pkey != NULL) ++ EVP_PKEY_free(ec_pkey); ++#if !OPENSSL_VERSION_PREREQ(3, 0) + if (ec_key != NULL) + EC_KEY_free(ec_key); ++#endif + + return rc; + } + +- *key = ec_key; ++ *pkey = ec_pkey; + + return CKR_OK; + } +@@ -4508,10 +4501,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata, + { + + CK_ATTRIBUTE *attr = NULL, *ec_point_attr, *value_attr, *parms_attr; +- EC_KEY *ec_key = NULL; +- BN_CTX *ctx = NULL; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ const EC_KEY *ec_key = NULL; ++ BN_CTX *bnctx = NULL; ++#else ++ BIGNUM *bn_d = NULL; ++#endif + CK_BYTE *ecpoint = NULL, *enc_ecpoint = NULL, *d = NULL; + CK_ULONG ecpoint_len, enc_ecpoint_len, d_len; ++ EVP_PKEY_CTX *ctx = NULL; ++ EVP_PKEY *ec_pkey = NULL; ++ int nid; + CK_RV rc; + + UNUSED(tokdata); +@@ -4520,29 +4520,83 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata, + if (rc != CKR_OK) + goto out; + +- rc = make_ec_key_from_params(attr->pValue, attr->ulValueLen, &ec_key); +- if (rc != CKR_OK) ++ nid = curve_nid_from_params(attr->pValue, attr->ulValueLen); ++ if (nid == NID_undef) { ++ TRACE_ERROR("curve not supported by OpenSSL.\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; + goto out; ++ } + +- if (!EC_KEY_generate_key(ec_key)) { +- TRACE_ERROR("Failed to generate an EC key.\n"); ++ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); ++ if (ctx == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed\n"); + rc = CKR_FUNCTION_FAILED; + goto out; + } + +- ctx = BN_CTX_new(); +- if (ctx == NULL) { ++ if (EVP_PKEY_keygen_init(ctx) <= 0) { ++ TRACE_ERROR("EVP_PKEY_keygen_init failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) <= 0) { ++ TRACE_ERROR("EVP_PKEY_CTX_set_ec_paramgen_curve_nid failed\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; ++ goto out; ++ } ++ ++ if (EVP_PKEY_keygen(ctx, &ec_pkey) <= 0) { ++ TRACE_ERROR("EVP_PKEY_keygen failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ ec_key = EVP_PKEY_get0_EC_KEY(ec_pkey); ++ if (ec_key == NULL) { ++ TRACE_ERROR("EVP_PKEY_get0_EC_KEY failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ bnctx = BN_CTX_new(); ++ if (bnctx == NULL) { + rc = CKR_HOST_MEMORY; + goto out; + } + + ecpoint_len = EC_KEY_key2buf(ec_key, POINT_CONVERSION_UNCOMPRESSED, +- &ecpoint, ctx); ++ &ecpoint, bnctx); + if (ecpoint_len == 0) { + TRACE_ERROR("Failed to get the EC Point compressed.\n"); + rc = CKR_FUNCTION_FAILED; + goto out; + } ++#else ++ if (!EVP_PKEY_get_octet_string_param(ec_pkey, ++ OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, ++ NULL, 0, &ecpoint_len)) { ++ TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ ecpoint = OPENSSL_zalloc(ecpoint_len); ++ if (ecpoint == NULL) { ++ TRACE_ERROR("OPENSSL_zalloc failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!EVP_PKEY_get_octet_string_param(ec_pkey, ++ OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, ++ ecpoint, ecpoint_len, &ecpoint_len)) { ++ TRACE_ERROR("EVP_PKEY_get_octet_string_param failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#endif + + rc = ber_encode_OCTET_STRING(FALSE, &enc_ecpoint, &enc_ecpoint_len, + ecpoint, ecpoint_len); +@@ -4564,12 +4618,30 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata, + goto out; + } + ++#if !OPENSSL_VERSION_PREREQ(3, 0) + d_len = EC_KEY_priv2buf(ec_key, &d); + if (d_len == 0) { + TRACE_ERROR("Failed to get the EC private key.\n"); + rc = CKR_FUNCTION_FAILED; + goto out; + } ++#else ++ if (!EVP_PKEY_get_bn_param(ec_pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn_d)) { ++ TRACE_ERROR("EVP_PKEY_get_bn_param failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ d_len = ec_prime_len_from_nid(nid); ++ d = OPENSSL_zalloc(d_len); ++ if (d == NULL) { ++ TRACE_ERROR("OPENSSL_zalloc failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ BN_bn2binpad(bn_d, d, d_len); ++#endif + + rc = build_attribute(CKA_VALUE, d, d_len, &value_attr); + if (rc != CKR_OK) { +@@ -4602,10 +4674,17 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata, + rc = CKR_OK; + + out: +- if (ctx) +- BN_CTX_free(ctx); +- if (ec_key != NULL) +- EC_KEY_free(ec_key); ++ if (ctx != NULL) ++ EVP_PKEY_CTX_free(ctx); ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ if (bnctx != NULL) ++ BN_CTX_free(bnctx); ++#else ++ if (bn_d != NULL) ++ BN_free(bn_d); ++#endif ++ if (ec_pkey != NULL) ++ EVP_PKEY_free(ec_pkey); + if (ecpoint != NULL) + OPENSSL_free(ecpoint); + if (enc_ecpoint != NULL) +@@ -4621,11 +4700,15 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *sess, + CK_BYTE *out_data, CK_ULONG *out_data_len, + OBJECT *key_obj) + { +- EC_KEY *ec_key; +- ECDSA_SIG *sig; ++ EVP_PKEY *ec_key; ++ ECDSA_SIG *sig = NULL; + const BIGNUM *r, *s; + CK_ULONG privlen, n; + CK_RV rc = CKR_OK; ++ EVP_PKEY_CTX *ctx = NULL; ++ size_t siglen; ++ CK_BYTE *sigbuf = NULL; ++ const unsigned char *p; + + UNUSED(tokdata); + UNUSED(sess); +@@ -4636,16 +4719,54 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *sess, + if (rc != CKR_OK) + return rc; + +- sig = ECDSA_do_sign(in_data, in_data_len, ec_key); ++ ctx = EVP_PKEY_CTX_new(ec_key, NULL); ++ if (ctx == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_PKEY_sign_init(ctx) <= 0) { ++ TRACE_ERROR("EVP_PKEY_sign_init failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_PKEY_sign(ctx, NULL, &siglen, in_data, in_data_len) <= 0) { ++ TRACE_ERROR("EVP_PKEY_sign failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ sigbuf = malloc(siglen); ++ if (sigbuf == NULL) { ++ TRACE_ERROR("malloc failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (EVP_PKEY_sign(ctx, sigbuf, &siglen, in_data, in_data_len) <= 0) { ++ TRACE_ERROR("EVP_PKEY_sign failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ p = sigbuf; ++ sig = d2i_ECDSA_SIG(NULL, &p, siglen); + if (sig == NULL) { +- TRACE_ERROR("ECDSA_do_sign failed\n"); ++ TRACE_ERROR("d2i_ECDSA_SIG failed\n"); + rc = CKR_FUNCTION_FAILED; + goto out; + } + + ECDSA_SIG_get0(sig, &r, &s); + +- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8; ++ privlen = ec_prime_len_from_pkey(ec_key); ++ if (privlen <= 0) { ++ TRACE_ERROR("ec_prime_len_from_pkey failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } + + /* Insert leading 0x00's if r or s shorter than privlen */ + n = privlen - BN_num_bytes(r); +@@ -4662,7 +4783,11 @@ out: + if (sig != NULL) + ECDSA_SIG_free(sig); + if (ec_key != NULL) +- EC_KEY_free(ec_key); ++ EVP_PKEY_free(ec_key); ++ if (sigbuf != NULL) ++ free(sigbuf); ++ if (ctx != NULL) ++ EVP_PKEY_CTX_free(ctx); + + return rc; + } +@@ -4674,11 +4799,14 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, + CK_BYTE *signature, + CK_ULONG signature_len, OBJECT *key_obj) + { +- EC_KEY *ec_key; ++ EVP_PKEY *ec_key; + CK_ULONG privlen; + ECDSA_SIG *sig = NULL; + BIGNUM *r = NULL, *s = NULL; + CK_RV rc = CKR_OK; ++ size_t siglen; ++ CK_BYTE *sigbuf = NULL; ++ EVP_PKEY_CTX *ctx = NULL; + + UNUSED(tokdata); + UNUSED(sess); +@@ -4687,7 +4815,12 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, + if (rc != CKR_OK) + return rc; + +- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_key)) + 7) / 8; ++ privlen = ec_prime_len_from_pkey(ec_key); ++ if (privlen <= 0) { ++ TRACE_ERROR("ec_prime_len_from_pkey failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } + + if (signature_len < 2 * privlen) { + TRACE_ERROR("Signature is too short\n"); +@@ -4715,7 +4848,27 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, + goto out; + } + +- rc = ECDSA_do_verify(in_data, in_data_len, sig, ec_key); ++ siglen = i2d_ECDSA_SIG(sig, &sigbuf); ++ if (siglen <= 0) { ++ TRACE_ERROR("i2d_ECDSA_SIG failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ ctx = EVP_PKEY_CTX_new(ec_key, NULL); ++ if (ctx == NULL) { ++ TRACE_ERROR("EVP_PKEY_CTX_new failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_PKEY_verify_init(ctx) <= 0) { ++ TRACE_ERROR("EVP_PKEY_verify_init failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ rc = EVP_PKEY_verify(ctx, sigbuf, siglen, in_data, in_data_len); + switch (rc) { + case 0: + rc = CKR_SIGNATURE_INVALID; +@@ -4732,7 +4885,11 @@ out: + if (sig != NULL) + ECDSA_SIG_free(sig); + if (ec_key != NULL) +- EC_KEY_free(ec_key); ++ EVP_PKEY_free(ec_key); ++ if (sigbuf != NULL) ++ OPENSSL_free(sigbuf); ++ if (ctx != NULL) ++ EVP_PKEY_CTX_free(ctx); + + return rc; + } +@@ -4746,43 +4903,118 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata, + CK_ULONG *secret_value_len, + CK_BYTE *oid, CK_ULONG oid_length) + { +- EC_KEY *ec_pub = NULL, *ec_priv = NULL; +- CK_ULONG privlen; +- int secret_len; ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ EC_KEY *pub = NULL, *priv = NULL; ++#else ++ OSSL_PARAM_BLD *tmpl = NULL; ++#endif ++ EVP_PKEY *ec_pub = NULL, *ec_priv = NULL; ++ EVP_PKEY_CTX *ctx = NULL; ++ size_t secret_len; ++ int nid; + CK_RV rc; + + UNUSED(tokdata); + +- rc = make_ec_key_from_params(oid, oid_length, &ec_priv); ++ nid = curve_nid_from_params(oid, oid_length); ++ if (nid == NID_undef) { ++ TRACE_ERROR("curve not supported by OpenSSL.\n"); ++ rc = CKR_CURVE_NOT_SUPPORTED; ++ goto out; ++ } ++ ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rc = make_ec_key_from_params(oid, oid_length, &priv); + if (rc != CKR_OK) { + TRACE_DEVEL("make_ec_key_from_params failed\n"); + goto out; + } ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) { ++ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME, ++ OBJ_nid2sn(nid), 0)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#endif + +- rc = fill_ec_key_from_privkey(ec_priv, priv_bytes, priv_length); ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rc = fill_ec_key_from_privkey(priv, priv_bytes, priv_length, &ec_priv); ++#else ++ rc = fill_ec_key_from_privkey(tmpl, priv_bytes, priv_length, nid, &ec_priv); ++#endif + if (rc != CKR_OK) { + TRACE_DEVEL("fill_ec_key_from_privkey failed\n"); + goto out; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ priv = NULL; ++#else ++ OSSL_PARAM_BLD_free(tmpl); ++ tmpl = NULL; ++#endif + +- rc = make_ec_key_from_params(oid, oid_length, &ec_pub); ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rc = make_ec_key_from_params(oid, oid_length, &pub); + if (rc != CKR_OK) { + TRACE_DEVEL("make_ec_key_from_params failed\n"); + goto out; + } ++#else ++ tmpl = OSSL_PARAM_BLD_new(); ++ if (tmpl == NULL) { ++ TRACE_ERROR("OSSL_PARAM_BLD_new failed\n"); ++ rc = CKR_HOST_MEMORY; ++ goto out; ++ } ++ ++ if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME, ++ OBJ_nid2sn(nid), 0)) { ++ TRACE_ERROR("OSSL_PARAM_BLD_push_utf8_string failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++#endif + +- rc = fill_ec_key_from_pubkey(ec_pub, pub_bytes, pub_length, TRUE); ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rc = fill_ec_key_from_pubkey(pub, pub_bytes, pub_length, TRUE, nid, ++ &ec_pub); ++#else ++ rc = fill_ec_key_from_pubkey(tmpl, pub_bytes, pub_length, TRUE, nid, ++ &ec_pub); ++#endif + if (rc != CKR_OK) { + TRACE_DEVEL("fill_ec_key_from_pubkey failed\n"); + goto out; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ pub = NULL; ++#else ++ OSSL_PARAM_BLD_free(tmpl); ++ tmpl = NULL; ++#endif + +- privlen = (EC_GROUP_order_bits(EC_KEY_get0_group(ec_priv)) + 7) / 8; ++ ctx = EVP_PKEY_CTX_new(ec_priv, NULL); ++ if (ctx == NULL) { ++ TRACE_DEVEL("EVP_PKEY_CTX_new failed\n"); ++ goto out; ++ } + +- secret_len = ECDH_compute_key(secret_value, privlen, +- EC_KEY_get0_public_key(ec_pub), ec_priv, +- NULL); +- if (secret_len <= 0) { ++ if (EVP_PKEY_derive_init(ctx) <= 0 || ++ EVP_PKEY_derive_set_peer(ctx, ec_pub) <= 0) { ++ TRACE_DEVEL("EVP_PKEY_derive_init/EVP_PKEY_derive_set_peer failed\n"); ++ goto out; ++ } ++ ++ secret_len = ec_prime_len_from_nid(nid); ++ if (EVP_PKEY_derive(ctx, secret_value, &secret_len) <= 0) { + TRACE_DEVEL("ECDH_compute_key failed\n"); + rc = CKR_FUNCTION_FAILED; + *secret_value_len = 0; +@@ -4792,10 +5024,21 @@ CK_RV token_specific_ecdh_pkcs_derive(STDLL_TokData_t *tokdata, + *secret_value_len = secret_len; + + out: ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ if (priv != NULL) ++ EC_KEY_free(priv); ++ if (pub != NULL) ++ EC_KEY_free(pub); ++#else ++ if (tmpl != NULL) ++ OSSL_PARAM_BLD_free(tmpl); ++#endif + if (ec_priv != NULL) +- EC_KEY_free(ec_priv); ++ EVP_PKEY_free(ec_priv); + if (ec_pub != NULL) +- EC_KEY_free(ec_pub); ++ EVP_PKEY_free(ec_pub); ++ if (ctx != NULL) ++ EVP_PKEY_CTX_free(ctx); + + return rc; + } +@@ -4807,7 +5050,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, + { + CK_KEY_TYPE keytype; + #ifndef NO_EC +- EC_KEY *ec_key = NULL; ++ EVP_PKEY *ec_key = NULL; + #endif + CK_RV rc; + +@@ -4824,7 +5067,7 @@ CK_RV token_specific_object_add(STDLL_TokData_t * tokdata, SESSION * sess, + /* Check if OpenSSL supports the curve */ + rc = make_ec_key_from_template(obj->template, &ec_key); + if (ec_key != NULL) +- EC_KEY_free(ec_key); ++ EVP_PKEY_free(ec_key); + return rc; + #endif + diff --git a/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch b/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch new file mode 100644 index 0000000..af4395d --- /dev/null +++ b/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch @@ -0,0 +1,147 @@ +commit 533cdea6897d1bc0af13490f1c89248c52e7a73b +Author: Ingo Franzki +Date: Wed Jun 30 11:30:00 2021 +0200 + + COMMON: utilities.c: Remove deprecated OpenSSL functions + + Rework functions compute_sha(), compute_sha1(), and compute_md5() to + no longer use the mech_sha and mech_md5 routines, but to use the + OpenSSL EVP interface directly. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/utility.c b/usr/lib/common/utility.c +index bcdc15bf..5fc68938 100644 +--- a/usr/lib/common/utility.c ++++ b/usr/lib/common/utility.c +@@ -849,66 +849,89 @@ CK_RV get_hmac_digest(CK_ULONG mech, CK_ULONG *digest_mech, CK_BBOOL *general) + return CKR_OK; + } + +-/* Compute specified SHA using either software or token implementation */ ++/* Compute specified SHA or MD5 using software */ + CK_RV compute_sha(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len, + CK_BYTE *hash, CK_ULONG mech) + { +- DIGEST_CONTEXT ctx; +- CK_ULONG hash_len; +- CK_RV rv; ++ const EVP_MD *md; ++ unsigned int hash_len; + +- memset(&ctx, 0x0, sizeof(ctx)); +- ctx.mech.mechanism = mech; ++ UNUSED(tokdata); + +- rv = get_sha_size(mech, &hash_len); +- if (rv != CKR_OK) +- return rv; ++ switch (mech) { ++ case CKM_MD5: ++ hash_len = MD5_HASH_SIZE; ++ md = EVP_md5(); ++ break; ++ case CKM_SHA_1: ++ hash_len = SHA1_HASH_SIZE; ++ md = EVP_sha1(); ++ break; ++ case CKM_SHA224: ++ case CKM_SHA512_224: ++ hash_len = SHA224_HASH_SIZE; ++ md = EVP_sha224(); ++ break; ++ case CKM_SHA256: ++ case CKM_SHA512_256: ++ hash_len = SHA256_HASH_SIZE; ++ md = EVP_sha256(); ++ break; ++ case CKM_SHA384: ++ hash_len = SHA384_HASH_SIZE; ++ md = EVP_sha384(); ++ break; ++ case CKM_SHA512: ++ hash_len = SHA512_HASH_SIZE; ++ md = EVP_sha512(); ++ break; ++#ifdef NID_sha3_224 ++ case CKM_IBM_SHA3_224: ++ hash_len = SHA3_224_HASH_SIZE; ++ md = EVP_sha3_224(); ++ break; ++#endif ++#ifdef NID_sha3_256 ++ case CKM_IBM_SHA3_256: ++ hash_len = SHA3_256_HASH_SIZE; ++ md = EVP_sha3_256(); ++ break; ++#endif ++#ifdef NID_sha3_384 ++ case CKM_IBM_SHA3_384: ++ hash_len = SHA3_384_HASH_SIZE; ++ md = EVP_sha3_384(); ++ break; ++#endif ++#ifdef NID_sha3_512 ++ case CKM_IBM_SHA3_512: ++ hash_len = SHA3_512_HASH_SIZE; ++ md = EVP_sha3_512(); ++ break; ++#endif ++ default: ++ return CKR_MECHANISM_INVALID; ++ } + +- rv = sha_init(tokdata, NULL, &ctx, &ctx.mech); +- if (rv != CKR_OK) { +- TRACE_DEBUG("failed to create digest.\n"); +- return rv; ++ if (EVP_Digest(data, len, hash, &hash_len, md, NULL) != 1) { ++ TRACE_ERROR("%s EVP_Digest failed\n", __func__); ++ return CKR_FUNCTION_FAILED; + } +- rv = sha_hash(tokdata, NULL, FALSE, &ctx, data, len, hash, &hash_len); + +- digest_mgr_cleanup(&ctx); +- return rv; ++ return CKR_OK; + } + + /* Compute SHA1 using software implementation */ + CK_RV compute_sha1(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len, + CK_BYTE *hash) + { +- // XXX KEY +- DIGEST_CONTEXT ctx; +- CK_ULONG hash_len = SHA1_HASH_SIZE; +- +- UNUSED(tokdata); +- +- memset(&ctx, 0x0, sizeof(ctx)); +- +- sw_sha1_init(&ctx); +- if (ctx.context == NULL) +- return CKR_HOST_MEMORY; +- +- return sw_sha1_hash(&ctx, data, len, hash, &hash_len); ++ return compute_sha(tokdata, data, len, hash, CKM_SHA_1); + } + + CK_RV compute_md5(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len, + CK_BYTE *hash) + { +- DIGEST_CONTEXT ctx; +- CK_ULONG hash_len = MD5_HASH_SIZE; +- +- UNUSED(tokdata); +- +- memset(&ctx, 0x0, sizeof(ctx)); +- +- sw_md5_init(&ctx); +- if (ctx.context == NULL) +- return CKR_HOST_MEMORY; +- +- return sw_md5_hash(&ctx, data, len, hash, &hash_len); ++ return compute_sha(tokdata, data, len, hash, CKM_MD5); + } + + CK_RV get_keytype(STDLL_TokData_t *tokdata, CK_OBJECT_HANDLE hkey, diff --git a/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch b/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch new file mode 100644 index 0000000..165a69b --- /dev/null +++ b/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch @@ -0,0 +1,174 @@ +commit 5377d25a6cbe3d07afcd08276ad7e90f62cad0c9 +Author: Ingo Franzki +Date: Wed Jun 30 13:51:02 2021 +0200 + + COMMON: mech_sha: Remove deprecated OpenSSL functions + + All low level SHA functions are deprecated in OpenSSL 3.0. + Update the code to not use any of those. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h +index 314613a5..b3b965bf 100644 +--- a/usr/lib/common/h_extern.h ++++ b/usr/lib/common/h_extern.h +@@ -1543,7 +1543,7 @@ CK_RV aes_cfb_decrypt_final(STDLL_TokData_t *tokdata, SESSION *sess, + // SHA mechanisms + // + +-void sw_sha1_init(DIGEST_CONTEXT *ctx); ++CK_RV sw_sha1_init(DIGEST_CONTEXT *ctx); + + CK_RV sw_sha1_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + CK_ULONG in_data_len, CK_BYTE *out_data, +diff --git a/usr/lib/common/mech_sha.c b/usr/lib/common/mech_sha.c +index 0b9b7b28..1c81abe2 100644 +--- a/usr/lib/common/mech_sha.c ++++ b/usr/lib/common/mech_sha.c +@@ -38,30 +38,49 @@ + #include "tok_spec_struct.h" + #include "trace.h" + +-#include ++#include + #include + + // + // Software SHA-1 implementation (OpenSSL based) + // + +-void sw_sha1_init(DIGEST_CONTEXT *ctx) ++static void sw_sha1_free(STDLL_TokData_t *tokdata, SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len) + { +- ctx->context_len = sizeof(SHA_CTX); +- ctx->context = (CK_BYTE *) malloc(sizeof(SHA_CTX)); ++ UNUSED(tokdata); ++ UNUSED(sess); ++ UNUSED(context_len); ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)context); ++} ++ ++CK_RV sw_sha1_init(DIGEST_CONTEXT *ctx) ++{ ++ ctx->context_len = 1; ++ ctx->context = (CK_BYTE *)EVP_MD_CTX_new(); + if (ctx->context == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- // TODO: propagate error up? +- return; ++ return CKR_HOST_MEMORY; ++ } ++ ++ if (!EVP_DigestInit_ex((EVP_MD_CTX *)ctx->context, EVP_sha1(), NULL)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); ++ return CKR_FUNCTION_FAILED; + } + +- SHA1_Init((SHA_CTX *)ctx->context); ++ ctx->state_unsaveable = CK_TRUE; ++ ctx->context_free_func = sw_sha1_free; ++ ++ return CKR_OK; + } + + CK_RV sw_sha1_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + CK_ULONG in_data_len, CK_BYTE *out_data, + CK_ULONG *out_data_len) + { ++ unsigned int len; + + if (!ctx || !out_data_len) { + TRACE_ERROR("%s received bad argument(s)\n", __func__); +@@ -76,43 +95,60 @@ CK_RV sw_sha1_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- SHA1_Update((SHA_CTX *)ctx->context, in_data, in_data_len); +- SHA1_Final(out_data, (SHA_CTX *)ctx->context); +- *out_data_len = SHA1_HASH_SIZE; ++ len = *out_data_len; ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len) || ++ !EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ *out_data_len = len; + +- if (ctx->context_free_func != NULL) +- ctx->context_free_func(ctx->context, ctx->context_len); +- else +- free(ctx->context); ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); + ctx->context = NULL; ++ ctx->context_free_func = NULL; + + return CKR_OK; + } + +-CK_RV sw_sha1_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, +- CK_ULONG in_data_len) ++static CK_RV sw_sha1_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, ++ CK_ULONG in_data_len) + { + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- SHA1_Update((SHA_CTX *)ctx->context, in_data, in_data_len); ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ + return CKR_OK; + } + +-CK_RV sw_sha1_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, +- CK_ULONG *out_data_len) ++static CK_RV sw_sha1_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, ++ CK_ULONG *out_data_len) + { ++ unsigned int len; ++ + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- SHA1_Final(out_data, (SHA_CTX *)ctx->context); +- *out_data_len = SHA1_HASH_SIZE; ++ if (*out_data_len < SHA1_HASH_SIZE) { ++ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL)); ++ return CKR_BUFFER_TOO_SMALL; ++ } ++ ++ len = *out_data_len; ++ if (!EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ *out_data_len = len; + +- if (ctx->context_free_func != NULL) +- ctx->context_free_func(ctx->context, ctx->context_len); +- else +- free(ctx->context); ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); + ctx->context = NULL; ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +@@ -134,8 +170,7 @@ CK_RV sha_init(STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, + * supported. JML + */ + if (mech->mechanism == CKM_SHA_1) { +- sw_sha1_init(ctx); +- return CKR_OK; ++ return sw_sha1_init(ctx); + } else { + return CKR_MECHANISM_INVALID; + } diff --git a/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch b/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch new file mode 100644 index 0000000..0cfe159 --- /dev/null +++ b/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch @@ -0,0 +1,84 @@ +commit 5cceead028ec8e0c244b01d38c9096c96d98f96b +Author: Ingo Franzki +Date: Mon Jul 5 10:46:52 2021 +0200 + + ICSF: Remove support for OpenSSL < v1.1.1 + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/icsf_stdll/pbkdf.c b/usr/lib/icsf_stdll/pbkdf.c +index 4ddd0fd7..6ec4128a 100644 +--- a/usr/lib/icsf_stdll/pbkdf.c ++++ b/usr/lib/icsf_stdll/pbkdf.c +@@ -82,7 +82,6 @@ CK_RV encrypt_aes(CK_BYTE * inbuf, int inbuflen, CK_BYTE * dkey, + const EVP_CIPHER *cipher = EVP_aes_256_cbc(); + int tmplen; + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + EVP_EncryptInit_ex(ctx, cipher, NULL, dkey, iv); +@@ -98,24 +97,6 @@ CK_RV encrypt_aes(CK_BYTE * inbuf, int inbuflen, CK_BYTE * dkey, + *outbuflen = (*outbuflen) + tmplen; + EVP_CIPHER_CTX_free(ctx); + +-#else +- EVP_CIPHER_CTX ctx; +- EVP_CIPHER_CTX_init(&ctx); +- +- EVP_EncryptInit_ex(&ctx, cipher, NULL, dkey, iv); +- if (!EVP_EncryptUpdate(&ctx, outbuf, outbuflen, inbuf, inbuflen)) { +- TRACE_ERROR("EVP_EncryptUpdate failed.\n"); +- return CKR_FUNCTION_FAILED; +- } +- if (!EVP_EncryptFinal_ex(&ctx, outbuf + (*outbuflen), &tmplen)) { +- TRACE_ERROR("EVP_EncryptFinal failed.\n"); +- return CKR_FUNCTION_FAILED; +- } +- +- *outbuflen = (*outbuflen) + tmplen; +- EVP_CIPHER_CTX_cleanup(&ctx); +-#endif +- + return CKR_OK; + } + +@@ -125,7 +106,6 @@ CK_RV decrypt_aes(CK_BYTE * inbuf, int inbuflen, CK_BYTE * dkey, + int size; + const EVP_CIPHER *cipher = EVP_aes_256_cbc(); + +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + + EVP_DecryptInit_ex(ctx, cipher, NULL, dkey, iv); +@@ -147,30 +127,6 @@ CK_RV decrypt_aes(CK_BYTE * inbuf, int inbuflen, CK_BYTE * dkey, + + EVP_CIPHER_CTX_free(ctx); + +-#else +- EVP_CIPHER_CTX ctx; +- EVP_CIPHER_CTX_init(&ctx); +- +- EVP_DecryptInit_ex(&ctx, cipher, NULL, dkey, iv); +- if (!EVP_DecryptUpdate(&ctx, outbuf, outbuflen, inbuf, inbuflen)) { +- TRACE_ERROR("EVP_DecryptUpdate failed.\n"); +- return CKR_FUNCTION_FAILED; +- } +- if (!EVP_DecryptFinal_ex(&ctx, outbuf + (*outbuflen), &size)) { +- TRACE_ERROR("EVP_DecryptFinal failed.\n"); +- return CKR_FUNCTION_FAILED; +- } +- +- /* total length of the decrypted data */ +- *outbuflen = (*outbuflen) + size; +- +- /* EVP_DecryptFinal removes any padding. The final length +- * is the length of the decrypted data without padding. +- */ +- +- EVP_CIPHER_CTX_cleanup(&ctx); +-#endif +- + return CKR_OK; + } + diff --git a/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch b/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch new file mode 100644 index 0000000..5721c2f --- /dev/null +++ b/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch @@ -0,0 +1,226 @@ +commit 62fc2bcd98672c5d0ff8a2c926f3103110e91ed7 +Author: Ingo Franzki +Date: Thu Jul 1 13:37:04 2021 +0200 + + COMMON: Perform proper context cleanup for 3DES/AES CMAC mechanisms + + The handling of 3DES/AES CMAC mechanisms use a complex context structure, + that contains pointers. Such state can not be saved, and needs a custom + context free routine to properly clean up the context. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/mech_aes.c b/usr/lib/common/mech_aes.c +index ad6af16b..59f82482 100644 +--- a/usr/lib/common/mech_aes.c ++++ b/usr/lib/common/mech_aes.c +@@ -2691,6 +2691,24 @@ CK_RV aes_mac_verify_final(STDLL_TokData_t *tokdata, + return CKR_SIGNATURE_INVALID; + } + ++static void aes_cmac_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len) ++{ ++ UNUSED(tokdata); ++ UNUSED(sess); ++ UNUSED(context_len); ++ ++ if (((AES_CMAC_CONTEXT *)context)->ctx != NULL) { ++ token_specific.t_aes_cmac(tokdata, (CK_BYTE *)"", 0, NULL, ++ ((AES_CMAC_CONTEXT *)context)->iv, ++ CK_FALSE, CK_TRUE, ++ ((AES_CMAC_CONTEXT *)context)->ctx); ++ ((AES_CMAC_CONTEXT *)context)->ctx = NULL; ++ } ++ ++ free(context); ++} ++ + CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata, + SESSION *sess, + CK_BBOOL length_only, +@@ -2743,6 +2761,8 @@ CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata, + if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = aes_cmac_cleanup; ++ + memcpy(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, mac_len); + *out_data_len = mac_len; + +@@ -2816,6 +2836,8 @@ CK_RV aes_cmac_sign_update(STDLL_TokData_t *tokdata, + + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; ++ ++ ctx->context_free_func = aes_cmac_cleanup; + } else { + TRACE_DEVEL("Token specific aes cmac failed.\n"); + } +@@ -2882,6 +2904,8 @@ CK_RV aes_cmac_sign_final(STDLL_TokData_t *tokdata, + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = aes_cmac_cleanup; ++ + memcpy(out_data, context->iv, mac_len); + *out_data_len = mac_len; + +@@ -2941,6 +2965,8 @@ CK_RV aes_cmac_verify(STDLL_TokData_t *tokdata, + if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = aes_cmac_cleanup; ++ + if (CRYPTO_memcmp(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { + return CKR_OK; +@@ -3012,6 +3038,8 @@ CK_RV aes_cmac_verify_update(STDLL_TokData_t *tokdata, + + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; ++ ++ ctx->context_free_func = aes_cmac_cleanup; + } else { + TRACE_DEVEL("Token specific aes cmac failed.\n"); + } +@@ -3070,6 +3098,8 @@ CK_RV aes_cmac_verify_final(STDLL_TokData_t *tokdata, + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = aes_cmac_cleanup; ++ + if (rc != CKR_OK) { + TRACE_DEVEL("Token specific aes mac failed.\n"); + return rc; +diff --git a/usr/lib/common/mech_des3.c b/usr/lib/common/mech_des3.c +index be8d6075..591ad3fa 100644 +--- a/usr/lib/common/mech_des3.c ++++ b/usr/lib/common/mech_des3.c +@@ -2334,6 +2334,24 @@ CK_RV des3_mac_verify_final(STDLL_TokData_t *tokdata, + return CKR_SIGNATURE_INVALID; + } + ++static void des3_cmac_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len) ++{ ++ UNUSED(tokdata); ++ UNUSED(sess); ++ UNUSED(context_len); ++ ++ if (((DES_CMAC_CONTEXT *)context)->ctx != NULL) { ++ token_specific.t_tdes_cmac(tokdata, (CK_BYTE *)"", 0, NULL, ++ ((DES_CMAC_CONTEXT *)context)->iv, ++ CK_FALSE, CK_TRUE, ++ ((DES_CMAC_CONTEXT *)context)->ctx); ++ ((DES_CMAC_CONTEXT *)context)->ctx = NULL; ++ } ++ ++ free(context); ++} ++ + CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata, + SESSION *sess, + CK_BBOOL length_only, +@@ -2383,6 +2401,8 @@ CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata, + if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = des3_cmac_cleanup; ++ + memcpy(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, mac_len); + + *out_data_len = mac_len; +@@ -2456,6 +2476,8 @@ CK_RV des3_cmac_sign_update(STDLL_TokData_t *tokdata, + + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; ++ ++ ctx->context_free_func = des3_cmac_cleanup; + } else { + TRACE_DEVEL("Token specific des3 cmac failed.\n"); + } +@@ -2521,6 +2543,8 @@ CK_RV des3_cmac_sign_final(STDLL_TokData_t *tokdata, + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = des3_cmac_cleanup; ++ + memcpy(out_data, context->iv, mac_len); + + *out_data_len = mac_len; +@@ -2577,6 +2601,8 @@ CK_RV des3_cmac_verify(STDLL_TokData_t *tokdata, + if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = des3_cmac_cleanup; ++ + if (CRYPTO_memcmp(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { + return CKR_OK; +@@ -2646,6 +2672,8 @@ CK_RV des3_cmac_verify_update(STDLL_TokData_t *tokdata, + + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; ++ ++ ctx->context_free_func = des3_cmac_cleanup; + } else { + TRACE_DEVEL("Token specific des3 cmac failed.\n"); + } +@@ -2709,6 +2737,8 @@ CK_RV des3_cmac_verify_final(STDLL_TokData_t *tokdata, + if (context->ctx != NULL) + ctx->state_unsaveable = CK_TRUE; + ++ ctx->context_free_func = des3_cmac_cleanup; ++ + if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) + return CKR_OK; + +diff --git a/usr/lib/ica_s390_stdll/ica_specific.c b/usr/lib/ica_s390_stdll/ica_specific.c +index 77876467..881a430c 100644 +--- a/usr/lib/ica_s390_stdll/ica_specific.c ++++ b/usr/lib/ica_s390_stdll/ica_specific.c +@@ -713,6 +713,9 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + UNUSED(tokdata); + UNUSED(ctx); + ++ if (key == NULL) ++ return CKR_ARGUMENTS_BAD; ++ + // get the key type + rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); + if (rc != CKR_OK) { +@@ -3621,6 +3624,9 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + UNUSED(tokdata); + UNUSED(ctx); + ++ if (key == NULL) ++ return CKR_ARGUMENTS_BAD; ++ + rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); + if (rc != CKR_OK) { + TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c +index aeff39a9..5ca22693 100644 +--- a/usr/lib/soft_stdll/soft_specific.c ++++ b/usr/lib/soft_stdll/soft_specific.c +@@ -3994,6 +3994,9 @@ CK_RV token_specific_tdes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + UNUSED(tokdata); + + if (first) { ++ if (key == NULL) ++ return CKR_ARGUMENTS_BAD; ++ + // get the key type + rv = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); + if (rv != CKR_OK) { +@@ -4194,6 +4197,9 @@ CK_RV token_specific_aes_cmac(STDLL_TokData_t *tokdata, CK_BYTE *message, + UNUSED(tokdata); + + if (first) { ++ if (key == NULL) ++ return CKR_ARGUMENTS_BAD; ++ + // get the key value + rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); + if (rc != CKR_OK) { diff --git a/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch b/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch new file mode 100644 index 0000000..516b513 --- /dev/null +++ b/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch @@ -0,0 +1,193 @@ +commit 6fee37f08391415cdf8d8610c501516c3d3ed29c +Author: Ingo Franzki +Date: Wed Jun 30 13:41:57 2021 +0200 + + COMMON: mech_md5: Remove deprecated OpenSSL functions + + All low level MD5 functions are deprecated in OpenSSL 3.0. + Update the code to not use any of those. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h +index 47b96ba0..314613a5 100644 +--- a/usr/lib/common/h_extern.h ++++ b/usr/lib/common/h_extern.h +@@ -1667,7 +1667,7 @@ CK_RV md5_hmac_verify(STDLL_TokData_t *tokdata, + CK_ULONG in_data_len, + CK_BYTE *signature, CK_ULONG sig_len); + +-void sw_md5_init(DIGEST_CONTEXT *ctx); ++CK_RV sw_md5_init(DIGEST_CONTEXT *ctx); + + CK_RV sw_md5_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + CK_ULONG in_data_len, CK_BYTE *out_data, +diff --git a/usr/lib/common/mech_md5.c b/usr/lib/common/mech_md5.c +index 320e2549..65c11def 100644 +--- a/usr/lib/common/mech_md5.c ++++ b/usr/lib/common/mech_md5.c +@@ -20,30 +20,50 @@ + #include "tok_spec_struct.h" + #include "trace.h" + +-#include ++#include + #include + + // + // Software MD5 implementation (OpenSSL based) + // + +-void sw_md5_init(DIGEST_CONTEXT *ctx) ++static void sw_md5_free(STDLL_TokData_t *tokdata, SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len) + { +- ctx->context_len = sizeof(MD5_CTX); +- ctx->context = (CK_BYTE *) malloc(sizeof(MD5_CTX)); ++ UNUSED(tokdata); ++ UNUSED(sess); ++ UNUSED(context_len); ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)context); ++} ++ ++CK_RV sw_md5_init(DIGEST_CONTEXT *ctx) ++{ ++ ctx->context_len = 1; ++ ctx->context = (CK_BYTE *)EVP_MD_CTX_new(); + if (ctx->context == NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); +- // TODO: propagate error up? +- return; ++ return CKR_HOST_MEMORY; ++ } ++ ++ if (!EVP_DigestInit_ex((EVP_MD_CTX *)ctx->context, EVP_md5(), NULL)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); ++ return CKR_FUNCTION_FAILED; + } + +- MD5_Init((MD5_CTX *)ctx->context); ++ ctx->state_unsaveable = CK_TRUE; ++ ctx->context_free_func = sw_md5_free; ++ ++ return CKR_OK; + } + + CK_RV sw_md5_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + CK_ULONG in_data_len, CK_BYTE *out_data, + CK_ULONG *out_data_len) + { ++ unsigned int len; ++ + if (!ctx || !out_data_len) { + TRACE_ERROR("%s received bad argument(s)\n", __func__); + return CKR_FUNCTION_FAILED; +@@ -57,43 +77,60 @@ CK_RV sw_md5_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- MD5_Update((MD5_CTX *)ctx->context, in_data, in_data_len); +- MD5_Final(out_data, (MD5_CTX *)ctx->context); +- *out_data_len = MD5_HASH_SIZE; ++ len = *out_data_len; ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len) || ++ !EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } + +- if (ctx->context_free_func != NULL) +- ctx->context_free_func(ctx->context, ctx->context_len); +- else +- free(ctx->context); ++ *out_data_len = len; ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); + ctx->context = NULL; ++ ctx->context_free_func = NULL; + + return CKR_OK; + } + +-CK_RV sw_MD5_Update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, +- CK_ULONG in_data_len) ++static CK_RV sw_md5_update(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, ++ CK_ULONG in_data_len) + { + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- MD5_Update((MD5_CTX *)ctx->context, in_data, in_data_len); ++ if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx->context, in_data, in_data_len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ + return CKR_OK; + } + +-CK_RV sw_MD5_Final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, +- CK_ULONG *out_data_len) ++static CK_RV sw_md5_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, ++ CK_ULONG *out_data_len) + { ++ unsigned int len; ++ + if (ctx->context == NULL) + return CKR_OPERATION_NOT_INITIALIZED; + +- MD5_Final(out_data, (MD5_CTX *)ctx->context); +- *out_data_len = MD5_HASH_SIZE; ++ if (*out_data_len < MD5_HASH_SIZE) { ++ TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL)); ++ return CKR_BUFFER_TOO_SMALL; ++ } + +- if (ctx->context_free_func != NULL) +- ctx->context_free_func(ctx->context, ctx->context_len); +- else +- free(ctx->context); ++ len = *out_data_len; ++ if (!EVP_DigestFinal((EVP_MD_CTX *)ctx->context, out_data, &len)) { ++ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ *out_data_len = len; ++ ++ EVP_MD_CTX_free((EVP_MD_CTX *)ctx->context); + ctx->context = NULL; ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +@@ -105,8 +142,7 @@ CK_RV md5_init(STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, + UNUSED(sess); + + if (mech->mechanism == CKM_MD5) { +- sw_md5_init(ctx); +- return CKR_OK; ++ return sw_md5_init(ctx); + } else { + return CKR_MECHANISM_INVALID; + } +@@ -159,7 +195,7 @@ CK_RV md5_hash_update(STDLL_TokData_t *tokdata, SESSION *sess, + return CKR_OK; + + if (ctx->mech.mechanism == CKM_MD5) +- return sw_MD5_Update(ctx, in_data, in_data_len); ++ return sw_md5_update(ctx, in_data, in_data_len); + else + return CKR_MECHANISM_INVALID; + } +@@ -188,7 +224,7 @@ CK_RV md5_hash_final(STDLL_TokData_t *tokdata, SESSION *sess, + } + + if (ctx->mech.mechanism == CKM_MD5) +- return sw_MD5_Final(ctx, out_data, out_data_len); ++ return sw_md5_final(ctx, out_data, out_data_len); + else + return CKR_MECHANISM_INVALID; + } diff --git a/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch b/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch new file mode 100644 index 0000000..b3c2339 --- /dev/null +++ b/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch @@ -0,0 +1,1085 @@ +commit 7a23c12214688b287b9591133445e593da633caa +Author: Ingo Franzki +Date: Mon Jul 5 12:58:42 2021 +0200 + + API: Use own OpenSSL library context for Opencryptoki's use of OpenSSL + + Create a separate library context for Opencryptoki's use of OpenSSL services + and explicitly load the 'default' provider for this context. + + This prevents call-loops when the calling application has configured a PKCS#11 + provider that uses Opencryptoki under the covers. This could produce a loop + with the following calling tree: + Application -> Openssl -> PKCS11-provider -> Opencryptoki -> OpenSSL + -> PKCS11-provider -> Opencryptoki -> ... + Explicitly using the 'default' provider only for Opencrypoki's OpenSSL usage + breaks this loop. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/include/apictl.h b/usr/include/apictl.h +index 81c65dad..0f3973b5 100644 +--- a/usr/include/apictl.h ++++ b/usr/include/apictl.h +@@ -13,12 +13,16 @@ + #include + #include + #include +- +-#include "local_types.h" ++#include + + #ifndef _APILOCAL_H + #define _APILOCAL_H + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ #include ++ #include ++#endif ++ + // SAB Add a linked list of STDLL's loaded to + // only load and get list once, but let multiple slots us it. + +@@ -59,6 +63,10 @@ typedef struct { + // per slot + int socketfd; + pthread_t event_thread; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_LIB_CTX *openssl_libctx; ++ OSSL_PROVIDER *openssl_default_provider; ++#endif + } API_Proc_Struct_t; + + #endif +diff --git a/usr/lib/api/api.mk b/usr/lib/api/api.mk +index 630a43b7..282f0017 100644 +--- a/usr/lib/api/api.mk ++++ b/usr/lib/api/api.mk +@@ -12,7 +12,7 @@ opencryptoki_libopencryptoki_la_CFLAGS = \ + -DSTDLL_NAME=\"api\" + + opencryptoki_libopencryptoki_la_LDFLAGS = \ +- -shared -Wl,-z,defs,-Bsymbolic -lc -ldl -lpthread \ ++ -shared -Wl,-z,defs,-Bsymbolic -lc -ldl -lpthread -lcrypto \ + -version-info $(SO_CURRENT):$(SO_REVISION):$(SO_AGE) \ + -Wl,--version-script=${srcdir}/opencryptoki.map + +diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c +index 6517ca6c..ca6aff06 100644 +--- a/usr/lib/api/api_interface.c ++++ b/usr/lib/api/api_interface.c +@@ -37,6 +37,28 @@ + + void api_init(); + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++#define BEGIN_OPENSSL_LIBCTX(ossl_ctx, rc) \ ++ do { \ ++ OSSL_LIB_CTX *prev_ctx = OSSL_LIB_CTX_set0_default((ossl_ctx));\ ++ if (prev_ctx == NULL) { \ ++ (rc) = CKR_FUNCTION_FAILED; \ ++ TRACE_ERROR("OSSL_LIB_CTX_set0_default failed\n"); \ ++ break; \ ++ } ++ ++#define END_OPENSSL_LIBCTX(rc) \ ++ if (OSSL_LIB_CTX_set0_default(prev_ctx) == NULL) { \ ++ if ((rc) == CKR_OK) \ ++ (rc) = CKR_FUNCTION_FAILED; \ ++ TRACE_ERROR("OSSL_LIB_CTX_set0_default failed\n"); \ ++ } \ ++ } while (0); ++#else ++#define BEGIN_OPENSSL_LIBCTX(ossl_ctx, rc) do { ++#define END_OPENSSL_LIBCTX(rc) } while (0); ++#endif ++ + // NOTES: + // In many cases the specificaiton does not allow returns + // of CKR_ARGUMENTSB_BAD. We break the spec, since validation of parameters +@@ -347,6 +369,7 @@ CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession) + + CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) + { ++ CK_RV rc = CKR_OK; + // Although why does modutil do a close all sessions. It is a single + // application it can only close its sessions... + // And all sessions should be closed anyhow. +@@ -365,9 +388,11 @@ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID) + /* for every node in the API-level session tree, if the session's slot + * matches slotID, close it + */ ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rc) + CloseAllSessions(slotID, FALSE); ++ END_OPENSSL_LIBCTX(rc) + +- return CKR_OK; ++ return rc; + } // end of C_CloseAllSessions + + //------------------------------------------------------------------------ +@@ -408,9 +433,12 @@ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_CloseSession) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_CloseSession(sltp->TokData, &rSession, FALSE); + TRACE_DEVEL("Called STDLL rv = 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) ++ + // If the STDLL successfully closed the session + // we can free it.. Otherwise we will have to leave it + // lying arround. +@@ -488,9 +516,12 @@ CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_CopyObject) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_CopyObject(sltp->TokData, &rSession, hObject, + pTemplate, ulCount, phNewObject); ++ TRACE_DEVEL("fcn->ST_CopyObject returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -558,10 +589,12 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_CreateObject) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_CreateObject(sltp->TokData, &rSession, pTemplate, + ulCount, phObject); + TRACE_DEVEL("fcn->ST_CreateObject returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -611,10 +644,12 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Decrypt) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Decrypt(sltp->TokData, &rSession, pEncryptedData, + ulEncryptedDataLen, pData, pulDataLen); + TRACE_DEVEL("fcn->ST_Decrypt returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -661,11 +696,13 @@ CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DecryptDigestUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DecryptDigestUpdate(sltp->TokData, &rSession, + pEncryptedPart, + ulEncryptedPartLen, pPart, pulPartLen); + TRACE_DEVEL("fcn->ST_DecryptDigestUpdate returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -714,10 +751,12 @@ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DecryptFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DecryptFinal(sltp->TokData, &rSession, pLastPart, + pulLastPartLen); + TRACE_DEVEL("fcn->ST_DecryptFinal returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -771,9 +810,11 @@ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DecryptInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DecryptInit(sltp->TokData, &rSession, pMechanism, hKey); + TRACE_DEVEL("fcn->ST_DecryptInit returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -823,11 +864,13 @@ CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DecryptUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DecryptUpdate(sltp->TokData, &rSession, + pEncryptedPart, ulEncryptedPartLen, + pPart, pulPartLen); + TRACE_DEVEL("fcn->ST_DecryptUpdate:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -873,11 +916,13 @@ CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DecryptVerifyUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DecryptVerifyUpdate(sltp->TokData, &rSession, + pEncryptedPart, ulEncryptedPartLen, + pPart, pulPartLen); + TRACE_DEVEL("fcn->ST_DecryptVerifyUpdate returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -941,10 +986,12 @@ CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DeriveKey) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DeriveKey(sltp->TokData, &rSession, pMechanism, + hBaseKey, pTemplate, ulAttributeCount, phKey); + TRACE_DEVEL("fcn->ST_DeriveKey returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -992,9 +1039,11 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DestroyObject) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DestroyObject(sltp->TokData, &rSession, hObject); + TRACE_DEVEL("fcn->ST_DestroyObject returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1040,10 +1089,12 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Digest) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Digest(sltp->TokData, &rSession, pData, ulDataLen, + pDigest, pulDigestLen); + TRACE_DEVEL("fcn->ST_Digest:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1091,11 +1142,13 @@ CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DigestEncryptUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DigestEncryptUpdate(sltp->TokData, &rSession, + pPart, ulPartLen, + pEncryptedPart, pulEncryptedPartLen); + TRACE_DEVEL("fcn->ST_DigestEncryptUpdate returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1139,10 +1192,12 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DigestFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DigestFinal(sltp->TokData, &rSession, pDigest, + pulDigestLen); + TRACE_DEVEL("fcn->ST_DigestFinal returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1189,9 +1244,11 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DigestInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DigestInit(sltp->TokData, &rSession, pMechanism); + TRACE_DEVEL("fcn->ST_DigestInit returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1234,9 +1291,11 @@ CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DigestKey) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DigestKey(sltp->TokData, &rSession, hKey); + TRACE_DEBUG("fcn->ST_DigestKey returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1280,9 +1339,11 @@ CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_DigestUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_DigestUpdate(sltp->TokData, &rSession, pPart, ulPartLen); + TRACE_DEVEL("fcn->ST_DigestUpdate returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1328,10 +1389,12 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Encrypt) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Encrypt(sltp->TokData, &rSession, pData, + ulDataLen, pEncryptedData, pulEncryptedDataLen); + TRACE_DEVEL("fcn->ST_Encrypt returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1376,10 +1439,12 @@ CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_EncryptFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_EncryptFinal(sltp->TokData, &rSession, + pLastEncryptedPart, pulLastEncryptedPartLen); + TRACE_DEVEL("fcn->ST_EncryptFinal: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1427,9 +1492,11 @@ CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_EncryptInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_EncryptInit(sltp->TokData, &rSession, pMechanism, hKey); + TRACE_INFO("fcn->ST_EncryptInit returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1476,11 +1543,13 @@ CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_EncryptUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_EncryptUpdate(sltp->TokData, &rSession, pPart, + ulPartLen, pEncryptedPart, + pulEncryptedPartLen); + TRACE_DEVEL("fcn->ST_EncryptUpdate returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1543,6 +1612,7 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) + // unload all the STDLL's from the application + // This is in case the APP decides to do the re-initialize and + // continue on ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rc) + for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { + sltp = &(Anchor->SltList[slotID]); + if (slot_loaded[slotID]) { +@@ -1565,12 +1635,20 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) + if (!in_child_fork_initializer) + DL_UnLoad(sltp, slotID); + } ++ END_OPENSSL_LIBCTX(rc) + + // Un register from Slot D + API_UnRegister(); + + bt_destroy(&Anchor->sess_btree); + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (Anchor->openssl_default_provider != NULL) ++ OSSL_PROVIDER_unload(Anchor->openssl_default_provider); ++ if (Anchor->openssl_libctx != NULL) ++ OSSL_LIB_CTX_free(Anchor->openssl_libctx); ++#endif ++ + detach_shared_memory(Anchor->SharedMemP); + free(Anchor); // Free API Proc Struct + Anchor = NULL; +@@ -1632,10 +1710,12 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_FindObjects) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_FindObjects(sltp->TokData, &rSession, phObject, + ulMaxObjectCount, pulObjectCount); + TRACE_DEVEL("fcn->ST_FindObjects returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1683,9 +1763,11 @@ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_FindObjectsFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_FindObjectsFinal(sltp->TokData, &rSession); + TRACE_DEVEL("fcn->ST_FindObjectsFinal returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1736,10 +1818,12 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_FindObjectsInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_FindObjectsInit(sltp->TokData, &rSession, + pTemplate, ulCount); + TRACE_DEVEL("fcn->ST_FindObjectsInit returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1794,10 +1878,12 @@ CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GenerateKey) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GenerateKey(sltp->TokData, &rSession, pMechanism, + pTemplate, ulCount, phKey); + TRACE_DEVEL("fcn->ST_GenerateKey returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1861,6 +1947,7 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GenerateKeyPair) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GenerateKeyPair(sltp->TokData, &rSession, + pMechanism, +@@ -1870,6 +1957,7 @@ CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, + ulPrivateKeyAttributeCount, + phPublicKey, phPrivateKey); + TRACE_DEVEL("fcn->ST_GenerateKeyPair returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1917,10 +2005,12 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GenerateRandom) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GenerateRandom(sltp->TokData, &rSession, + RandomData, ulRandomLen); + TRACE_DEVEL("fcn->ST_GenerateRandom returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -1977,10 +2067,12 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetAttributeValue) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GetAttributeValue(sltp->TokData, &rSession, + hObject, pTemplate, ulCount); + TRACE_DEVEL("fcn->ST_GetAttributeValue returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2098,8 +2190,10 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetMechanismInfo) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + rv = fcn->ST_GetMechanismInfo(sltp->TokData, slotID, type, pInfo); + TRACE_DEVEL("fcn->ST_GetMechanismInfo returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2156,9 +2250,11 @@ CK_RV C_GetMechanismList(CK_SLOT_ID slotID, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetMechanismList) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + rv = fcn->ST_GetMechanismList(sltp->TokData, slotID, + pMechanismList, pulCount); + TRACE_DEVEL("fcn->ST_GetMechanismList returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2220,9 +2316,11 @@ CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetObjectSize) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GetObjectSize(sltp->TokData, &rSession, hObject, pulSize); + TRACE_DEVEL("fcn->ST_GetObjectSize retuned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2272,10 +2370,12 @@ CK_RV C_GetOperationState(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetOperationState) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GetOperationState(sltp->TokData, &rSession, + pOperationState, pulOperationStateLen); + TRACE_DEVEL("fcn->ST_GetOperationState returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2328,6 +2428,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetSessionInfo) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_GetSessionInfo(sltp->TokData, &rSession, pInfo); + +@@ -2335,6 +2436,7 @@ CK_RV C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) + TRACE_DEVEL("Slot %lu State %lx Flags %lx DevErr %lx\n", + pInfo->slotID, pInfo->state, pInfo->flags, + pInfo->ulDeviceError); ++ END_OPENSSL_LIBCTX(rv) + + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); +@@ -2650,11 +2752,13 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_GetTokenInfo) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + rv = fcn->ST_GetTokenInfo(sltp->TokData, slotID, pInfo); + if (rv == CKR_OK) { + get_sess_count(slotID, &(pInfo->ulSessionCount)); + } + TRACE_DEVEL("rv %lu CK_TOKEN_INFO Flags %lx\n", rv, pInfo->flags); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -2814,6 +2918,35 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) + bt_init(&Anchor->sess_btree, free); + Anchor->Pid = getpid(); + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ /* ++ * OpenSSL >= 3.0: ++ * Create a separate library context for Opencryptoki's use of OpenSSL ++ * services and explicitly load the 'default' provider for this context. ++ * This prevents call loops when the calling application has configured a ++ * PKCS#11 provider that uses Opencryptoki under the covers. This could ++ * produce a loop with the following calling tree: ++ * Application -> Openssl -> PKCS11-provider -> Opencryptoki -> OpenSSL ++ * -> PKCS11-provider -> Opencryptoki -> ... ++ * Explicitly using the 'default' provider only for Opencrypoki's OpenSSL ++ * usage breaks this loop. ++ */ ++ Anchor->openssl_libctx = OSSL_LIB_CTX_new(); ++ if (Anchor->openssl_libctx == NULL) { ++ TRACE_ERROR("OSSL_LIB_CTX_new failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto error; ++ } ++ ++ Anchor->openssl_default_provider = ++ OSSL_PROVIDER_load(Anchor->openssl_libctx, "default"); ++ if (Anchor->openssl_default_provider == NULL) { ++ TRACE_ERROR("OSSL_PROVIDER_load for 'default' failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto error; ++ } ++#endif ++ + // Get shared memory + if ((Anchor->SharedMemP = attach_shared_memory()) == NULL) { + OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to attach to " +@@ -2870,10 +3003,14 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) + } + // + // load all the slot DLL's here ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rc) + for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { + sltp = &(Anchor->SltList[slotID]); + slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); + } ++ END_OPENSSL_LIBCTX(rc) ++ if (rc != CKR_OK) ++ goto error_shm; + + /* Start event receiver thread */ + if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && +@@ -2883,6 +3020,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) + // unload all the STDLL's from the application + // This is in case the APP decides to do the re-initialize and + // continue on ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rc) + for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { + sltp = &(Anchor->SltList[slotID]); + if (slot_loaded[slotID]) { +@@ -2895,6 +3033,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) + } + DL_UnLoad(sltp, slotID); + } ++ END_OPENSSL_LIBCTX(rc) + + API_UnRegister(); + +@@ -2913,6 +3052,13 @@ error: + if (Anchor->socketfd >= 0) + close(Anchor->socketfd); + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ if (Anchor->openssl_default_provider != NULL) ++ OSSL_PROVIDER_unload(Anchor->openssl_default_provider); ++ if (Anchor->openssl_libctx != NULL) ++ OSSL_LIB_CTX_free(Anchor->openssl_libctx); ++#endif ++ + free((void *) Anchor); + Anchor = NULL; + +@@ -2974,9 +3120,11 @@ CK_RV C_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_InitPIN) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_InitPIN(sltp->TokData, &rSession, pPin, ulPinLen); + TRACE_DEVEL("fcn->ST_InitPIN returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3042,8 +3190,10 @@ CK_RV C_InitToken(CK_SLOT_ID slotID, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_InitToken) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + rv = fcn->ST_InitToken(sltp->TokData, slotID, pPin, ulPinLen, pLabel); + TRACE_DEVEL("fcn->ST_InitToken returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3097,9 +3247,11 @@ CK_RV C_Login(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Login) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Login(sltp->TokData, &rSession, userType, pPin, ulPinLen); + TRACE_DEVEL("fcn->ST_Login returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3147,9 +3299,11 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession) + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Logout) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Logout(sltp->TokData, &rSession); + TRACE_DEVEL("fcn->ST_Logout returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3223,9 +3377,11 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, + } + + if (fcn->ST_OpenSession) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + rv = fcn->ST_OpenSession(sltp->TokData, slotID, flags, + &(apiSessp->sessionh)); + TRACE_DEVEL("fcn->ST_OpenSession returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + + // If the session allocation is successful, then we need to + // complete the API session block and return. Otherwise +@@ -3237,10 +3393,12 @@ CK_RV C_OpenSession(CK_SLOT_ID slotID, + */ + *phSession = AddToSessionList(apiSessp); + if (*phSession == 0) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + /* failed to add the object to the API-level tree, close the + * STDLL-level session and return failure + */ + fcn->ST_CloseSession(sltp->TokData, apiSessp, FALSE); ++ END_OPENSSL_LIBCTX(rv) + free(apiSessp); + rv = CKR_HOST_MEMORY; + goto done; +@@ -3310,9 +3468,11 @@ CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SeedRandom) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SeedRandom(sltp->TokData, &rSession, pSeed, ulSeedLen); + TRACE_DEVEL("fcn->ST_SeedRandom returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3371,10 +3531,12 @@ CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SetAttributeValue) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SetAttributeValue(sltp->TokData, &rSession, + hObject, pTemplate, ulCount); + TRACE_DEVEL("fcn->ST_SetAttributeValue returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3426,12 +3588,14 @@ CK_RV C_SetOperationState(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SetOperationState) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SetOperationState(sltp->TokData, &rSession, + pOperationState, + ulOperationStateLen, + hEncryptionKey, hAuthenticationKey); + TRACE_DEVEL("fcn->ST_SetOperationState returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3486,10 +3650,12 @@ CK_RV C_SetPIN(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SetPIN) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SetPIN(sltp->TokData, &rSession, pOldPin, + ulOldLen, pNewPin, ulNewLen); + TRACE_DEVEL("fcn->ST_SetPIN returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3540,10 +3706,12 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Sign) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Sign(sltp->TokData, &rSession, pData, ulDataLen, + pSignature, pulSignatureLen); + TRACE_DEVEL("fcn->ST_Sign returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3590,11 +3758,13 @@ CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignEncryptUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignEncryptUpdate(sltp->TokData, &rSession, pPart, + ulPartLen, pEncryptedPart, + pulEncryptedPartLen); + TRACE_DEVEL("fcn->ST_SignEncryptUpdate return: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3642,10 +3812,12 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignFinal(sltp->TokData, &rSession, pSignature, + pulSignatureLen); + TRACE_DEVEL("fcn->ST_SignFinal returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3697,9 +3869,11 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignInit(sltp->TokData, &rSession, pMechanism, hKey); + TRACE_DEVEL("fcn->ST_SignInit returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3745,10 +3919,12 @@ CK_RV C_SignRecover(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignRecover) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignRecover(sltp->TokData, &rSession, pData, + ulDataLen, pSignature, pulSignatureLen); + TRACE_DEVEL("fcn->ST_SignRecover returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3796,10 +3972,12 @@ CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignRecoverInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignRecoverInit(sltp->TokData, &rSession, + pMechanism, hKey); + TRACE_DEVEL("fcn->ST_SignRecoverInit returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3847,9 +4025,11 @@ CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_SignUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_SignUpdate(sltp->TokData, &rSession, pPart, ulPartLen); + TRACE_DEVEL("fcn->ST_SignUpdate returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3910,12 +4090,14 @@ CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_UnwrapKey) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_UnwrapKey(sltp->TokData, &rSession, pMechanism, + hUnwrappingKey, pWrappedKey, + ulWrappedKeyLen, pTemplate, + ulAttributeCount, phKey); + TRACE_DEVEL("fcn->ST_UnwrapKey returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -3962,10 +4144,12 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_Verify) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_Verify(sltp->TokData, &rSession, pData, ulDataLen, + pSignature, ulSignatureLen); + TRACE_DEVEL("fcn->ST_Verify returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4009,10 +4193,12 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_VerifyFinal) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_VerifyFinal(sltp->TokData, &rSession, pSignature, + ulSignatureLen); + TRACE_DEVEL("fcn->ST_VerifyFinal returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4060,9 +4246,11 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_VerifyInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_VerifyInit(sltp->TokData, &rSession, pMechanism, hKey); + TRACE_DEVEL("fcn->ST_VerifyInit returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4109,10 +4297,12 @@ CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_VerifyRecover) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_VerifyRecover(sltp->TokData, &rSession, pSignature, + ulSignatureLen, pData, pulDataLen); + TRACE_DEVEL("fcn->ST_VerifyRecover returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4160,10 +4350,12 @@ CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_VerifyRecoverInit) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_VerifyRecoverInit(sltp->TokData, &rSession, + pMechanism, hKey); + TRACE_DEVEL("fcn->ST_VerifyRecoverInit returned:0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4207,9 +4399,11 @@ CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_VerifyUpdate) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_VerifyUpdate(sltp->TokData, &rSession, pPart, ulPartLen); + TRACE_DEVEL("fcn->ST_VerifyUpdate returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -4407,10 +4601,12 @@ CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_WrapKey) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_WrapKey(sltp->TokData, &rSession, pMechanism, + hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen); + TRACE_DEVEL("fcn->ST_WrapKey returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +@@ -5110,6 +5306,7 @@ CK_RV C_IBM_ReencryptSingle(CK_SESSION_HANDLE hSession, + return CKR_TOKEN_NOT_PRESENT; + } + if (fcn->ST_IBM_ReencryptSingle) { ++ BEGIN_OPENSSL_LIBCTX(Anchor->openssl_libctx, rv) + // Map the Session to the slot session + rv = fcn->ST_IBM_ReencryptSingle(sltp->TokData, &rSession, pDecrMech, + hDecrKey, pEncrMech, hEncrKey, +@@ -5117,6 +5314,7 @@ CK_RV C_IBM_ReencryptSingle(CK_SESSION_HANDLE hSession, + pReencryptedData, + pulReencryptedDataLen); + TRACE_DEVEL("fcn->ST_IBM_ReencryptSingle returned: 0x%lx\n", rv); ++ END_OPENSSL_LIBCTX(rv) + } else { + TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_NOT_SUPPORTED)); + rv = CKR_FUNCTION_NOT_SUPPORTED; +diff --git a/usr/lib/api/socket_client.c b/usr/lib/api/socket_client.c +index e344ddbf..423972a1 100644 +--- a/usr/lib/api/socket_client.c ++++ b/usr/lib/api/socket_client.c +@@ -245,11 +245,22 @@ static int handle_event(API_Proc_Struct_t *anchor, event_msg_t *event, + return 0; + } + ++struct cleanup_data { ++ API_Proc_Struct_t *anchor; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_LIB_CTX *prev_libctx; ++#endif ++}; ++ + static void event_thread_cleanup(void *arg) + { +- API_Proc_Struct_t *anchor = arg; ++ struct cleanup_data *cleanup = arg; + +- UNUSED(anchor); ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_LIB_CTX_set0_default(cleanup->prev_libctx); ++#else ++ UNUSED(cleanup); ++#endif + + TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); + } +@@ -257,6 +268,10 @@ static void event_thread_cleanup(void *arg) + static void *event_thread(void *arg) + { + API_Proc_Struct_t *anchor = arg; ++ struct cleanup_data cleanup; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_LIB_CTX *prev_libctx; ++#endif + int oldstate, oldtype; + struct pollfd pollfd; + event_msg_t event; +@@ -275,10 +290,24 @@ static void *event_thread(void *arg) + return NULL; + } + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ /* Ensure that the event thread uses Opencryptoki's own library context */ ++ prev_libctx = OSSL_LIB_CTX_set0_default(Anchor->openssl_libctx); ++ if (prev_libctx == NULL) { ++ TRACE_ERROR("OSSL_LIB_CTX_set0_default failed\n"); ++ TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); ++ return NULL; ++ } ++#endif ++ + /* Enable cancellation */ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); +- pthread_cleanup_push(event_thread_cleanup, anchor); ++ cleanup.anchor = anchor; ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ cleanup.prev_libctx = prev_libctx; ++#endif ++ pthread_cleanup_push(event_thread_cleanup, &cleanup); + + pollfd.fd = anchor->socketfd; + pollfd.events = POLLIN | POLLHUP | POLLERR; +@@ -395,6 +424,10 @@ static void *event_thread(void *arg) + close(anchor->socketfd); + anchor->socketfd = -1; + ++#if OPENSSL_VERSION_PREREQ(3, 0) ++ OSSL_LIB_CTX_set0_default(prev_libctx); ++#endif ++ + pthread_cleanup_pop(1); + return NULL; + } diff --git a/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch b/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch new file mode 100644 index 0000000..104a5f4 --- /dev/null +++ b/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch @@ -0,0 +1,870 @@ +commit 7b4177e8557887d196ce77a129d457e817f8cc59 +Author: Ingo Franzki +Date: Wed Jun 30 10:47:28 2021 +0200 + + TPM: Remove deprecated OpenSSL functions + + All low level RSA functions are deprecated in OpenSSL 3.0. + Update the code to not use any of those, and only use the EVP + interface. + + Also remove support for OpenSSL < v1.1.1. This code used even more + low level RSA, DES, and AES functions. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/tpm_stdll/tpm_openssl.c b/usr/lib/tpm_stdll/tpm_openssl.c +index 94ef9a62..0ccc543d 100644 +--- a/usr/lib/tpm_stdll/tpm_openssl.c ++++ b/usr/lib/tpm_stdll/tpm_openssl.c +@@ -39,50 +39,33 @@ + + #include "tpm_specific.h" + +-/* +- * In order to make opencryptoki compatible with +- * OpenSSL 1.1 API Changes and backward compatible +- * we need to check for its version +- */ +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +-#define OLDER_OPENSSL ++#if OPENSSL_VERSION_PREREQ(3, 0) ++#include + #endif + + #ifdef DEBUG + void openssl_print_errors() + { ++#if !OPENSSL_VERSION_PREREQ(3, 0) + ERR_load_ERR_strings(); ++#endif + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); + } + #endif + +-RSA *openssl_gen_key(STDLL_TokData_t *tokdata) ++EVP_PKEY *openssl_gen_key(STDLL_TokData_t *tokdata) + { +- RSA *rsa = NULL; + int rc = 0, counter = 0; + char buf[32]; +-#ifndef OLDER_OPENSSL + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + BIGNUM *bne = NULL; +-#endif + + token_specific_rng(tokdata, (CK_BYTE *) buf, 32); + RAND_seed(buf, 32); + + regen_rsa_key: +-#ifdef OLDER_OPENSSL +- rsa = RSA_generate_key(2048, 65537, NULL, NULL); +- if (rsa == NULL) { +- fprintf(stderr, "Error generating user's RSA key\n"); +- ERR_load_crypto_strings(); +- ERR_print_errors_fp(stderr); +- goto err; +- } +- +- rc = RSA_check_key(rsa); +-#else + bne = BN_new(); + rc = BN_set_word(bne, 65537); + if (!rc) { +@@ -98,35 +81,36 @@ regen_rsa_key: + + if (EVP_PKEY_keygen_init(ctx) <= 0 + || EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0 ++#if !OPENSSL_VERSION_PREREQ(3, 0) + || EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, bne) <= 0) { ++#else ++ || EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, bne) <= 0) { ++#endif + fprintf(stderr, "Error generating user's RSA key\n"); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); + goto err; + } ++#if !OPENSSL_VERSION_PREREQ(3, 0) + bne = NULL; // will be freed as part of the context +- if (EVP_PKEY_keygen(ctx, &pkey) <= 0 +- || (rsa = EVP_PKEY_get1_RSA(pkey)) == NULL) { ++#else ++ BN_free(bne); ++ bne = NULL; ++#endif ++ if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { + fprintf(stderr, "Error generating user's RSA key\n"); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); + goto err; + } +-#if OPENSSL_VERSION_NUMBER < 0x10101000L +- rc = RSA_check_key(rsa); +-#else + EVP_PKEY_CTX_free(ctx); + ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (ctx == NULL) + goto err; + rc = (EVP_PKEY_check(ctx) == 1 ? 1 : 0); +-#endif +-#endif + switch (rc) { + case 0: + /* rsa is not a valid RSA key */ +- RSA_free(rsa); +- rsa = NULL; + counter++; + if (counter == KEYGEN_RETRY) { + TRACE_DEVEL("Tried %d times to generate a " +@@ -145,30 +129,23 @@ regen_rsa_key: + break; + } + +-#ifndef OLDER_OPENSSL +- if (pkey != NULL) +- EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + if (bne != NULL) + BN_free(bne); +-#endif +- return rsa; ++ return pkey; + err: +- if (rsa != NULL) +- RSA_free(rsa); +-#ifndef OLDER_OPENSSL + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + if (bne != NULL) + BN_free(bne); +-#endif ++ + return NULL; + } + +-int openssl_write_key(STDLL_TokData_t * tokdata, RSA * rsa, char *filename, ++int openssl_write_key(STDLL_TokData_t * tokdata, EVP_PKEY *pkey, char *filename, + CK_BYTE * pPin) + { + BIO *b = NULL; +@@ -193,8 +170,8 @@ int openssl_write_key(STDLL_TokData_t * tokdata, RSA * rsa, char *filename, + return -1; + } + +- if (!PEM_write_bio_RSAPrivateKey(b, rsa, +- EVP_aes_256_cbc(), NULL, 0, 0, pPin)) { ++ if (!PEM_write_bio_PrivateKey(b, pkey, ++ EVP_aes_256_cbc(), NULL, 0, 0, pPin)) { + BIO_free(b); + TRACE_ERROR("Writing key %s to disk failed.\n", loc); + DEBUG_openssl_print_errors(); +@@ -211,10 +188,10 @@ int openssl_write_key(STDLL_TokData_t * tokdata, RSA * rsa, char *filename, + } + + CK_RV openssl_read_key(STDLL_TokData_t * tokdata, char *filename, +- CK_BYTE * pPin, RSA ** ret) ++ CK_BYTE * pPin, EVP_PKEY **ret) + { + BIO *b = NULL; +- RSA *rsa = NULL; ++ EVP_PKEY *pkey = NULL; + char loc[PATH_MAX]; + struct passwd *pw = NULL; + CK_RV rc = CKR_FUNCTION_FAILED; +@@ -242,7 +219,7 @@ CK_RV openssl_read_key(STDLL_TokData_t * tokdata, char *filename, + return CKR_FILE_NOT_FOUND; + } + +- if ((rsa = PEM_read_bio_RSAPrivateKey(b, NULL, 0, pPin)) == NULL) { ++ if ((pkey = PEM_read_bio_PrivateKey(b, NULL, 0, pPin)) == NULL) { + TRACE_ERROR("Reading key %s from disk failed.\n", loc); + DEBUG_openssl_print_errors(); + if (ERR_GET_REASON(ERR_get_error()) == PEM_R_BAD_DECRYPT) { +@@ -253,40 +230,54 @@ CK_RV openssl_read_key(STDLL_TokData_t * tokdata, char *filename, + } + + BIO_free(b); +- *ret = rsa; ++ *ret = pkey; + + return CKR_OK; + } + +-int openssl_get_modulus_and_prime(RSA * rsa, unsigned int *size_n, ++int openssl_get_modulus_and_prime(EVP_PKEY *pkey, unsigned int *size_n, + unsigned char *n, unsigned int *size_p, + unsigned char *p) + { +-#ifndef OLDER_OPENSSL ++#if !OPENSSL_VERSION_PREREQ(3, 0) + const BIGNUM *n_tmp, *p_tmp; ++ RSA *rsa; ++#else ++ BIGNUM *n_tmp, *p_tmp; + #endif + ++#if !OPENSSL_VERSION_PREREQ(3, 0) ++ rsa = EVP_PKEY_get0_RSA(pkey); + /* get the modulus from the RSA object */ +-#ifdef OLDER_OPENSSL +- if ((*size_n = BN_bn2bin(rsa->n, n)) <= 0) { +-#else + RSA_get0_key(rsa, &n_tmp, NULL, NULL); + if ((*size_n = BN_bn2bin(n_tmp, n)) <= 0) { +-#endif + DEBUG_openssl_print_errors(); + return -1; + } + + /* get one of the primes from the RSA object */ +-#ifdef OLDER_OPENSSL +- if ((*size_p = BN_bn2bin(rsa->p, p)) <= 0) { +-#else + RSA_get0_factors(rsa, &p_tmp, NULL); + if ((*size_p = BN_bn2bin(p_tmp, p)) <= 0) { +-#endif + DEBUG_openssl_print_errors(); + return -1; + } ++#else ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &n_tmp) || ++ (*size_n = BN_bn2bin(n_tmp, n)) <= 0) { ++ DEBUG_openssl_print_errors(); ++ BN_free(n_tmp); ++ return -1; ++ } ++ BN_free(n_tmp); ++ ++ if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &p_tmp) || ++ (*size_p = BN_bn2bin(p_tmp, p)) <= 0) { ++ DEBUG_openssl_print_errors(); ++ BN_free(p_tmp); ++ return -1; ++ } ++ BN_free(p_tmp); ++#endif + + return 0; + } +diff --git a/usr/lib/tpm_stdll/tpm_specific.c b/usr/lib/tpm_stdll/tpm_specific.c +index 4ebb4a88..45bc4b78 100644 +--- a/usr/lib/tpm_stdll/tpm_specific.c ++++ b/usr/lib/tpm_stdll/tpm_specific.c +@@ -1451,15 +1451,15 @@ CK_RV token_create_private_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, + tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data; + CK_RV rc; + TSS_RESULT result; +- RSA *rsa; ++ EVP_PKEY *pkey; + unsigned int size_n, size_p; + unsigned char n[256], p[256]; + + /* all sw generated keys are 2048 bits */ +- if ((rsa = openssl_gen_key(tokdata)) == NULL) ++ if ((pkey = openssl_gen_key(tokdata)) == NULL) + return CKR_HOST_MEMORY; + +- if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { ++ if (openssl_get_modulus_and_prime(pkey, &size_n, n, &size_p, p) != 0) { + TRACE_DEVEL("openssl_get_modulus_and_prime failed\n"); + return CKR_FUNCTION_FAILED; + } +@@ -1473,13 +1473,13 @@ CK_RV token_create_private_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, + return rc; + } + +- if (openssl_write_key(tokdata, rsa, TPMTOK_PRIV_ROOT_KEY_FILE, pPin)) { ++ if (openssl_write_key(tokdata, pkey, TPMTOK_PRIV_ROOT_KEY_FILE, pPin)) { + TRACE_DEVEL("openssl_write_key failed.\n"); +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + return CKR_FUNCTION_FAILED; + } + +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + + /* store the user base key in a PKCS#11 object internally */ + rc = token_store_tss_key(tokdata, tpm_data->hPrivateRootKey, +@@ -1529,15 +1529,15 @@ CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, + tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data; + CK_RV rc; + TSS_RESULT result; +- RSA *rsa; ++ EVP_PKEY *pkey; + unsigned int size_n, size_p; + unsigned char n[256], p[256]; + + /* all sw generated keys are 2048 bits */ +- if ((rsa = openssl_gen_key(tokdata)) == NULL) ++ if ((pkey = openssl_gen_key(tokdata)) == NULL) + return CKR_HOST_MEMORY; + +- if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { ++ if (openssl_get_modulus_and_prime(pkey, &size_n, n, &size_p, p) != 0) { + TRACE_DEVEL("openssl_get_modulus_and_prime failed\n"); + return CKR_FUNCTION_FAILED; + } +@@ -1551,13 +1551,13 @@ CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, + return rc; + } + +- if (openssl_write_key(tokdata, rsa, TPMTOK_PUB_ROOT_KEY_FILE, pPin)) { ++ if (openssl_write_key(tokdata, pkey, TPMTOK_PUB_ROOT_KEY_FILE, pPin)) { + TRACE_DEVEL("openssl_write_key\n"); +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + return CKR_FUNCTION_FAILED; + } + +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + + result = Tspi_Key_LoadKey(tpm_data->hPublicRootKey, tpm_data->hSRK); + if (result) { +@@ -1602,7 +1602,7 @@ CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash, + CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin) + { + tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data; +- RSA *rsa; ++ EVP_PKEY *pkey; + char *backup_loc; + unsigned int size_n, size_p; + unsigned char n[256], p[256]; +@@ -1630,7 +1630,7 @@ CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin) + } + + /* read the backup key with the old pin */ +- if ((rc = openssl_read_key(tokdata, backup_loc, pin, &rsa))) { ++ if ((rc = openssl_read_key(tokdata, backup_loc, pin, &pkey))) { + if (rc == CKR_FILE_NOT_FOUND) + rc = CKR_FUNCTION_FAILED; + TRACE_DEVEL("openssl_read_key failed\n"); +@@ -1640,8 +1640,9 @@ CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin) + /* So, reading the backup openssl key off disk succeeded with the SOs PIN. + * We will now try to re-wrap that key with the current SRK + */ +- if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) { ++ if (openssl_get_modulus_and_prime(pkey, &size_n, n, &size_p, p) != 0) { + TRACE_DEVEL("openssl_get_modulus_and_prime failed\n"); ++ EVP_PKEY_free(pkey); + return CKR_FUNCTION_FAILED; + } + +@@ -1650,10 +1651,10 @@ CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin) + phKey); + if (rc != CKR_OK) { + TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lx\n", rc); +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + return rc; + } +- RSA_free(rsa); ++ EVP_PKEY_free(pkey); + + result = Tspi_Key_LoadKey(*phKey, tpm_data->hSRK); + if (result) { +@@ -1998,7 +1999,7 @@ CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess, + tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data; + CK_BYTE oldpin_hash[SHA1_HASH_SIZE], newpin_hash[SHA1_HASH_SIZE]; + CK_RV rc; +- RSA *rsa_root; ++ EVP_PKEY *pkey_root; + TSS_RESULT result; + + if (!sess) { +@@ -2094,7 +2095,7 @@ CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess, + + /* read the backup key with the old pin */ + rc = openssl_read_key(tokdata, TPMTOK_PRIV_ROOT_KEY_FILE, pOldPin, +- &rsa_root); ++ &pkey_root); + if (rc != CKR_OK) { + if (rc == CKR_FILE_NOT_FOUND) { + /* If the user has moved his backup PEM file off site, allow a +@@ -2107,14 +2108,14 @@ CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess, + } + + /* write it out using the new pin */ +- rc = openssl_write_key(tokdata, rsa_root, TPMTOK_PRIV_ROOT_KEY_FILE, ++ rc = openssl_write_key(tokdata, pkey_root, TPMTOK_PRIV_ROOT_KEY_FILE, + pNewPin); + if (rc != CKR_OK) { +- RSA_free(rsa_root); ++ EVP_PKEY_free(pkey_root); + TRACE_DEVEL("openssl_write_key failed\n"); + return CKR_FUNCTION_FAILED; + } +- RSA_free(rsa_root); ++ EVP_PKEY_free(pkey_root); + } else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) { + if (tpm_data->not_initialized) { + if (memcmp(default_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) { +@@ -2166,7 +2167,7 @@ CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess, + + /* change auth on the public root key's openssl backup */ + rc = openssl_read_key(tokdata, TPMTOK_PUB_ROOT_KEY_FILE, pOldPin, +- &rsa_root); ++ &pkey_root); + if (rc != CKR_OK) { + if (rc == CKR_FILE_NOT_FOUND) { + /* If the user has moved his backup PEM file off site, allow a +@@ -2179,14 +2180,14 @@ CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess, + } + + /* write it out using the new pin */ +- rc = openssl_write_key(tokdata, rsa_root, TPMTOK_PUB_ROOT_KEY_FILE, ++ rc = openssl_write_key(tokdata, pkey_root, TPMTOK_PUB_ROOT_KEY_FILE, + pNewPin); + if (rc != CKR_OK) { +- RSA_free(rsa_root); ++ EVP_PKEY_free(pkey_root); + TRACE_DEVEL("openssl_write_key failed\n"); + return CKR_FUNCTION_FAILED; + } +- RSA_free(rsa_root); ++ EVP_PKEY_free(pkey_root); + } else { + TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_ONLY)); + rc = CKR_SESSION_READ_ONLY; +@@ -2401,60 +2402,6 @@ CK_RV token_specific_des_ecb(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- CK_ATTRIBUTE *attr = NULL; +- +- DES_key_schedule des_key2; +- const_DES_cblock key_val_SSL, in_key_data; +- DES_cblock out_key_data; +- unsigned int i, j; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- +- // Create the key schedule +- memcpy(&key_val_SSL, attr->pValue, 8); +- DES_set_key_unchecked(&key_val_SSL, &des_key2); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // Both the encrypt and the decrypt are done 8 bytes at a time +- if (encrypt) { +- for (i = 0; i < in_data_len; i = i + 8) { +- memcpy(in_key_data, in_data + i, 8); +- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2, +- DES_ENCRYPT); +- memcpy(out_data + i, out_key_data, 8); +- } +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- +- for (j = 0; j < in_data_len; j = j + 8) { +- memcpy(in_key_data, in_data + j, 8); +- DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2, +- DES_DECRYPT); +- memcpy(out_data + j, out_key_data, 8); +- } +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ecb(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -2501,7 +2448,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_des_cbc(STDLL_TokData_t * tokdata, +@@ -2511,50 +2457,6 @@ CK_RV token_specific_des_cbc(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- CK_ATTRIBUTE *attr = NULL; +- +- DES_cblock ivec; +- +- DES_key_schedule des_key2; +- const_DES_cblock key_val_SSL; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- +- // Create the key schedule +- memcpy(&key_val_SSL, attr->pValue, 8); +- DES_set_key_unchecked(&key_val_SSL, &des_key2); +- +- memcpy(&ivec, init_v, 8); +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- +- +- if (encrypt) { +- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec, +- DES_ENCRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec, +- DES_DECRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_cbc(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -2601,7 +2503,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_tdes_ecb(STDLL_TokData_t * tokdata, +@@ -2611,83 +2512,6 @@ CK_RV token_specific_tdes_ecb(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc; +- CK_ATTRIBUTE *attr = NULL; +- CK_KEY_TYPE keytype; +- CK_BYTE key_value[3 * DES_KEY_SIZE]; +- +- unsigned int k, j; +- DES_key_schedule des_key1; +- DES_key_schedule des_key2; +- DES_key_schedule des_key3; +- +- const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data; +- DES_cblock out_key_data; +- +- UNUSED(tokdata); +- +- // get the key type +- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n"); +- return rc; +- } +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- +- if (keytype == CKK_DES2) { +- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE); +- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE); +- } else { +- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE); +- } +- +- // The key as passed is a 24 byte long string containing three des keys +- // pick them apart and create the 3 corresponding key schedules +- memcpy(&key_SSL1, key_value, 8); +- memcpy(&key_SSL2, key_value + 8, 8); +- memcpy(&key_SSL3, key_value + 16, 8); +- DES_set_key_unchecked(&key_SSL1, &des_key1); +- DES_set_key_unchecked(&key_SSL2, &des_key2); +- DES_set_key_unchecked(&key_SSL3, &des_key3); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // the encrypt and decrypt are done 8 bytes at a time +- if (encrypt) { +- for (k = 0; k < in_data_len; k = k + 8) { +- memcpy(in_key_data, in_data + k, 8); +- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data, +- (DES_cblock *) & out_key_data, +- &des_key1, &des_key2, &des_key3, DES_ENCRYPT); +- memcpy(out_data + k, out_key_data, 8); +- } +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- for (j = 0; j < in_data_len; j = j + 8) { +- memcpy(in_key_data, in_data + j, 8); +- DES_ecb3_encrypt((const_DES_cblock *) & in_key_data, +- (DES_cblock *) & out_key_data, +- &des_key1, &des_key2, &des_key3, DES_DECRYPT); +- memcpy(out_data + j, out_key_data, 8); +- } +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ede3_ecb(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -2747,7 +2571,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_tdes_cbc(STDLL_TokData_t * tokdata, +@@ -2757,81 +2580,6 @@ CK_RV token_specific_tdes_cbc(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_RV rc = CKR_OK; +- CK_ATTRIBUTE *attr = NULL; +- CK_KEY_TYPE keytype; +- CK_BYTE key_value[3 * DES_KEY_SIZE]; +- +- DES_key_schedule des_key1; +- DES_key_schedule des_key2; +- DES_key_schedule des_key3; +- +- const_DES_cblock key_SSL1, key_SSL2, key_SSL3; +- DES_cblock ivec; +- +- UNUSED(tokdata); +- +- // get the key type +- rc = template_attribute_get_ulong(key->template, CKA_KEY_TYPE, &keytype); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_KEY_TYPE for the key\n"); +- return rc; +- } +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key\n"); +- return rc; +- } +- +- if (keytype == CKK_DES2) { +- memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE); +- memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE); +- } else { +- memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE); +- } +- +- // The key as passed in is a 24 byte string containing 3 keys +- // pick it apart and create the key schedules +- memcpy(&key_SSL1, key_value, 8); +- memcpy(&key_SSL2, key_value + 8, 8); +- memcpy(&key_SSL3, key_value + 16, 8); +- DES_set_key_unchecked(&key_SSL1, &des_key1); +- DES_set_key_unchecked(&key_SSL2, &des_key2); +- DES_set_key_unchecked(&key_SSL3, &des_key3); +- +- memcpy(ivec, init_v, sizeof(ivec)); +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by 8 +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // Encrypt or decrypt the data +- if (encrypt) { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_ENCRYPT); +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } else { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_DECRYPT); +- +- *out_data_len = in_data_len; +- rc = CKR_OK; +- } +- +- return rc; +-#else + const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); + EVP_CIPHER_CTX *ctx = NULL; + CK_ATTRIBUTE *attr = NULL; +@@ -2891,7 +2639,6 @@ done: + OPENSSL_cleanse(dkey, sizeof(dkey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + /* wrap the 20 bytes of auth data @authData and store in an attribute of the two +@@ -3626,49 +3373,6 @@ CK_RV token_specific_aes_ecb(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- CK_ATTRIBUTE *attr = NULL; +- AES_KEY ssl_aes_key; +- unsigned int i; +- /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, +- * so this is fine */ +- CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE); +- CK_RV rc; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- +- memset(&ssl_aes_key, 0, sizeof(AES_KEY)); +- +- // AES_ecb_encrypt encrypts only a single block, so we have to break up the +- // input data here +- if (encrypt) { +- AES_set_encrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- for (i = 0; i < loops; i++) { +- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE), +- (unsigned char *) out_data + (i * AES_BLOCK_SIZE), +- &ssl_aes_key, AES_ENCRYPT); +- } +- } else { +- AES_set_decrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- for (i = 0; i < loops; i++) { +- AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE), +- (unsigned char *) out_data + (i * AES_BLOCK_SIZE), +- &ssl_aes_key, AES_DECRYPT); +- } +- } +- *out_data_len = in_data_len; +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + unsigned char akey[AES_KEY_SIZE_256]; +@@ -3729,7 +3433,6 @@ done: + OPENSSL_cleanse(akey, sizeof(akey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_aes_cbc(STDLL_TokData_t * tokdata, +@@ -3739,39 +3442,6 @@ CK_RV token_specific_aes_cbc(STDLL_TokData_t * tokdata, + CK_ULONG * out_data_len, + OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- AES_KEY ssl_aes_key; +- CK_ATTRIBUTE *attr = NULL; +- CK_RV rc; +- +- UNUSED(tokdata); +- +- // get the key value +- rc = template_attribute_get_non_empty(key->template, CKA_VALUE, &attr); +- if (rc != CKR_OK) { +- TRACE_ERROR("Could not find CKA_VALUE for the key.\n"); +- return rc; +- } +- +- memset(&ssl_aes_key, 0, sizeof(AES_KEY)); +- +- // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike +- // AES_ecb_encrypt, so no looping required. +- if (encrypt) { +- AES_set_encrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data, +- in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT); +- } else { +- AES_set_decrypt_key((unsigned char *) attr->pValue, +- (attr->ulValueLen * 8), &ssl_aes_key); +- AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data, +- in_data_len, &ssl_aes_key, init_v, AES_DECRYPT); +- } +- *out_data_len = in_data_len; +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + unsigned char akey[AES_KEY_SIZE_256]; +@@ -3832,7 +3502,6 @@ done: + OPENSSL_cleanse(akey, sizeof(akey)); + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV token_specific_get_mechanism_list(STDLL_TokData_t * tokdata, +diff --git a/usr/lib/tpm_stdll/tpm_specific.h b/usr/lib/tpm_stdll/tpm_specific.h +index 81af2744..2ffd0afc 100644 +--- a/usr/lib/tpm_stdll/tpm_specific.h ++++ b/usr/lib/tpm_stdll/tpm_specific.h +@@ -56,10 +56,10 @@ + /* retry count for generating software RSA keys */ + #define KEYGEN_RETRY 5 + +-RSA *openssl_gen_key(STDLL_TokData_t *); +-int openssl_write_key(STDLL_TokData_t *, RSA *, char *, CK_BYTE *); +-CK_RV openssl_read_key(STDLL_TokData_t *, char *, CK_BYTE *, RSA **); +-int openssl_get_modulus_and_prime(RSA *, unsigned int *, unsigned char *, ++EVP_PKEY *openssl_gen_key(STDLL_TokData_t *); ++int openssl_write_key(STDLL_TokData_t *, EVP_PKEY *, char *, CK_BYTE *); ++CK_RV openssl_read_key(STDLL_TokData_t *, char *, CK_BYTE *, EVP_PKEY **); ++int openssl_get_modulus_and_prime(EVP_PKEY *, unsigned int *, unsigned char *, + unsigned int *, unsigned char *); + int util_set_file_mode(char *, mode_t); + CK_BYTE *util_create_id(int); diff --git a/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch b/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch new file mode 100644 index 0000000..a9d436e --- /dev/null +++ b/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch @@ -0,0 +1,1847 @@ +commit 93588f53d918fe6c7452da076b95081fb6aa9aef +Author: Ingo Franzki +Date: Wed Jun 30 13:18:39 2021 +0200 + + COMMON: Prevent unsavable operation state to be exported + + Tokens using OpenSSL 3.0 to implement digest operations (SHA, MD5) are no + longer able to store its digest state in the session context in a way + that it could be exported via C_GetOperationState(). OpenSSL 3.0 does not + provide support to get the digest state. A token must therefore place + pointers to OpenSSL digest contexts into the session state structure. + Such a state can not be externalized through C_GetOperationState(). + + Also see the discussion in OpenSSL issue "Digest State Serialization": + https://github.com/openssl/openssl/issues/14222 + + Allow a token to mark an operation context as 'not saveable', which will + cause C_GetOperationState() to return CKR_STATE_UNSAVEABLE if it is tried + to save such a state. + + Also, such operation contexts can not simply be freed that way the common + code performs that. Allow a token to use a custom context free function, + to cleanup such complex context structures. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/decr_mgr.c b/usr/lib/common/decr_mgr.c +index 9842302b..fea6c99e 100644 +--- a/usr/lib/common/decr_mgr.c ++++ b/usr/lib/common/decr_mgr.c +@@ -620,7 +620,8 @@ done: + + // + // +-CK_RV decr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) ++CK_RV decr_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ ENCR_DECR_CONTEXT *ctx) + { + if (!ctx) { + TRACE_ERROR("Invalid function argument.\n"); +@@ -635,6 +636,7 @@ CK_RV decr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) + ctx->init_pending = FALSE; + ctx->context_len = 0; + ctx->pkey_active = FALSE; ++ ctx->state_unsaveable = FALSE; + + if (ctx->mech.pParameter) { + free(ctx->mech.pParameter); +@@ -642,9 +644,14 @@ CK_RV decr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) + } + + if (ctx->context) { +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(tokdata, sess, ctx->context, ++ ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + } ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +diff --git a/usr/lib/common/dig_mgr.c b/usr/lib/common/dig_mgr.c +index 77cb60a1..222eee75 100644 +--- a/usr/lib/common/dig_mgr.c ++++ b/usr/lib/common/dig_mgr.c +@@ -63,7 +63,7 @@ CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + ctx->context = NULL; + rc = sha_init(tokdata, sess, ctx, mech); + if (rc != CKR_OK) { +- digest_mgr_cleanup(ctx); // to de-initialize context above ++ digest_mgr_cleanup(tokdata, sess, ctx); // to de-initialize context above + TRACE_ERROR("Failed to init sha context.\n"); + return rc; + } +@@ -76,7 +76,7 @@ CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + ctx->context_len = sizeof(MD2_CONTEXT); + ctx->context = (CK_BYTE *) malloc(sizeof(MD2_CONTEXT)); + if (!ctx->context) { +- digest_mgr_cleanup(ctx); // to de-initialize context above ++ digest_mgr_cleanup(tokdata, sess, ctx); // to de-initialize context above + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); + return CKR_HOST_MEMORY; + } +@@ -90,7 +90,7 @@ CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + ctx->context = NULL; + rc = md5_init(tokdata, sess, ctx, mech); + if (rc != CKR_OK) { +- digest_mgr_cleanup(ctx); // to de-initialize context above ++ digest_mgr_cleanup(tokdata, sess, ctx); // to de-initialize context above + TRACE_ERROR("Failed to init md5 context.\n"); + return rc; + } +@@ -103,7 +103,7 @@ CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + if (mech->ulParameterLen > 0 && mech->pParameter != NULL) { + ptr = (CK_BYTE *) malloc(mech->ulParameterLen); + if (!ptr) { +- digest_mgr_cleanup(ctx); // to de-initialize context above ++ digest_mgr_cleanup(tokdata, sess, ctx); // to de-initialize context above + TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); + return CKR_HOST_MEMORY; + } +@@ -122,7 +122,8 @@ CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + + // + // +-CK_RV digest_mgr_cleanup(DIGEST_CONTEXT *ctx) ++CK_RV digest_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ DIGEST_CONTEXT *ctx) + { + if (!ctx) { + TRACE_ERROR("Invalid function argument.\n"); +@@ -134,6 +135,7 @@ CK_RV digest_mgr_cleanup(DIGEST_CONTEXT *ctx) + ctx->multi = FALSE; + ctx->active = FALSE; + ctx->context_len = 0; ++ ctx->state_unsaveable = FALSE; + + if (ctx->mech.pParameter) { + free(ctx->mech.pParameter); +@@ -141,9 +143,14 @@ CK_RV digest_mgr_cleanup(DIGEST_CONTEXT *ctx) + } + + if (ctx->context != NULL) { +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(tokdata, sess, ctx->context, ++ ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + } ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +@@ -232,7 +239,7 @@ out: + // unless it returns CKR_BUFFER_TOO_SMALL or is a successful call (i.e., + // one which returns CKR_OK) to determine the length of the buffer + // needed to hold the message digest." +- digest_mgr_cleanup(ctx); ++ digest_mgr_cleanup(tokdata, sess, ctx); + } + + return rc; +@@ -301,7 +308,7 @@ CK_RV digest_mgr_digest_update(STDLL_TokData_t *tokdata, + + out: + if (rc != CKR_OK) { +- digest_mgr_cleanup(ctx); ++ digest_mgr_cleanup(tokdata, sess, ctx); + // "A call to C_DigestUpdate which results in an error + // terminates the current digest operation." + } +@@ -373,7 +380,7 @@ CK_RV digest_mgr_digest_key(STDLL_TokData_t *tokdata, + + out: + if (rc != CKR_OK) { +- digest_mgr_cleanup(ctx); ++ digest_mgr_cleanup(tokdata, sess, ctx); + } + + object_put(tokdata, key_obj, TRUE); +@@ -451,7 +458,7 @@ out: + // operation unless it returns CKR_BUFFER_TOO_SMALL or is a successful + // call (i.e., one which returns CKR_OK) to determine the length of the + // buffer needed to hold the message digest." +- digest_mgr_cleanup(ctx); ++ digest_mgr_cleanup(tokdata, sess, ctx); + } + + return rc; +diff --git a/usr/lib/common/encr_mgr.c b/usr/lib/common/encr_mgr.c +index 3e85ceab..7f7dfbae 100644 +--- a/usr/lib/common/encr_mgr.c ++++ b/usr/lib/common/encr_mgr.c +@@ -617,7 +617,8 @@ done: + + // + // +-CK_RV encr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) ++CK_RV encr_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ ENCR_DECR_CONTEXT *ctx) + { + if (!ctx) { + TRACE_ERROR("Invalid function argument.\n"); +@@ -632,6 +633,7 @@ CK_RV encr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) + ctx->init_pending = FALSE; + ctx->context_len = 0; + ctx->pkey_active = FALSE; ++ ctx->state_unsaveable = FALSE; + + if (ctx->mech.pParameter) { + free(ctx->mech.pParameter); +@@ -639,9 +641,14 @@ CK_RV encr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx) + } + + if (ctx->context) { +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(tokdata, sess, ctx->context, ++ ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + } ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +@@ -1204,8 +1211,8 @@ done: + free(decr_data); + } + +- decr_mgr_cleanup(decr_ctx); +- encr_mgr_cleanup(encr_ctx); ++ decr_mgr_cleanup(tokdata, sess, decr_ctx); ++ encr_mgr_cleanup(tokdata, sess, encr_ctx); + + return rc; + } +diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h +index 5e251d95..47b96ba0 100644 +--- a/usr/lib/common/h_extern.h ++++ b/usr/lib/common/h_extern.h +@@ -1790,7 +1790,8 @@ CK_RV encr_mgr_init(STDLL_TokData_t *tokdata, + CK_ULONG operation, + CK_MECHANISM *mech, CK_OBJECT_HANDLE key_handle); + +-CK_RV encr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx); ++CK_RV encr_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ ENCR_DECR_CONTEXT *ctx); + + CK_RV encr_mgr_encrypt(STDLL_TokData_t *tokdata, + SESSION *sess, CK_BBOOL length_only, +@@ -1825,7 +1826,8 @@ CK_RV decr_mgr_init(STDLL_TokData_t *tokdata, + CK_ULONG operation, + CK_MECHANISM *mech, CK_OBJECT_HANDLE key_handle); + +-CK_RV decr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx); ++CK_RV decr_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ ENCR_DECR_CONTEXT *ctx); + + CK_RV decr_mgr_decrypt(STDLL_TokData_t *tokdata, + SESSION *sess, CK_BBOOL length_only, +@@ -1866,7 +1868,8 @@ CK_RV decr_mgr_update_des3_cbc(STDLL_TokData_t *tokdata, SESSION *sess, + + // digest manager routines + // +-CK_RV digest_mgr_cleanup(DIGEST_CONTEXT *ctx); ++CK_RV digest_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ DIGEST_CONTEXT *ctx); + + CK_RV digest_mgr_init(STDLL_TokData_t *tokdata, + SESSION *sess, +@@ -1955,7 +1958,8 @@ CK_RV sign_mgr_init(STDLL_TokData_t *tokdata, + CK_MECHANISM *mech, + CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle); + +-CK_RV sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx); ++CK_RV sign_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ SIGN_VERIFY_CONTEXT *ctx); + + CK_RV sign_mgr_sign(STDLL_TokData_t *tokdata, + SESSION *sess, +@@ -1992,7 +1996,8 @@ CK_RV verify_mgr_init(STDLL_TokData_t *tokdata, + CK_MECHANISM *mech, + CK_BBOOL recover_mode, CK_OBJECT_HANDLE key_handle); + +-CK_RV verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx); ++CK_RV verify_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ SIGN_VERIFY_CONTEXT *ctx); + + CK_RV verify_mgr_verify(STDLL_TokData_t *tokdata, + SESSION *sess, +@@ -2036,10 +2041,11 @@ CK_BBOOL session_mgr_so_session_exists(STDLL_TokData_t *tokdata); + CK_BBOOL session_mgr_user_session_exists(STDLL_TokData_t *tokdata); + CK_BBOOL session_mgr_public_session_exists(STDLL_TokData_t *tokdata); + +-CK_RV session_mgr_get_op_state(SESSION *sess, CK_BBOOL length_only, ++CK_RV session_mgr_get_op_state(SESSION *sess, ++ CK_BBOOL length_only, + CK_BYTE *data, CK_ULONG *data_len); + +-CK_RV session_mgr_set_op_state(SESSION *sess, ++CK_RV session_mgr_set_op_state(STDLL_TokData_t *tokdata, SESSION *sess, + CK_OBJECT_HANDLE encr_key, + CK_OBJECT_HANDLE auth_key, CK_BYTE *data, + CK_ULONG data_len); +diff --git a/usr/lib/common/host_defs.h b/usr/lib/common/host_defs.h +index c0b5c83d..41fdb657 100644 +--- a/usr/lib/common/host_defs.h ++++ b/usr/lib/common/host_defs.h +@@ -21,27 +21,36 @@ + + #include "local_types.h" + ++struct _SESSION; ++ ++typedef void (*context_free_func_t)(STDLL_TokData_t *tokdata, struct _SESSION *sess, ++ CK_BYTE *context, CK_ULONG context_len); ++ + typedef struct _ENCR_DECR_CONTEXT { + CK_OBJECT_HANDLE key; + CK_MECHANISM mech; + CK_BYTE *context; + CK_ULONG context_len; ++ context_free_func_t context_free_func; + CK_BBOOL multi; + CK_BBOOL active; + CK_BBOOL init_pending; // indicate init request pending + CK_BBOOL multi_init; // multi field is initialized + // on first call *after* init + CK_BBOOL pkey_active; ++ CK_BBOOL state_unsaveable; + } ENCR_DECR_CONTEXT; + + typedef struct _DIGEST_CONTEXT { + CK_MECHANISM mech; + CK_BYTE *context; + CK_ULONG context_len; ++ context_free_func_t context_free_func; + CK_BBOOL multi; + CK_BBOOL active; + CK_BBOOL multi_init; // multi field is initialized + // on first call *after* init ++ CK_BBOOL state_unsaveable; + } DIGEST_CONTEXT; + + typedef struct _SIGN_VERIFY_CONTEXT { +@@ -49,6 +58,7 @@ typedef struct _SIGN_VERIFY_CONTEXT { + CK_MECHANISM mech; // current sign mechanism + CK_BYTE *context; // temporary work area + CK_ULONG context_len; ++ context_free_func_t context_free_func; + CK_BBOOL multi; // is this a multi-part operation? + CK_BBOOL recover; // are we in recover mode? + CK_BBOOL active; +@@ -56,6 +66,7 @@ typedef struct _SIGN_VERIFY_CONTEXT { + CK_BBOOL multi_init; // multi field is initialized + // on first call *after* init + CK_BBOOL pkey_active; ++ CK_BBOOL state_unsaveable; + } SIGN_VERIFY_CONTEXT; + + +diff --git a/usr/lib/common/key_mgr.c b/usr/lib/common/key_mgr.c +index d9cd1f2f..aea74b7c 100644 +--- a/usr/lib/common/key_mgr.c ++++ b/usr/lib/common/key_mgr.c +@@ -1011,7 +1011,7 @@ CK_RV key_mgr_wrap_key(STDLL_TokData_t *tokdata, + OPENSSL_cleanse(data, data_len); + free(data); + } +- encr_mgr_cleanup(ctx); ++ encr_mgr_cleanup(tokdata, sess, ctx); + free(ctx); + + done: +@@ -1259,7 +1259,7 @@ CK_RV key_mgr_unwrap_key(STDLL_TokData_t *tokdata, + FALSE, + ctx, wrapped_key, wrapped_key_len, data, &data_len); + +- decr_mgr_cleanup(ctx); ++ decr_mgr_cleanup(tokdata, sess, ctx); + free(ctx); + ctx = NULL; + +@@ -1345,7 +1345,7 @@ done: + free(data); + } + if (ctx != NULL) { +- decr_mgr_cleanup(ctx); ++ decr_mgr_cleanup(tokdata, sess, ctx); + free(ctx); + } + +diff --git a/usr/lib/common/lock_sess_mgr.c b/usr/lib/common/lock_sess_mgr.c +index 0c7dbedf..0609a6c9 100644 +--- a/usr/lib/common/lock_sess_mgr.c ++++ b/usr/lib/common/lock_sess_mgr.c +@@ -276,32 +276,62 @@ CK_RV session_mgr_close_session(STDLL_TokData_t *tokdata, + if (sess->find_list) + free(sess->find_list); + +- if (sess->encr_ctx.context) +- free(sess->encr_ctx.context); ++ if (sess->encr_ctx.context) { ++ if (sess->encr_ctx.context_free_func != NULL) ++ sess->encr_ctx.context_free_func(tokdata, sess, ++ sess->encr_ctx.context, ++ sess->encr_ctx.context_len); ++ else ++ free(sess->encr_ctx.context); ++ } + + if (sess->encr_ctx.mech.pParameter) + free(sess->encr_ctx.mech.pParameter); + +- if (sess->decr_ctx.context) +- free(sess->decr_ctx.context); ++ if (sess->decr_ctx.context) { ++ if (sess->decr_ctx.context_free_func != NULL) ++ sess->decr_ctx.context_free_func(tokdata, sess, ++ sess->decr_ctx.context, ++ sess->decr_ctx.context_len); ++ else ++ free(sess->decr_ctx.context); ++ } + + if (sess->decr_ctx.mech.pParameter) + free(sess->decr_ctx.mech.pParameter); + +- if (sess->digest_ctx.context) +- free(sess->digest_ctx.context); ++ if (sess->digest_ctx.context) { ++ if (sess->digest_ctx.context_free_func != NULL) ++ sess->digest_ctx.context_free_func(tokdata, sess, ++ sess->digest_ctx.context, ++ sess->digest_ctx.context_len); ++ else ++ free(sess->digest_ctx.context); ++ } + + if (sess->digest_ctx.mech.pParameter) + free(sess->digest_ctx.mech.pParameter); + +- if (sess->sign_ctx.context) +- free(sess->sign_ctx.context); ++ if (sess->sign_ctx.context) { ++ if (sess->sign_ctx.context_free_func != NULL) ++ sess->sign_ctx.context_free_func(tokdata, sess, ++ sess->sign_ctx.context, ++ sess->sign_ctx.context_len); ++ else ++ free(sess->sign_ctx.context); ++ } + + if (sess->sign_ctx.mech.pParameter) + free(sess->sign_ctx.mech.pParameter); + +- if (sess->verify_ctx.context) +- free(sess->verify_ctx.context); ++ if (sess->verify_ctx.context) { ++ if (sess->verify_ctx.context_free_func != NULL) ++ sess->verify_ctx.context_free_func(tokdata, sess, ++ sess->verify_ctx.context, ++ sess->verify_ctx.context_len); ++ else ++ free(sess->verify_ctx.context); ++ } + + if (sess->verify_ctx.mech.pParameter) + free(sess->verify_ctx.mech.pParameter); +@@ -354,32 +384,62 @@ void session_free(STDLL_TokData_t *tokdata, void *node_value, + if (sess->find_list) + free(sess->find_list); + +- if (sess->encr_ctx.context) +- free(sess->encr_ctx.context); ++ if (sess->encr_ctx.context) { ++ if (sess->encr_ctx.context_free_func != NULL) ++ sess->encr_ctx.context_free_func(tokdata, sess, ++ sess->encr_ctx.context, ++ sess->encr_ctx.context_len); ++ else ++ free(sess->encr_ctx.context); ++ } + + if (sess->encr_ctx.mech.pParameter) + free(sess->encr_ctx.mech.pParameter); + +- if (sess->decr_ctx.context) +- free(sess->decr_ctx.context); ++ if (sess->decr_ctx.context) { ++ if (sess->decr_ctx.context_free_func != NULL) ++ sess->decr_ctx.context_free_func(tokdata, sess, ++ sess->decr_ctx.context, ++ sess->decr_ctx.context_len); ++ else ++ free(sess->decr_ctx.context); ++ } + + if (sess->decr_ctx.mech.pParameter) + free(sess->decr_ctx.mech.pParameter); + +- if (sess->digest_ctx.context) +- free(sess->digest_ctx.context); ++ if (sess->digest_ctx.context) { ++ if (sess->digest_ctx.context_free_func != NULL) ++ sess->digest_ctx.context_free_func(tokdata, sess, ++ sess->digest_ctx.context, ++ sess->digest_ctx.context_len); ++ else ++ free(sess->digest_ctx.context); ++ } + + if (sess->digest_ctx.mech.pParameter) + free(sess->digest_ctx.mech.pParameter); + +- if (sess->sign_ctx.context) +- free(sess->sign_ctx.context); ++ if (sess->sign_ctx.context) { ++ if (sess->sign_ctx.context_free_func != NULL) ++ sess->sign_ctx.context_free_func(tokdata, sess, ++ sess->sign_ctx.context, ++ sess->sign_ctx.context_len); ++ else ++ free(sess->sign_ctx.context); ++ } + + if (sess->sign_ctx.mech.pParameter) + free(sess->sign_ctx.mech.pParameter); + +- if (sess->verify_ctx.context) +- free(sess->verify_ctx.context); ++ if (sess->verify_ctx.context) { ++ if (sess->verify_ctx.context_free_func != NULL) ++ sess->verify_ctx.context_free_func(tokdata, sess, ++ sess->verify_ctx.context, ++ sess->verify_ctx.context_len); ++ else ++ free(sess->verify_ctx.context); ++ } + + if (sess->verify_ctx.mech.pParameter) + free(sess->verify_ctx.mech.pParameter); +@@ -528,6 +588,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + active_ops = 0; + + if (sess->encr_ctx.active == TRUE) { ++ if (sess->encr_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -572,6 +636,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->decr_ctx.active == TRUE) { ++ if (sess->decr_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -616,6 +684,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->digest_ctx.active == TRUE) { ++ if (sess->digest_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -660,6 +732,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->sign_ctx.active == TRUE) { ++ if (sess->sign_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -704,6 +780,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->verify_ctx.active == TRUE) { ++ if (sess->verify_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -759,7 +839,7 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + + // + // +-CK_RV session_mgr_set_op_state(SESSION *sess, ++CK_RV session_mgr_set_op_state(STDLL_TokData_t *tokdata, SESSION *sess, + CK_OBJECT_HANDLE encr_key, + CK_OBJECT_HANDLE auth_key, + CK_BYTE *data, CK_ULONG data_len) +@@ -939,19 +1019,19 @@ CK_RV session_mgr_set_op_state(SESSION *sess, + // state information looks okay. cleanup the current session state, first + // + if (sess->encr_ctx.active) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + + if (sess->decr_ctx.active) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + + if (sess->digest_ctx.active) +- digest_mgr_cleanup(&sess->digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &sess->digest_ctx); + + if (sess->sign_ctx.active) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + + if (sess->verify_ctx.active) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + + // copy the new state information +diff --git a/usr/lib/common/mech_aes.c b/usr/lib/common/mech_aes.c +index a117487d..ad6af16b 100644 +--- a/usr/lib/common/mech_aes.c ++++ b/usr/lib/common/mech_aes.c +@@ -2740,6 +2740,9 @@ CK_RV aes_cmac_sign(STDLL_TokData_t *tokdata, + goto done; + } + ++ if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + memcpy(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, mac_len); + *out_data_len = mac_len; + +@@ -2810,6 +2813,9 @@ CK_RV aes_cmac_sign_update(STDLL_TokData_t *tokdata, + context->len = remain; + + context->initialized = CK_TRUE; ++ ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; + } else { + TRACE_DEVEL("Token specific aes cmac failed.\n"); + } +@@ -2873,6 +2879,9 @@ CK_RV aes_cmac_sign_final(STDLL_TokData_t *tokdata, + goto done; + } + ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + memcpy(out_data, context->iv, mac_len); + *out_data_len = mac_len; + +@@ -2929,6 +2938,9 @@ CK_RV aes_cmac_verify(STDLL_TokData_t *tokdata, + return rc; + } + ++ if (((AES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + if (CRYPTO_memcmp(out_data, ((AES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { + return CKR_OK; +@@ -2997,6 +3009,9 @@ CK_RV aes_cmac_verify_update(STDLL_TokData_t *tokdata, + context->len = remain; + + context->initialized = CK_TRUE; ++ ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; + } else { + TRACE_DEVEL("Token specific aes cmac failed.\n"); + } +@@ -3052,6 +3067,9 @@ CK_RV aes_cmac_verify_final(STDLL_TokData_t *tokdata, + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; + ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + if (rc != CKR_OK) { + TRACE_DEVEL("Token specific aes mac failed.\n"); + return rc; +diff --git a/usr/lib/common/mech_des3.c b/usr/lib/common/mech_des3.c +index 786f9a4a..be8d6075 100644 +--- a/usr/lib/common/mech_des3.c ++++ b/usr/lib/common/mech_des3.c +@@ -2380,6 +2380,9 @@ CK_RV des3_cmac_sign(STDLL_TokData_t *tokdata, + if (rc != CKR_OK) + TRACE_DEVEL("Token specific des3 cmac failed.\n"); + ++ if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + memcpy(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, mac_len); + + *out_data_len = mac_len; +@@ -2450,6 +2453,9 @@ CK_RV des3_cmac_sign_update(STDLL_TokData_t *tokdata, + context->len = remain; + + context->initialized = CK_TRUE; ++ ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; + } else { + TRACE_DEVEL("Token specific des3 cmac failed.\n"); + } +@@ -2512,6 +2518,9 @@ CK_RV des3_cmac_sign_final(STDLL_TokData_t *tokdata, + goto done; + } + ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + memcpy(out_data, context->iv, mac_len); + + *out_data_len = mac_len; +@@ -2565,6 +2574,9 @@ CK_RV des3_cmac_verify(STDLL_TokData_t *tokdata, + object_put(tokdata, key_obj, TRUE); + key_obj = NULL; + ++ if (((DES_CMAC_CONTEXT *)ctx->context)->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + if (CRYPTO_memcmp(out_data, ((DES_CMAC_CONTEXT *) ctx->context)->iv, + out_data_len) == 0) { + return CKR_OK; +@@ -2631,6 +2643,9 @@ CK_RV des3_cmac_verify_update(STDLL_TokData_t *tokdata, + context->len = remain; + + context->initialized = CK_TRUE; ++ ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; + } else { + TRACE_DEVEL("Token specific des3 cmac failed.\n"); + } +@@ -2691,6 +2706,9 @@ CK_RV des3_cmac_verify_final(STDLL_TokData_t *tokdata, + return rc; + } + ++ if (context->ctx != NULL) ++ ctx->state_unsaveable = CK_TRUE; ++ + if (CRYPTO_memcmp(signature, context->iv, signature_len) == 0) + return CKR_OK; + +diff --git a/usr/lib/common/mech_ec.c b/usr/lib/common/mech_ec.c +index a0a06302..c338d063 100644 +--- a/usr/lib/common/mech_ec.c ++++ b/usr/lib/common/mech_ec.c +@@ -414,7 +414,7 @@ CK_RV ec_hash_sign(STDLL_TokData_t *tokdata, + in_data_len, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + +@@ -434,7 +434,7 @@ CK_RV ec_hash_sign(STDLL_TokData_t *tokdata, + TRACE_DEVEL("Sign Mgr Sign failed.\n"); + + error: +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -485,6 +485,7 @@ CK_RV ec_hash_sign_update(STDLL_TokData_t *tokdata, + return rc; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, &context->hash_context, +@@ -556,12 +557,12 @@ CK_RV ec_hash_sign_final(STDLL_TokData_t *tokdata, + TRACE_DEVEL("Sign Mgr Sign failed.\n"); + + if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) { +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + return rc; + } + + done: +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -627,7 +628,7 @@ CK_RV ec_hash_verify(STDLL_TokData_t *tokdata, + in_data_len, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + // Verify the Signed BER-encoded Data block +@@ -649,7 +650,7 @@ CK_RV ec_hash_verify(STDLL_TokData_t *tokdata, + if (rc != CKR_OK) + TRACE_DEVEL("Verify Mgr Verify failed.\n"); + done: +- sign_mgr_cleanup(&verify_ctx); ++ sign_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +@@ -701,6 +702,7 @@ CK_RV ec_hash_verify_update(STDLL_TokData_t *tokdata, + return rc; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, &context->hash_context, +@@ -768,7 +770,7 @@ CK_RV ec_hash_verify_final(STDLL_TokData_t *tokdata, + if (rc != CKR_OK) + TRACE_DEVEL("Verify Mgr Verify failed.\n"); + done: +- verify_mgr_cleanup(&verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +@@ -823,7 +825,7 @@ CK_RV ckm_kdf(STDLL_TokData_t *tokdata, SESSION *sess, CK_ULONG kdf, + h_len); + if (rc != CKR_OK) { + TRACE_ERROR("digest_mgr_digest failed with rc = %s\n", ock_err(rc)); +- digest_mgr_cleanup(&ctx); ++ digest_mgr_cleanup(tokdata, sess, &ctx); + return rc; + } + +diff --git a/usr/lib/common/mech_md2.c b/usr/lib/common/mech_md2.c +index beb84365..91da6259 100644 +--- a/usr/lib/common/mech_md2.c ++++ b/usr/lib/common/mech_md2.c +@@ -245,7 +245,7 @@ CK_RV md2_hmac_sign(STDLL_TokData_t *tokdata, + attr->pValue, attr->ulValueLen, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + goto done; + } + memset(&digest_ctx, 0x0, sizeof(DIGEST_CONTEXT)); +diff --git a/usr/lib/common/mech_md5.c b/usr/lib/common/mech_md5.c +index 6b1281de..320e2549 100644 +--- a/usr/lib/common/mech_md5.c ++++ b/usr/lib/common/mech_md5.c +@@ -61,7 +61,10 @@ CK_RV sw_md5_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + MD5_Final(out_data, (MD5_CTX *)ctx->context); + *out_data_len = MD5_HASH_SIZE; + +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(ctx->context, ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + + return CKR_OK; +@@ -86,7 +89,10 @@ CK_RV sw_MD5_Final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, + MD5_Final(out_data, (MD5_CTX *)ctx->context); + *out_data_len = MD5_HASH_SIZE; + +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(ctx->context, ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + + return CKR_OK; +@@ -267,7 +273,7 @@ CK_RV md5_hmac_sign(STDLL_TokData_t *tokdata, + attr->pValue, attr->ulValueLen, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + goto done; + } + +@@ -413,6 +419,6 @@ CK_RV md5_hmac_verify(STDLL_TokData_t *tokdata, SESSION *sess, + } + + done: +- sign_mgr_cleanup(&hmac_ctx); ++ sign_mgr_cleanup(tokdata, sess, &hmac_ctx); + return rc; + } +diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c +index e35b383c..0a690e78 100644 +--- a/usr/lib/common/mech_rsa.c ++++ b/usr/lib/common/mech_rsa.c +@@ -1476,7 +1476,7 @@ CK_RV rsa_hash_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess, + in_data, in_data_len, hash, &hlen); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + +@@ -1497,7 +1497,7 @@ CK_RV rsa_hash_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess, + TRACE_DEVEL("Sign Mgr Sign failed.\n"); + + done: +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -1546,6 +1546,7 @@ CK_RV rsa_hash_pss_update(STDLL_TokData_t *tokdata, SESSION *sess, + TRACE_DEVEL("Digest Mgr Init failed.\n"); + return rc; + } ++ ctx->state_unsaveable |= digest_ctx->state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, digest_ctx, in_data, +@@ -1613,7 +1614,7 @@ CK_RV rsa_hash_pss_sign_final(STDLL_TokData_t *tokdata, SESSION *sess, + TRACE_DEVEL("Sign Mgr Sign failed.\n"); + + done: +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -1676,7 +1677,7 @@ CK_RV rsa_hash_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess, + in_data_len, hash, &hlen); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + +@@ -1698,7 +1699,7 @@ CK_RV rsa_hash_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess, + TRACE_DEVEL("Verify Mgr Verify failed.\n"); + + done: +- verify_mgr_cleanup(&verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +@@ -1760,7 +1761,7 @@ CK_RV rsa_hash_pss_verify_final(STDLL_TokData_t *tokdata, SESSION *sess, + TRACE_DEVEL("Verify Mgr Verify failed.\n"); + + done: +- verify_mgr_cleanup(&verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +@@ -1842,7 +1843,7 @@ CK_RV rsa_hash_pkcs_sign(STDLL_TokData_t *tokdata, + in_data_len, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + // build the BER-encodings +@@ -1885,7 +1886,7 @@ error: + free(octet_str); + if (ber_data) + free(ber_data); +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -1934,6 +1935,7 @@ CK_RV rsa_hash_pkcs_sign_update(STDLL_TokData_t *tokdata, + return rc; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, &context->hash_context, +@@ -2021,7 +2023,7 @@ CK_RV rsa_hash_pkcs_verify(STDLL_TokData_t *tokdata, + in_data_len, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + return rc; + } + // Build the BER encoding +@@ -2063,7 +2065,7 @@ done: + free(octet_str); + if (ber_data) + free(ber_data); +- sign_mgr_cleanup(&verify_ctx); ++ sign_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +@@ -2111,6 +2113,7 @@ CK_RV rsa_hash_pkcs_verify_update(STDLL_TokData_t *tokdata, + return rc; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, &context->hash_context, +@@ -2236,7 +2239,7 @@ done: + free(octet_str); + if (ber_data) + free(ber_data); +- sign_mgr_cleanup(&sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sign_ctx); + + return rc; + } +@@ -2347,7 +2350,7 @@ done: + free(octet_str); + if (ber_data) + free(ber_data); +- verify_mgr_cleanup(&verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &verify_ctx); + + return rc; + } +diff --git a/usr/lib/common/mech_sha.c b/usr/lib/common/mech_sha.c +index 4037b8f1..0b9b7b28 100644 +--- a/usr/lib/common/mech_sha.c ++++ b/usr/lib/common/mech_sha.c +@@ -80,7 +80,10 @@ CK_RV sw_sha1_hash(DIGEST_CONTEXT *ctx, CK_BYTE *in_data, + SHA1_Final(out_data, (SHA_CTX *)ctx->context); + *out_data_len = SHA1_HASH_SIZE; + +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(ctx->context, ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + + return CKR_OK; +@@ -105,7 +108,10 @@ CK_RV sw_sha1_final(DIGEST_CONTEXT *ctx, CK_BYTE *out_data, + SHA1_Final(out_data, (SHA_CTX *)ctx->context); + *out_data_len = SHA1_HASH_SIZE; + +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(ctx->context, ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + + return CKR_OK; +@@ -421,7 +427,7 @@ CK_RV sha_hmac_sign(STDLL_TokData_t *tokdata, + attr->pValue, attr->ulValueLen, hash, &hash_len); + if (rc != CKR_OK) { + TRACE_DEVEL("Digest Mgr Digest failed.\n"); +- digest_mgr_cleanup(&digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &digest_ctx); + goto done; + } + +@@ -607,7 +613,7 @@ CK_RV sha_hmac_verify(STDLL_TokData_t *tokdata, SESSION *sess, + } + + done: +- sign_mgr_cleanup(&hmac_ctx); ++ sign_mgr_cleanup(tokdata, sess, &hmac_ctx); + return rc; + } + +diff --git a/usr/lib/common/mech_ssl3.c b/usr/lib/common/mech_ssl3.c +index 66bdb8f4..566aeee2 100644 +--- a/usr/lib/common/mech_ssl3.c ++++ b/usr/lib/common/mech_ssl3.c +@@ -289,6 +289,7 @@ CK_RV ssl3_mac_sign_update(STDLL_TokData_t *tokdata, + goto done; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + +@@ -485,7 +486,7 @@ CK_RV ssl3_mac_verify(STDLL_TokData_t *tokdata, + rc = CKR_SIGNATURE_INVALID; + } + error: +- sign_mgr_cleanup(&mac_ctx); ++ sign_mgr_cleanup(tokdata, sess, &mac_ctx); + + return rc; + } +@@ -573,6 +574,7 @@ CK_RV ssl3_mac_verify_update(STDLL_TokData_t *tokdata, + goto done; + } + context->flag = TRUE; ++ ctx->state_unsaveable |= context->hash_context.state_unsaveable; + } + + rc = digest_mgr_digest_update(tokdata, sess, &context->hash_context, +diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c +index a3749d26..d01091f9 100644 +--- a/usr/lib/common/new_host.c ++++ b/usr/lib/common/new_host.c +@@ -1215,8 +1215,9 @@ CK_RV SC_SetOperationState(STDLL_TokData_t *tokdata, + goto done; + } + +- rc = session_mgr_set_op_state(sess, hEncryptionKey, hAuthenticationKey, +- pOperationState, ulOperationStateLen); ++ rc = session_mgr_set_op_state(tokdata, sess, hEncryptionKey, ++ hAuthenticationKey, pOperationState, ++ ulOperationStateLen); + + if (rc != CKR_OK) + TRACE_DEVEL("session_mgr_set_op_state() failed.\n"); +@@ -2128,7 +2129,7 @@ CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_Encrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2187,7 +2188,7 @@ CK_RV SC_EncryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2244,7 +2245,7 @@ CK_RV SC_EncryptFinal(STDLL_TokData_t * tokdata, ST_SESSION_HANDLE * sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptFinal: rc = 0x%08lx, sess = %ld\n", +@@ -2361,7 +2362,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_Decrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2420,7 +2421,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2477,7 +2478,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptFinal: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2825,7 +2826,7 @@ CK_RV SC_Sign(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_Sign: rc = 0x%08lx, sess = %ld, datalen = %lu\n", +@@ -2875,7 +2876,7 @@ CK_RV SC_SignUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (rc != CKR_OK && sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + + TRACE_INFO("C_SignUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -2930,7 +2931,7 @@ CK_RV SC_SignFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_SignFinal: rc = 0x%08lx, sess = %ld\n", +@@ -3045,7 +3046,7 @@ CK_RV SC_SignRecover(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_SignRecover: rc = 0x%08lx, sess = %ld, datalen = %lu\n", +@@ -3155,7 +3156,7 @@ CK_RV SC_Verify(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_Verify: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen); +@@ -3205,7 +3206,7 @@ CK_RV SC_VerifyUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (rc != CKR_OK && sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -3255,7 +3256,7 @@ CK_RV SC_VerifyFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyFinal: rc = 0x%08lx, sess = %ld\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle); +@@ -3372,7 +3373,7 @@ CK_RV SC_VerifyRecover(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + } + + TRACE_INFO("C_VerifyRecover: rc = 0x%08lx, sess = %ld, recover len = %lu, " +diff --git a/usr/lib/common/sess_mgr.c b/usr/lib/common/sess_mgr.c +index e2da6df5..69c3be3b 100644 +--- a/usr/lib/common/sess_mgr.c ++++ b/usr/lib/common/sess_mgr.c +@@ -243,32 +243,62 @@ CK_RV session_mgr_close_session(STDLL_TokData_t *tokdata, + if (sess->find_list) + free(sess->find_list); + +- if (sess->encr_ctx.context) +- free(sess->encr_ctx.context); ++ if (sess->encr_ctx.context) { ++ if (sess->encr_ctx.context_free_func != NULL) ++ sess->encr_ctx.context_free_func(tokdata, sess, ++ sess->encr_ctx.context, ++ sess->encr_ctx.context_len); ++ else ++ free(sess->encr_ctx.context); ++ } + + if (sess->encr_ctx.mech.pParameter) + free(sess->encr_ctx.mech.pParameter); + +- if (sess->decr_ctx.context) +- free(sess->decr_ctx.context); ++ if (sess->decr_ctx.context) { ++ if (sess->decr_ctx.context_free_func != NULL) ++ sess->decr_ctx.context_free_func(tokdata, sess, ++ sess->decr_ctx.context, ++ sess->decr_ctx.context_len); ++ else ++ free(sess->decr_ctx.context); ++ } + + if (sess->decr_ctx.mech.pParameter) + free(sess->decr_ctx.mech.pParameter); + +- if (sess->digest_ctx.context) +- free(sess->digest_ctx.context); ++ if (sess->digest_ctx.context) { ++ if (sess->digest_ctx.context_free_func != NULL) ++ sess->digest_ctx.context_free_func(tokdata, sess, ++ sess->digest_ctx.context, ++ sess->digest_ctx.context_len); ++ else ++ free(sess->digest_ctx.context); ++ } + + if (sess->digest_ctx.mech.pParameter) + free(sess->digest_ctx.mech.pParameter); + +- if (sess->sign_ctx.context) +- free(sess->sign_ctx.context); ++ if (sess->sign_ctx.context) { ++ if (sess->sign_ctx.context_free_func != NULL) ++ sess->sign_ctx.context_free_func(tokdata, sess, ++ sess->sign_ctx.context, ++ sess->sign_ctx.context_len); ++ else ++ free(sess->sign_ctx.context); ++ } + + if (sess->sign_ctx.mech.pParameter) + free(sess->sign_ctx.mech.pParameter); + +- if (sess->verify_ctx.context) +- free(sess->verify_ctx.context); ++ if (sess->verify_ctx.context) { ++ if (sess->verify_ctx.context_free_func != NULL) ++ sess->verify_ctx.context_free_func(tokdata, sess, ++ sess->verify_ctx.context, ++ sess->verify_ctx.context_len); ++ else ++ free(sess->verify_ctx.context); ++ } + + if (sess->verify_ctx.mech.pParameter) + free(sess->verify_ctx.mech.pParameter); +@@ -323,32 +353,62 @@ void session_free(STDLL_TokData_t *tokdata, void *node_value, + if (sess->find_list) + free(sess->find_list); + +- if (sess->encr_ctx.context) +- free(sess->encr_ctx.context); ++ if (sess->encr_ctx.context) { ++ if (sess->encr_ctx.context_free_func != NULL) ++ sess->encr_ctx.context_free_func(tokdata, sess, ++ sess->encr_ctx.context, ++ sess->encr_ctx.context_len); ++ else ++ free(sess->encr_ctx.context); ++ } + + if (sess->encr_ctx.mech.pParameter) + free(sess->encr_ctx.mech.pParameter); + +- if (sess->decr_ctx.context) +- free(sess->decr_ctx.context); ++ if (sess->decr_ctx.context) { ++ if (sess->decr_ctx.context_free_func != NULL) ++ sess->decr_ctx.context_free_func(tokdata, sess, ++ sess->decr_ctx.context, ++ sess->decr_ctx.context_len); ++ else ++ free(sess->decr_ctx.context); ++ } + + if (sess->decr_ctx.mech.pParameter) + free(sess->decr_ctx.mech.pParameter); + +- if (sess->digest_ctx.context) +- free(sess->digest_ctx.context); ++ if (sess->digest_ctx.context) { ++ if (sess->digest_ctx.context_free_func != NULL) ++ sess->digest_ctx.context_free_func(tokdata, sess, ++ sess->digest_ctx.context, ++ sess->digest_ctx.context_len); ++ else ++ free(sess->digest_ctx.context); ++ } + + if (sess->digest_ctx.mech.pParameter) + free(sess->digest_ctx.mech.pParameter); + +- if (sess->sign_ctx.context) +- free(sess->sign_ctx.context); ++ if (sess->sign_ctx.context) { ++ if (sess->sign_ctx.context_free_func != NULL) ++ sess->sign_ctx.context_free_func(tokdata, sess, ++ sess->sign_ctx.context, ++ sess->sign_ctx.context_len); ++ else ++ free(sess->sign_ctx.context); ++ } + + if (sess->sign_ctx.mech.pParameter) + free(sess->sign_ctx.mech.pParameter); + +- if (sess->verify_ctx.context) +- free(sess->verify_ctx.context); ++ if (sess->verify_ctx.context) { ++ if (sess->verify_ctx.context_free_func != NULL) ++ sess->verify_ctx.context_free_func(tokdata, sess, ++ sess->verify_ctx.context, ++ sess->verify_ctx.context_len); ++ else ++ free(sess->verify_ctx.context); ++ } + + if (sess->verify_ctx.mech.pParameter) + free(sess->verify_ctx.mech.pParameter); +@@ -480,6 +540,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + active_ops = 0; + + if (sess->encr_ctx.active == TRUE) { ++ if (sess->encr_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -524,6 +588,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->decr_ctx.active == TRUE) { ++ if (sess->decr_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -568,6 +636,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->digest_ctx.active == TRUE) { ++ if (sess->digest_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -612,6 +684,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->sign_ctx.active == TRUE) { ++ if (sess->sign_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -656,6 +732,10 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + } + + if (sess->verify_ctx.active == TRUE) { ++ if (sess->verify_ctx.state_unsaveable) { ++ TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); ++ return CKR_STATE_UNSAVEABLE; ++ } + active_ops++; + if (op_data != NULL) { + TRACE_ERROR("%s\n", ock_err(ERR_STATE_UNSAVEABLE)); +@@ -711,7 +791,7 @@ CK_RV session_mgr_get_op_state(SESSION *sess, + + // + // +-CK_RV session_mgr_set_op_state(SESSION *sess, ++CK_RV session_mgr_set_op_state(STDLL_TokData_t *tokdata, SESSION *sess, + CK_OBJECT_HANDLE encr_key, + CK_OBJECT_HANDLE auth_key, + CK_BYTE *data, CK_ULONG data_len) +@@ -891,19 +971,19 @@ CK_RV session_mgr_set_op_state(SESSION *sess, + // state information looks okay. cleanup the current session state, first + // + if (sess->encr_ctx.active) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + + if (sess->decr_ctx.active) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + + if (sess->digest_ctx.active) +- digest_mgr_cleanup(&sess->digest_ctx); ++ digest_mgr_cleanup(tokdata, sess, &sess->digest_ctx); + + if (sess->sign_ctx.active) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + + if (sess->verify_ctx.active) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + + // copy the new state information +diff --git a/usr/lib/common/sign_mgr.c b/usr/lib/common/sign_mgr.c +index c7268e01..74e3a9e0 100644 +--- a/usr/lib/common/sign_mgr.c ++++ b/usr/lib/common/sign_mgr.c +@@ -805,7 +805,8 @@ done: + + // + // +-CK_RV sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) ++CK_RV sign_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ SIGN_VERIFY_CONTEXT *ctx) + { + if (!ctx) { + TRACE_ERROR("Invalid function argument.\n"); +@@ -821,6 +822,7 @@ CK_RV sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) + ctx->recover = FALSE; + ctx->context_len = 0; + ctx->pkey_active = FALSE; ++ ctx->state_unsaveable = FALSE; + + if (ctx->mech.pParameter) { + free(ctx->mech.pParameter); +@@ -828,9 +830,14 @@ CK_RV sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) + } + + if (ctx->context) { +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(tokdata, sess, ctx->context, ++ ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + } ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +diff --git a/usr/lib/common/verify_mgr.c b/usr/lib/common/verify_mgr.c +index c46a9803..b49fbb49 100644 +--- a/usr/lib/common/verify_mgr.c ++++ b/usr/lib/common/verify_mgr.c +@@ -798,7 +798,8 @@ done: + + // + // +-CK_RV verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) ++CK_RV verify_mgr_cleanup(STDLL_TokData_t *tokdata, SESSION *sess, ++ SIGN_VERIFY_CONTEXT *ctx) + { + if (!ctx) { + TRACE_ERROR("Invalid function argument.\n"); +@@ -814,6 +815,7 @@ CK_RV verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) + ctx->recover = FALSE; + ctx->context_len = 0; + ctx->pkey_active = FALSE; ++ ctx->state_unsaveable = FALSE; + + if (ctx->mech.pParameter) { + free(ctx->mech.pParameter); +@@ -821,9 +823,14 @@ CK_RV verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) + } + + if (ctx->context) { +- free(ctx->context); ++ if (ctx->context_free_func != NULL) ++ ctx->context_free_func(tokdata, sess, ctx->context, ++ ctx->context_len); ++ else ++ free(ctx->context); + ctx->context = NULL; + } ++ ctx->context_free_func = NULL; + + return CKR_OK; + } +diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c +index fb6055e9..49775d0a 100644 +--- a/usr/lib/ep11_stdll/ep11_specific.c ++++ b/usr/lib/ep11_stdll/ep11_specific.c +@@ -8091,7 +8091,7 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, + ctx->context_len = ep11_state_l; + ctx->pkey_active = FALSE; + if (rc != CKR_OK) { +- decr_mgr_cleanup(ctx); ++ decr_mgr_cleanup(tokdata, session, ctx); + rc = ep11_error_to_pkcs11_error(rc, session); + TRACE_ERROR("%s m_DecryptInit rc=0x%lx blob_len=0x%zx " + "mech=0x%lx\n", __func__, rc, blob_len, +@@ -8124,7 +8124,7 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, + ctx->context_len = ep11_state_l; + ctx->pkey_active = FALSE; + if (rc != CKR_OK) { +- encr_mgr_cleanup(ctx); ++ encr_mgr_cleanup(tokdata, session, ctx); + rc = ep11_error_to_pkcs11_error(rc, session); + TRACE_ERROR("%s m_EncryptInit rc=0x%lx blob_len=0x%zx " + "mech=0x%lx\n", __func__, rc, blob_len, +diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c +index cd12604e..a0e7517c 100644 +--- a/usr/lib/ep11_stdll/new_host.c ++++ b/usr/lib/ep11_stdll/new_host.c +@@ -1223,8 +1223,9 @@ CK_RV SC_SetOperationState(STDLL_TokData_t *tokdata, + goto done; + } + +- rc = session_mgr_set_op_state(sess, hEncryptionKey, hAuthenticationKey, +- pOperationState, ulOperationStateLen); ++ rc = session_mgr_set_op_state(tokdata, sess, hEncryptionKey, ++ hAuthenticationKey, pOperationState, ++ ulOperationStateLen); + + if (rc != CKR_OK) + TRACE_DEVEL("session_mgr_set_op_state() failed.\n"); +@@ -2160,7 +2161,7 @@ CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_Encrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2236,7 +2237,7 @@ CK_RV SC_EncryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2310,7 +2311,7 @@ CK_RV SC_EncryptFinal(STDLL_TokData_t * tokdata, ST_SESSION_HANDLE * sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptFinal: rc = 0x%08lx, sess = %ld\n", +@@ -2478,7 +2479,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_Decrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2554,7 +2555,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2626,7 +2627,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptFinal: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -3022,7 +3023,7 @@ CK_RV SC_Sign(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_Sign: rc = 0x%08lx, sess = %ld, datalen = %lu\n", +@@ -3104,7 +3105,7 @@ CK_RV SC_SignUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (rc != CKR_OK && sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + + TRACE_INFO("C_SignUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -3185,7 +3186,7 @@ CK_RV SC_SignFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_SignFinal: rc = 0x%08lx, sess = %ld\n", +@@ -3406,7 +3407,7 @@ CK_RV SC_Verify(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_Verify: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen); +@@ -3487,7 +3488,7 @@ CK_RV SC_VerifyUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (rc != CKR_OK && sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -3562,7 +3563,7 @@ CK_RV SC_VerifyFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyFinal: rc = 0x%08lx, sess = %ld\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle); +diff --git a/usr/lib/ica_s390_stdll/ica_specific.c b/usr/lib/ica_s390_stdll/ica_specific.c +index 7a81145d..77876467 100644 +--- a/usr/lib/ica_s390_stdll/ica_specific.c ++++ b/usr/lib/ica_s390_stdll/ica_specific.c +@@ -810,8 +810,10 @@ CK_RV token_specific_sha_init(STDLL_TokData_t *tokdata, DIGEST_CONTEXT *ctx, + } + + /* (re)alloc ctx in one memory area */ +- if (ctx->context) ++ if (ctx->context) { + free(ctx->context); ++ ctx->context_free_func = NULL; ++ } + ctx->context_len = 0; + ctx->context = malloc(ctxsize + devctxsize); + if (ctx->context == NULL) { +diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c +index cfef7425..09e9d27a 100644 +--- a/usr/lib/icsf_stdll/new_host.c ++++ b/usr/lib/icsf_stdll/new_host.c +@@ -773,8 +773,9 @@ CK_RV SC_SetOperationState(STDLL_TokData_t *tokdata, + //set the handle into the session. + sess->handle = sSession->sessionh; + +- rc = session_mgr_set_op_state(sess, hEncryptionKey, hAuthenticationKey, +- pOperationState, ulOperationStateLen); ++ rc = session_mgr_set_op_state(tokdata, sess, hEncryptionKey, ++ hAuthenticationKey, pOperationState, ++ ulOperationStateLen); + + if (rc != CKR_OK) + TRACE_DEVEL("session_mgr_set_op_state() failed.\n"); +@@ -1556,7 +1557,7 @@ CK_RV SC_Encrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_Encrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -1612,7 +1613,7 @@ CK_RV SC_EncryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -1671,7 +1672,7 @@ CK_RV SC_EncryptFinal(STDLL_TokData_t * tokdata, ST_SESSION_HANDLE * sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- encr_mgr_cleanup(&sess->encr_ctx); ++ encr_mgr_cleanup(tokdata, sess, &sess->encr_ctx); + } + + TRACE_INFO("C_EncryptFinal: rc = 0x%08lx, sess = %ld\n", +@@ -1790,7 +1791,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_Decrypt: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -1846,7 +1847,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptUpdate: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -1903,7 +1904,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { + if (sess) +- decr_mgr_cleanup(&sess->decr_ctx); ++ decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } + + TRACE_INFO("C_DecryptFinal: rc = 0x%08lx, sess = %ld, amount = %lu\n", +@@ -2261,7 +2262,7 @@ CK_RV SC_Sign(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || pSignature)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_Sign: rc = 0x%08lx, sess = %ld, datalen = %lu\n", +@@ -2312,7 +2313,7 @@ CK_RV SC_SignUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + TRACE_DEVEL("icsftok_sign_update() failed.\n"); + done: + if (rc != CKR_OK && sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + + TRACE_INFO("C_SignUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -2364,7 +2365,7 @@ CK_RV SC_SignFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + done: + if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || pSignature)) { + if (sess != NULL) +- sign_mgr_cleanup(&sess->sign_ctx); ++ sign_mgr_cleanup(tokdata, sess, &sess->sign_ctx); + } + + TRACE_INFO("C_SignFinal: rc = 0x%08lx, sess = %ld\n", +@@ -2517,7 +2518,7 @@ CK_RV SC_Verify(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_Verify: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulDataLen); +@@ -2568,7 +2569,7 @@ CK_RV SC_VerifyUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (rc != CKR_OK && sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyUpdate: rc = 0x%08lx, sess = %ld, datalen = %lu\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle, ulPartLen); +@@ -2619,7 +2620,7 @@ CK_RV SC_VerifyFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + done: + if (sess != NULL) +- verify_mgr_cleanup(&sess->verify_ctx); ++ verify_mgr_cleanup(tokdata, sess, &sess->verify_ctx); + + TRACE_INFO("C_VerifyFinal: rc = 0x%08lx, sess = %ld\n", + rc, (sess == NULL) ? -1 : (CK_LONG) sess->handle); diff --git a/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch b/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch new file mode 100644 index 0000000..091bc8e --- /dev/null +++ b/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch @@ -0,0 +1,115 @@ +commit ab3fceae6194e8213e9d3ffb7447ccd04d469b9d +Author: Ingo Franzki +Date: Mon Jul 5 10:45:04 2021 +0200 + + COMMON: sw_crypt.c: Remove support for OpenSSL < v1.1.1 + + Remove support for OpenSSL < v1.1.1. This code used low level + DES/AES functions. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/sw_crypt.c b/usr/lib/common/sw_crypt.c +index 906a41ab..253b3c26 100644 +--- a/usr/lib/common/sw_crypt.c ++++ b/usr/lib/common/sw_crypt.c +@@ -32,51 +32,6 @@ CK_RV sw_des3_cbc(CK_BYTE *in_data, + CK_ULONG *out_data_len, + CK_BYTE *init_v, CK_BYTE *key_value, CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- DES_key_schedule des_key1; +- DES_key_schedule des_key2; +- DES_key_schedule des_key3; +- +- const_DES_cblock key_SSL1, key_SSL2, key_SSL3; +- DES_cblock ivec; +- +- // the des decrypt will only fail if the data length is not evenly divisible +- // by DES_BLOCK_SIZE +- if (in_data_len % DES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- // The key as passed in is a 24 byte string containing 3 keys +- // pick it apart and create the key schedules +- memcpy(&key_SSL1, key_value, (size_t) 8); +- memcpy(&key_SSL2, key_value + 8, (size_t) 8); +- memcpy(&key_SSL3, key_value + 16, (size_t) 8); +- DES_set_key_unchecked(&key_SSL1, &des_key1); +- DES_set_key_unchecked(&key_SSL2, &des_key2); +- DES_set_key_unchecked(&key_SSL3, &des_key3); +- +- memcpy(ivec, init_v, sizeof(ivec)); +- +- // Encrypt or decrypt the data +- if (encrypt) { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_ENCRYPT); +- *out_data_len = in_data_len; +- } else { +- DES_ede3_cbc_encrypt(in_data, +- out_data, +- in_data_len, +- &des_key1, +- &des_key2, &des_key3, &ivec, DES_DECRYPT); +- +- *out_data_len = in_data_len; +- } +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); +@@ -109,7 +64,6 @@ CK_RV sw_des3_cbc(CK_BYTE *in_data, + done: + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } + + CK_RV sw_aes_cbc(CK_BYTE *in_data, +@@ -119,33 +73,6 @@ CK_RV sw_aes_cbc(CK_BYTE *in_data, + CK_BYTE *init_v, CK_BYTE *key_value, CK_ULONG keylen, + CK_BYTE encrypt) + { +-#if OPENSSL_VERSION_NUMBER < 0x10100000L +- AES_KEY aes_key; +- +- UNUSED(out_data_len); //XXX can this parameter be removed ? +- +- memset(&aes_key, 0, sizeof(aes_key)); +- +- // the aes decrypt will only fail if the data length is not evenly divisible +- // by AES_BLOCK_SIZE +- if (in_data_len % AES_BLOCK_SIZE) { +- TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE)); +- return CKR_DATA_LEN_RANGE; +- } +- +- // Encrypt or decrypt the data +- if (encrypt) { +- AES_set_encrypt_key(key_value, keylen * 8, &aes_key); +- AES_cbc_encrypt(in_data, out_data, in_data_len, &aes_key, +- init_v, AES_ENCRYPT); +- } else { +- AES_set_decrypt_key(key_value, keylen * 8, &aes_key); +- AES_cbc_encrypt(in_data, out_data, in_data_len, &aes_key, +- init_v, AES_DECRYPT); +- } +- +- return CKR_OK; +-#else + CK_RV rc; + int outlen; + const EVP_CIPHER *cipher = NULL; +@@ -187,5 +114,4 @@ CK_RV sw_aes_cbc(CK_BYTE *in_data, + done: + EVP_CIPHER_CTX_free(ctx); + return rc; +-#endif + } diff --git a/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch b/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch new file mode 100644 index 0000000..8a88c26 --- /dev/null +++ b/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch @@ -0,0 +1,37 @@ +commit c4683eb904238d20cb34a4c7661ffac04901283c +Author: Ingo Franzki +Date: Tue Jun 29 17:35:30 2021 +0200 + + COMMON: Add OPENSSL_VERSION_PREREQ macro to check for OpenSSL version + + Make the OPENSSL_VERSION_PREREQ macro available independent of the + used OpenSSL version, so that the code can easily check for the OpenSSL + version it is compiled with. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/defs.h b/usr/lib/common/defs.h +index 22d75d2d..8ab50517 100644 +--- a/usr/lib/common/defs.h ++++ b/usr/lib/common/defs.h +@@ -17,6 +17,20 @@ + #ifndef _DEFS_H + #define _DEFS_H + ++#include ++ ++#ifndef OPENSSL_VERSION_PREREQ ++ #if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR) ++ #define OPENSSL_VERSION_PREREQ(maj, min) \ ++ ((OPENSSL_VERSION_MAJOR << 16) + \ ++ OPENSSL_VERSION_MINOR >= ((maj) << 16) + (min)) ++ #else ++ #define OPENSSL_VERSION_PREREQ(maj, min) \ ++ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | \ ++ ((min) << 20))) ++ #endif ++#endif ++ + #define MAX_SESSION_COUNT 64 + #define MAX_PIN_LEN 8 + #define MIN_PIN_LEN 4 diff --git a/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch b/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch new file mode 100644 index 0000000..dccf2e8 --- /dev/null +++ b/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch @@ -0,0 +1,49 @@ +commit dd9cfe2ef89dad185397df46227f9392a6317d35 +Author: Ingo Franzki +Date: Wed Jul 21 13:54:59 2021 +0200 + + CONFIGURE: Check that OpenSSL 1.1.1 or later is available + + Signed-off-by: Ingo Franzki + +diff --git a/configure.ac b/configure.ac +index 286b7408..f47060d9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -277,21 +277,14 @@ if test "x$with_openssl" != "xno"; then + old_libs="$LIBS" + CFLAGS="$CFLAGS $OPENSSL_CFLAGS" + LIBS="$LIBS $OPENSSL_LIBS" +- AC_CHECK_HEADER([openssl/ssl.h], [], [ +- if test "x$with_openssl" != "xcheck"; then +- AC_MSG_ERROR([Build with OpenSSL requested but OpenSSL headers couldn't be found]) +- fi +- with_openssl=no ++ AC_CHECK_HEADER([openssl/evp.h], [], [ ++ AC_MSG_ERROR([OpenSSL 1.1.1 or later is required but OpenSSL headers couldn't be found]) + ]) + if test "x$with_openssl" != "xno"; then +- AC_CHECK_LIB([crypto], [RSA_generate_key], [ ++ AC_CHECK_LIB([crypto], [EVP_sha3_256], [ + OPENSSL_LIBS="$OPENSSL_LIBS -lcrypto" +- with_openssl=yes +- ], [ +- if test "x$with_openssl" != "xcheck"; then +- AC_MSG_ERROR([Build with OpenSSL requested but OpenSSL libraries couldn't be found]) +- fi +- with_openssl=no ++ with_openssl=yes], [ ++ AC_MSG_ERROR([OpenSSL 1.1.1 or later is required but OpenSSL libraries version 1.1.1 or later couldn't be found]) + ]) + fi + if test "x$with_openssl" = "xno"; then +@@ -299,6 +292,9 @@ if test "x$with_openssl" != "xno"; then + LIBS="$old_libs" + fi + fi ++if test "x$with_openssl" != "xyes"; then ++ AC_MSG_ERROR([OpenSSL 1.1.1 or later is required but build without OpenSSL was requested]) ++fi + AC_SUBST([OPENSSL_CFLAGS]) + AC_SUBST([OPENSSL_LIBS]) + diff --git a/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch b/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch new file mode 100644 index 0000000..722c1d6 --- /dev/null +++ b/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch @@ -0,0 +1,853 @@ +commit ecf71404e84ae35931cd6c7398c825378ee052b6 +Author: Ingo Franzki +Date: Fri Jul 2 11:20:22 2021 +0200 + + TESTCASES: Soft: Skip tests with RSA publ.exp. not supported by OpenSSL + + OpenSSL 3.0 only accepts public exponents of 3 and 65537 for RSA keys. + Skip the testcase if another public exponent is used. + + Also fixed some ugly line breaks within messages. + + Signed-off-by: Ingo Franzki + +diff --git a/testcases/common/common.c b/testcases/common/common.c +index bfd486cb..0a64ecf2 100644 +--- a/testcases/common/common.c ++++ b/testcases/common/common.c +@@ -876,6 +876,16 @@ int is_valid_cca_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len) + || (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3))); + } + ++/** Returns true if pubexp is valid for Soft Tokens **/ ++int is_valid_soft_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len) ++{ ++ CK_BYTE exp3[] = { 0x03 }; // 3 ++ CK_BYTE exp65537[] = { 0x01, 0x00, 0x01 }; // 65537 ++ ++ return (pubexp_len == 1 && (!memcmp(pubexp, exp3, 1))) ++ || (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3))); ++} ++ + /** Returns true if slot_id is an ICSF token + ** ICSF token info is not necessarily hard-coded like the other tokens + ** so there is no single identifying attribute. So, instead just +diff --git a/testcases/crypto/rsa_func.c b/testcases/crypto/rsa_func.c +index 62aa7a76..8739ed37 100644 +--- a/testcases/crypto/rsa_func.c ++++ b/testcases/crypto/rsa_func.c +@@ -102,8 +102,8 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + free(s); + continue; + } +@@ -111,8 +111,7 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -124,8 +123,7 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("CCA Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -148,6 +146,16 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + continue; + } + } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp.='%s'", ++ s); ++ free(s); ++ continue; ++ } ++ } + // tpm special cases: + // tpm token can only use public exponent 0x010001 (65537) + // so skip test if invalid public exponent is used +@@ -155,8 +163,7 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) { +- testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'", +- s); ++ testcase_skip("TPM Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -166,8 +173,7 @@ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (!is_valid_icsf_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len) || + (tsuite->tv[i].modbits < 1024)) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -376,8 +382,8 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].mod_len * 8)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].mod_len * 8); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].mod_len * 8); + free(s); + continue; + } +@@ -385,16 +391,14 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } + // modulus length must be multiple of 128 byte + // skip test if modulus length has unsuported size + if ((tsuite->tv[i].mod_len % 128) != 0) { +- testcase_skip("EP11 Token cannot be used with " +- "this test vector."); ++ testcase_skip("EP11 Token cannot be used with this test vector."); + free(s); + continue; + } +@@ -416,8 +420,7 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + (tsuite->tv[i].exp2_len > + (tsuite->tv[i].mod_len / 2)) || + (tsuite->tv[i].coef_len > (tsuite->tv[i].mod_len / 2))) { +- testcase_skip("ICA Token cannot be used with " +- "this test vector."); ++ testcase_skip("ICA Token cannot be used with this test vector."); + free(s); + continue; + } +@@ -431,12 +434,21 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("CCA Token cannot be used with publ_exp.='%s'", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } + } ++ + // tpm special cases: + // tpm token can only use public exponent 0x010001 (65537) + // so skip test if invalid public exponent is used +@@ -444,8 +456,7 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].mod_len * 8))) { +- testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'", +- s); ++ testcase_skip("TPM Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -455,8 +466,7 @@ CK_RV do_EncryptDecryptImportRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) + if (!is_valid_icsf_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len) || + (tsuite->tv[i].mod_len * 8 < 1024)) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -691,8 +701,8 @@ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO * tsuite, + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + free(s); + continue; + } +@@ -700,8 +710,7 @@ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO * tsuite, + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -710,8 +719,16 @@ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO * tsuite, + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -721,8 +738,7 @@ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO * tsuite, + if ((!is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) { +- testcase_skip("TPM Token cannot " "be used with publ_exp='%s'.", +- s); ++ testcase_skip("TPM Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -732,8 +748,7 @@ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO * tsuite, + if (!is_valid_icsf_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len) || + (tsuite->tv[i].modbits < 1024)) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -944,16 +959,23 @@ CK_RV do_SignVerify_RSAPSS(struct GENERATED_TEST_SUITE_INFO * tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + free(s); + continue; + } + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -1154,8 +1176,8 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + continue; + } + // get public exponent from test vector +@@ -1169,8 +1191,7 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -1179,8 +1200,7 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + if (!is_valid_icsf_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len) || + (tsuite->tv[i].modbits < 1024)) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -1189,8 +1209,7 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) || + (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) { +- testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'", +- s); ++ testcase_skip("TPM Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -1198,8 +1217,7 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -1228,6 +1246,14 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO * tsuite) + continue; + } + } ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } + + // begin test + testcase_begin("%s Wrap Unwrap with test vector %d, " +@@ -1554,8 +1580,7 @@ CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + (tsuite->tv[i].exp2_len > + (tsuite->tv[i].mod_len / 2)) || + (tsuite->tv[i].coef_len > (tsuite->tv[i].mod_len / 2))) { +- testcase_skip("ICA Token cannot be used with " +- "this test vector."); ++ testcase_skip("ICA Token cannot be used with this test vector."); + continue; + } + +@@ -1565,8 +1590,7 @@ CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + // skip test if modulus length has unsuported size + if (is_ep11_token(slot_id)) { + if ((tsuite->tv[i].mod_len % 128) != 0) { +- testcase_skip("EP11 Token cannot be used with " +- "this test vector."); ++ testcase_skip("EP11 Token cannot be used with this test vector."); + continue; + } + } +@@ -1575,8 +1599,7 @@ CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].mod_len))) { +- testcase_skip("TPM Token cannot " +- "be used with this test vector."); ++ testcase_skip("TPM Token cannot be used with this test vector."); + continue; + } + } +@@ -1584,8 +1607,15 @@ CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with this test vector."); ++ testcase_skip("CCA Token cannot be used with this test vector."); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len)) { ++ testcase_skip("Soft Token cannot be used with this test vector."); + continue; + } + } +@@ -1735,8 +1765,7 @@ CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + // skip test if modulus length has unsuported size + if (is_ep11_token(slot_id)) { + if ((tsuite->tv[i].mod_len % 128) != 0) { +- testcase_skip("EP11 Token cannot be used with " +- "this test vector."); ++ testcase_skip("EP11 Token cannot be used with this test vector."); + continue; + } + } +@@ -1745,8 +1774,7 @@ CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].mod_len))) { +- testcase_skip("TPM Token cannot " +- "be used with this test vector."); ++ testcase_skip("TPM Token cannot be used with this test vector."); + continue; + } + } +@@ -1754,8 +1782,15 @@ CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with this test vector."); ++ testcase_skip("CCA Token cannot be used with this test vector."); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len)) { ++ testcase_skip("Soft Token cannot be used with this test vector."); + continue; + } + } +diff --git a/testcases/crypto/rsaupdate_func.c b/testcases/crypto/rsaupdate_func.c +index 20611b85..22f8d7e4 100644 +--- a/testcases/crypto/rsaupdate_func.c ++++ b/testcases/crypto/rsaupdate_func.c +@@ -96,8 +96,8 @@ CK_RV do_SignVerifyUpdateRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + free(s); + continue; + } +@@ -105,8 +105,7 @@ CK_RV do_SignVerifyUpdateRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -115,19 +114,27 @@ CK_RV do_SignVerifyUpdateRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } + } + ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ + if (is_tpm_token(slot_id)) { + if ((!is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) + || (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) { +- testcase_skip("TPM Token cannot " "be used with publ_exp='%s'.", +- s); ++ testcase_skip("TPM Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -137,8 +144,7 @@ CK_RV do_SignVerifyUpdateRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + if (!is_valid_icsf_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len) || + (tsuite->tv[i].modbits < 1024)) { +- testcase_skip("ICSF Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -162,8 +168,7 @@ CK_RV do_SignVerifyUpdateRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + tsuite->tv[i].publ_exp_len, + &publ_key, &priv_key); + if (rc != CKR_OK) { +- testcase_error("generate_RSA_PKCS_KeyPair(), " +- "rc=%s", p11_get_ckr(rc)); ++ testcase_error("generate_RSA_PKCS_KeyPair(), rc=%s", p11_get_ckr(rc)); + goto testcase_cleanup; + } + +@@ -367,8 +372,8 @@ CK_RV do_SignVerifyUpdate_RSAPSS(struct GENERATED_TEST_SUITE_INFO * tsuite) + + if (!keysize_supported(slot_id, tsuite->mech.mechanism, + tsuite->tv[i].modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", SLOT_ID, tsuite->tv[i].modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ SLOT_ID, tsuite->tv[i].modbits); + free(s); + continue; + } +@@ -376,8 +381,7 @@ CK_RV do_SignVerifyUpdate_RSAPSS(struct GENERATED_TEST_SUITE_INFO * tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -386,8 +390,16 @@ CK_RV do_SignVerifyUpdate_RSAPSS(struct GENERATED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].publ_exp, + tsuite->tv[i].publ_exp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].publ_exp, ++ tsuite->tv[i].publ_exp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -412,8 +424,7 @@ CK_RV do_SignVerifyUpdate_RSAPSS(struct GENERATED_TEST_SUITE_INFO * tsuite) + tsuite->tv[i].publ_exp_len, + &publ_key, &priv_key); + if (rc != CKR_OK) { +- testcase_error("generate_RSA_PKCS_KeyPair(), " +- "rc=%s", p11_get_ckr(rc)); ++ testcase_error("generate_RSA_PKCS_KeyPair(), rc=%s", p11_get_ckr(rc)); + goto error; + } + // generate message +@@ -639,8 +650,7 @@ CK_RV do_VerifyUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with pub_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with pub_exp.='%s'", s); + free(s); + continue; + } +@@ -650,8 +660,7 @@ CK_RV do_VerifyUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) || + (!is_valid_tpm_modbits(tsuite->tv[i].mod_len))) { +- testcase_skip("TPM Token cannot " +- "be used with pub_exp='%s'.", s); ++ testcase_skip("TPM Token cannot be used with pub_exp='%s'.", s); + free(s); + continue; + } +@@ -660,8 +669,16 @@ CK_RV do_VerifyUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +@@ -826,8 +843,7 @@ CK_RV do_SignUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + (tsuite->tv[i].exp2_len > + (tsuite->tv[i].mod_len / 2)) || + (tsuite->tv[i].coef_len > (tsuite->tv[i].mod_len / 2))) { +- testcase_skip("ICA Token cannot be used with " +- "this test vector."); ++ testcase_skip("ICA Token cannot be used with this test vector."); + free(s); + continue; + } +@@ -848,8 +864,7 @@ CK_RV do_SignUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("EP11 Token cannot " +- "be used with publ_exp.='%s'", s); ++ testcase_skip("EP11 Token cannot be used with publ_exp.='%s'", s); + free(s); + continue; + } +@@ -859,8 +874,7 @@ CK_RV do_SignUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if ((!is_valid_tpm_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) || + (!is_valid_tpm_modbits(tsuite->tv[i].mod_len))) { +- testcase_skip("TPM Token cannot " +- "be used with pub_exp='%s'.", s); ++ testcase_skip("TPM Token cannot be used with pub_exp='%s'.", s); + free(s); + continue; + } +@@ -869,8 +883,16 @@ CK_RV do_SignUpdateRSA(struct PUBLISHED_TEST_SUITE_INFO * tsuite) + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(tsuite->tv[i].pub_exp, + tsuite->tv[i].pubexp_len)) { +- testcase_skip("CCA Token cannot " +- "be used with publ_exp='%s'.", s); ++ testcase_skip("CCA Token cannot be used with publ_exp='%s'.", s); ++ free(s); ++ continue; ++ } ++ } ++ ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len)) { ++ testcase_skip("Soft Token cannot be used with publ_exp='%s'.", s); + free(s); + continue; + } +diff --git a/testcases/misc_tests/reencrypt.c b/testcases/misc_tests/reencrypt.c +index a78e1f5a..93fa31bd 100644 +--- a/testcases/misc_tests/reencrypt.c ++++ b/testcases/misc_tests/reencrypt.c +@@ -361,24 +361,29 @@ CK_RV do_reencrypt(struct mech_info *mech1, struct mech_info *mech2) + + if (!keysize_supported(slot_id, mech2->key_gen_mech.mechanism, + mech2->rsa_modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", slot_id, mech2->rsa_modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ slot_id, mech2->rsa_modbits); + goto testcase_cleanup; + } + + if (is_ep11_token(slot_id)) { + if (!is_valid_ep11_pubexp(mech2->rsa_publ_exp, + mech2->rsa_publ_exp_len)) { +- testcase_skip("EP11 Token in cannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("EP11 Token in cannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } + if (is_cca_token(slot_id)) { + if (!is_valid_cca_pubexp(mech2->rsa_publ_exp, + mech2->rsa_publ_exp_len)) { +- testcase_skip("CCA Token in cannot be used with " +- " publ_exp.='%s'", s); ++ testcase_skip("CCA Token in cannot be used with publ_exp.='%s'", s); ++ goto testcase_cleanup; ++ } ++ } ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(mech2->rsa_publ_exp, ++ mech2->rsa_publ_exp_len)) { ++ testcase_skip("Soft Token in cannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -386,8 +391,7 @@ CK_RV do_reencrypt(struct mech_info *mech1, struct mech_info *mech2) + if (!is_valid_tpm_pubexp(mech2->rsa_publ_exp, + mech2->rsa_publ_exp_len) || + !is_valid_tpm_modbits(mech2->rsa_modbits)) { +- testcase_skip("TPM Token cannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("TPM Token cannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -395,8 +399,7 @@ CK_RV do_reencrypt(struct mech_info *mech1, struct mech_info *mech2) + if (!is_valid_icsf_pubexp(mech2->rsa_publ_exp, + mech2->rsa_publ_exp_len) || + mech2->rsa_modbits < 1024) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + goto testcase_cleanup; + } + } +@@ -619,6 +622,14 @@ CK_RV do_encrypt_reencrypt(struct mech_info *mech1) + goto testcase_cleanup; + } + } ++ if (is_soft_token(slot_id)) { ++ if (!is_valid_soft_pubexp(mech1->rsa_publ_exp, ++ mech1->rsa_publ_exp_len)) { ++ testsuite_skip(NUM_REENCRYPT_TESTS, "Soft Token cannot be " ++ "used with publ_exp.='%s'", s); ++ goto testcase_cleanup; ++ } ++ } + if (is_tpm_token(slot_id) ) { + if (!is_valid_tpm_pubexp(mech1->rsa_publ_exp, + mech1->rsa_publ_exp_len) || +diff --git a/testcases/misc_tests/tok2tok_transport.c b/testcases/misc_tests/tok2tok_transport.c +index 9c1dee8f..ebb44760 100644 +--- a/testcases/misc_tests/tok2tok_transport.c ++++ b/testcases/misc_tests/tok2tok_transport.c +@@ -581,30 +581,35 @@ CK_RV do_wrap_key_test(struct wrapped_mech_info *tsuite, + + if (!keysize_supported(slot_id1, tsuite->wrapped_key_gen_mech.mechanism, + tsuite->rsa_modbits)) { +- testcase_skip("Token in slot %lu cannot be used with " +- "modbits.='%ld'", slot_id1, tsuite->rsa_modbits); ++ testcase_skip("Token in slot %lu cannot be used with modbits.='%ld'", ++ slot_id1, tsuite->rsa_modbits); + goto testcase_cleanup; + } + if (!keysize_supported(slot_id2, tsuite->wrapped_key_gen_mech.mechanism, + tsuite->rsa_modbits)) { +- testcase_skip("Token in slot %lu cannot be used with " +- "modbits.='%ld'", slot_id2, tsuite->rsa_modbits); ++ testcase_skip("Token in slot %lu cannot be used with modbits.='%ld'", ++ slot_id2, tsuite->rsa_modbits); + goto testcase_cleanup; + } + + if (is_ep11_token(slot_id1) || is_ep11_token(slot_id2)) { + if (!is_valid_ep11_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len)) { +- testcase_skip("EP11 Token in cannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("EP11 Token in cannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } + if (is_cca_token(slot_id1) || is_cca_token(slot_id2)) { + if (!is_valid_cca_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len)) { +- testcase_skip("CCA Token in scannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("CCA Token in scannot be used with publ_exp.='%s'", s); ++ goto testcase_cleanup; ++ } ++ } ++ if (is_soft_token(slot_id1) || is_cca_token(slot_id2)) { ++ if (!is_valid_soft_pubexp(tsuite->rsa_publ_exp, ++ tsuite->rsa_publ_exp_len)) { ++ testcase_skip("Soft Token in scannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -612,8 +617,7 @@ CK_RV do_wrap_key_test(struct wrapped_mech_info *tsuite, + if (!is_valid_tpm_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len) || + !is_valid_tpm_modbits(tsuite->rsa_modbits)) { +- testcase_skip("TPM Token cannot " "be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -621,8 +625,7 @@ CK_RV do_wrap_key_test(struct wrapped_mech_info *tsuite, + if (!is_valid_icsf_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len) || + tsuite->rsa_modbits < 1024) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + goto testcase_cleanup; + } + } +@@ -967,31 +970,36 @@ CK_RV do_wrapping_test(struct wrapping_mech_info *tsuite) + if (!keysize_supported(slot_id1, + tsuite->wrapping_key_gen_mech.mechanism, + tsuite->rsa_modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", slot_id1, tsuite->rsa_modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ slot_id1, tsuite->rsa_modbits); + goto testcase_cleanup; + } + if (!keysize_supported(slot_id2, + tsuite->wrapping_key_gen_mech.mechanism, + tsuite->rsa_modbits)) { +- testcase_skip("Token in slot %ld cannot be used with " +- "modbits.='%ld'", slot_id2, tsuite->rsa_modbits); ++ testcase_skip("Token in slot %ld cannot be used with modbits.='%ld'", ++ slot_id2, tsuite->rsa_modbits); + goto testcase_cleanup; + } + + if (is_ep11_token(slot_id1) || is_ep11_token(slot_id2)) { + if (!is_valid_ep11_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len)) { +- testcase_skip("EP11 Token in cannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("EP11 Token in cannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } + if (is_cca_token(slot_id1) || is_cca_token(slot_id2)) { + if (!is_valid_cca_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len)) { +- testcase_skip("CCA Token in scannot be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("CCA Token in scannot be used with publ_exp.='%s'", s); ++ goto testcase_cleanup; ++ } ++ } ++ if (is_soft_token(slot_id1) || is_soft_token(slot_id2)) { ++ if (!is_valid_soft_pubexp(tsuite->rsa_publ_exp, ++ tsuite->rsa_publ_exp_len)) { ++ testcase_skip("Soft Token in scannot be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -999,8 +1007,7 @@ CK_RV do_wrapping_test(struct wrapping_mech_info *tsuite) + if (!is_valid_tpm_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len) || + !is_valid_tpm_modbits(tsuite->rsa_modbits)) { +- testcase_skip("TPM Token cannot " "be used with " +- "publ_exp.='%s'", s); ++ testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'", s); + goto testcase_cleanup; + } + } +@@ -1008,8 +1015,7 @@ CK_RV do_wrapping_test(struct wrapping_mech_info *tsuite) + if (!is_valid_icsf_pubexp(tsuite->rsa_publ_exp, + tsuite->rsa_publ_exp_len) || + tsuite->rsa_modbits < 1024) { +- testcase_skip("ICSF Token cannot be used with " +- "publ_exp='%s'.", s); ++ testcase_skip("ICSF Token cannot be used with publ_exp='%s'.", s); + goto testcase_cleanup; + } + } diff --git a/opencryptoki.spec b/opencryptoki.spec index fdbc69a..94ab872 100644 --- a/opencryptoki.spec +++ b/opencryptoki.spec @@ -1,7 +1,7 @@ Name: opencryptoki Summary: Implementation of the PKCS#11 (Cryptoki) specification v2.11 Version: 3.16.0 -Release: 10%{?dist} +Release: 11%{?dist} License: CPL URL: https://github.com/opencryptoki/opencryptoki Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz @@ -35,6 +35,24 @@ Patch214: opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_ru Patch215: opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch Patch216: opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch Patch217: opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch +Patch218: opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch +Patch219: opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch +Patch220: opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch +Patch221: opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch +Patch222: opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch +Patch223: opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch +Patch224: opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch +Patch225: opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch +Patch226: opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch +Patch227: opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch +Patch228: opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch +Patch230: opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch +Patch231: opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch +Patch232: opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch +Patch233: opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch +Patch234: opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch +Patch235: opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch +Patch236: opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch Requires(pre): coreutils Requires: (selinux-policy >= 34.1.8-1 if selinux-policy-targeted) @@ -221,7 +239,6 @@ configured with Enterprise PKCS#11 (EP11) firmware. %install %make_install CHGRP=/bin/true -install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opencryptoki.module %pre libs @@ -280,10 +297,6 @@ fi %{_libdir}/pkcs11/libopencryptoki.so %{_libdir}/pkcs11/PKCS11_API.so %{_libdir}/pkcs11/stdll -# Co-owned with p11-kit -%dir %{_datadir}/p11-kit/ -%dir %{_datadir}/p11-kit/modules/ -%{_datadir}/p11-kit/modules/opencryptoki.module %files devel %{_includedir}/%{name}/ @@ -342,6 +355,9 @@ fi %changelog +* Mon Aug 23 2021 Than Ngo - 3.16.0-11 +- Resolves: #1989138, Support for OpenSSL 3.0 + * Thu Aug 19 2021 Than Ngo - 3.16.0-10 - Resolves: #1987186, pkcstok_migrate leaves options with multiple strings in opencryptoki.conf options without double-quotes