diff --git a/.gitignore b/.gitignore index 1230c18..088a728 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/opencryptoki-3.16.0.tar.gz +SOURCES/opencryptoki-3.17.0.tar.gz diff --git a/.opencryptoki.metadata b/.opencryptoki.metadata index 9c6b848..1ece19c 100644 --- a/.opencryptoki.metadata +++ b/.opencryptoki.metadata @@ -1 +1 @@ -e5d8cf8df446a9bdcb3658a8f191f5a31d3a751e SOURCES/opencryptoki-3.16.0.tar.gz +598f43d2a04a878a4577f143251f4631625ac49b SOURCES/opencryptoki-3.17.0.tar.gz diff --git a/SOURCES/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch b/SOURCES/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch deleted file mode 100644 index e7872d6..0000000 --- a/SOURCES/opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch +++ /dev/null @@ -1,136 +0,0 @@ -commit 19f56d12b302b87e1dacf613cc61a063ad209d15 -Author: Ingo Franzki -Date: Fri Feb 12 15:57:20 2021 +0100 - - Fix compile warning when compiling pkcsslotd with -DDEV and/or -DTHREADED - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcsslotd/garbage_linux.c b/usr/sbin/pkcsslotd/garbage_linux.c -index d4878c3b..a4dd9713 100644 ---- a/usr/sbin/pkcsslotd/garbage_linux.c -+++ b/usr/sbin/pkcsslotd/garbage_linux.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include "log.h" - #include "slotmgr.h" -@@ -80,8 +81,8 @@ BOOL StartGCThread(Slot_Mgr_Shr_t *MemPtr) - #ifdef DEV - // Only development builds - LogLog("StartGCThread: garbage collection thread started as ID " -- "%d (%#x) by ID %d (%#x)", -- GCThread, GCThread, pthread_self(), pthread_self()); -+ "%lu by ID %lu", -+ GCThread, pthread_self()); - #endif - - return TRUE; -@@ -115,8 +116,8 @@ BOOL StopGCThread(void *Ptr) - return FALSE; - } - -- DbgLog(DL0, "StopGCThread: tid %d is stopping the garbage collection " -- "thread (tid %d)", -+ DbgLog(DL0, "StopGCThread: tid %lu is stopping the garbage collection " -+ "thread (tid %lu)", - pthread_self(), GCThread); - - /* Cause the GC thread to be cancelled */ -@@ -245,7 +246,7 @@ void GCCancel(void *Ptr) - UNUSED(Ptr); - - /* Yeah, yeah. Doesn't do anything, but I had plans */ -- DbgLog(DL3, "GCCancel: tid: %d running cleanup routine", pthread_self()); -+ DbgLog(DL3, "GCCancel: tid: %lu running cleanup routine", pthread_self()); - - return; - } -@@ -268,7 +269,7 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - - ASSERT(MemPtr != NULL_PTR); - #ifdef DEV -- DbgLog(DL5, "Thread %d is checking for garbage", pthread_self()); -+ DbgLog(DL5, "Thread %lu is checking for garbage", pthread_self()); - #endif /* DEV */ - - -@@ -326,9 +327,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - if (*pProcSessions > 0) { - - #ifdef DEV -- DbgLog(DL2, "GC: Invalid pid (%d) is holding %d sessions " -+ DbgLog(DL2, "GC: Invalid pid (%d) is holding %u sessions " - "open on slot %d. Global session count for this " -- "slot is %d", -+ "slot is %u", - pProc->proc_id, *pProcSessions, SlotIndex, - *pGlobalSessions); - #endif /* DEV */ -@@ -338,9 +339,9 @@ BOOL CheckForGarbage(Slot_Mgr_Shr_t *MemPtr) - WarnLog("Garbage Collection: Illegal values in table " - "for defunct process"); - DbgLog(DL0, "Garbage collection: A process " -- "( Index: %d, pid: %d ) showed %d sessions " -- "open on slot %s, but the global count for this " -- "slot is only %d", -+ "( Index: %d, pid: %d ) showed %u sessions " -+ "open on slot %d, but the global count for this " -+ "slot is only %u", - ProcIndex, pProc->proc_id, *pProcSessions, - SlotIndex, *pGlobalSessions); - #endif /* DEV */ -@@ -395,14 +396,8 @@ int Stat2Proc(int pid, proc_t *p) - char fbuf[800]; // about 40 fields, 64-bit decimal is about 20 chars - char *tmp; - int fd, num; -- // FILE *fp; -- -- // sprintf(buf, "%s/%d/stat", PROC_BASE, pid); -- // if( (fp = fopen(buf, "r")) == NULL ) -- // return FALSE; - - sprintf(fbuf, "%s/%d/stat", PROC_BASE, pid); -- printf("Buff = %s \n", fbuf); - fflush(stdout); - if ((fd = open(fbuf, O_RDONLY, 0)) == -1) - return FALSE; -diff --git a/usr/sbin/pkcsslotd/log.c b/usr/sbin/pkcsslotd/log.c -index 0214f952..0394cc7d 100644 ---- a/usr/sbin/pkcsslotd/log.c -+++ b/usr/sbin/pkcsslotd/log.c -@@ -463,8 +463,8 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap) - #endif /* DEV */ - - if (WriteNow) { -- fprintf(stderr, "%s[%d.%d]: %s\n", pInfo->Descrip, getpid(), -- (int) pthread_self(), buf); -+ fprintf(stderr, "%s[%d.%lu]: %s\n", pInfo->Descrip, getpid(), -+ pthread_self(), buf); - } - } - -@@ -482,7 +482,7 @@ BOOL PKCS_Log(pLogHandle phLog, char *fmt, va_list ap) - GetCurrentTimeString(timebuf); - - /* Date/Time stamp, descrip, Error message */ -- fprintf(fd, "%s %s[%d.%d]: ", timebuf, pInfo->Descrip, getpid(), -+ fprintf(fd, "%s %s[%d.%lu]: ", timebuf, pInfo->Descrip, getpid(), - pthread_self()); - fprintf(fd, "%s\n", buf); - fflush(fd); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index 94288f13..efbfe8fd 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -660,7 +660,6 @@ int main(int argc, char *argv[], char *envp[]) - */ - - #if !defined(NOGARBAGE) -- printf("Start garbage \n"); - /* start garbage collection thread */ - if (!StartGCThread(shmp)) { - term_socket_server(); diff --git a/SOURCES/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch b/SOURCES/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch deleted file mode 100644 index 264f27d..0000000 --- a/SOURCES/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch +++ /dev/null @@ -1,2304 +0,0 @@ -commit 1fdd0e4497b0078e73e0004e3492db647c7c458b -Author: Ingo Franzki -Date: Wed Feb 24 15:47:05 2021 +0100 - - EP11: Handle APQN events to update APQN version, CP infos and target - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c -index 52f95d7a..728fedd5 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.c -+++ b/usr/lib/ep11_stdll/ep11_specific.c -@@ -38,6 +38,7 @@ - #include "ock_syslog.h" - #include "ec_defs.h" - #include "p11util.h" -+#include "events.h" - - #include - #include -@@ -197,19 +198,27 @@ typedef struct { - - #define MAX_RETRY_COUNT 100 - --#define RETRY_START do { \ -+#define RETRY_START(rc, tokdata) \ -+ do { \ - int retry_count; \ -+ ep11_target_info_t* target_info = \ -+ get_target_info((tokdata)); \ -+ if (target_info == NULL) \ -+ (rc) = CKR_FUNCTION_FAILED; \ - for(retry_count = 0; \ -+ target_info != NULL && \ - retry_count < MAX_RETRY_COUNT; \ - retry_count ++) { - - #define RETRY_END(rc, tokdata, session) if ((rc) != CKR_SESSION_CLOSED) \ - break; \ - (rc) = ep11tok_relogin_session( \ -- tokdata, session); \ -+ (tokdata), (session)); \ - if ((rc) != CKR_OK) \ - break; \ - } \ -+ put_target_info((tokdata), \ -+ target_info); \ - } while (0); - - #define CKF_EP11_HELPER_SESSION 0x80000000 -@@ -248,7 +257,6 @@ typedef struct ep11_card_version { - } ep11_card_version_t; - - static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version); --static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata); - static void free_card_versions(ep11_card_version_t *card_version); - static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - const CK_VERSION *ep11_lib_version, -@@ -476,16 +484,23 @@ static CK_RV handle_all_ep11_cards(ep11_target_t * ep11_targets, - #define PKEY_MODE_ENABLE4NONEXTR 2 - - typedef struct { -+ volatile unsigned long ref_count; - target_t target; -+ ep11_card_version_t *card_versions; -+ CK_ULONG used_firmware_API_version; -+ unsigned char control_points[XCP_CP_BYTES]; -+ size_t control_points_len; -+ size_t max_control_point_index; -+ CK_CHAR serialNumber[16]; -+} ep11_target_info_t; -+ -+typedef struct { - ep11_target_t target_list; - CK_BYTE raw2key_wrap_blob[MAX_BLOBSIZE]; - size_t raw2key_wrap_blob_l; - int cka_sensitive_default_true; - char cp_filter_config_filename[PATH_MAX]; - cp_config_t *cp_config; -- unsigned char control_points[XCP_CP_BYTES]; -- size_t control_points_len; -- size_t max_control_point_index; - int strict_mode; - int vhsm_mode; - int optimize_single_ops; -@@ -497,12 +512,14 @@ typedef struct { - char digest_libica_path[PATH_MAX]; - libica_t libica; - CK_VERSION ep11_lib_version; -- ep11_card_version_t *card_versions; -- CK_ULONG used_firmware_API_version; -- CK_CHAR serialNumber[16]; -+ volatile ep11_target_info_t *target_info; -+ pthread_rwlock_t target_rwlock; - } ep11_private_data_t; - --static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata); -+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata); -+static void put_target_info(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info); -+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata); - - static CK_RV get_ep11_target_for_apqn(uint_32 adapter, uint_32 domain, - target_t *target, uint64_t flags); -@@ -704,8 +721,13 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata) - CK_BYTE blob[MAX_BLOBSIZE]; - size_t blobsize = sizeof(blob); - CK_ATTRIBUTE *pkey_attr = NULL, *blob_attr=NULL; -+ ep11_target_info_t* target_info; - CK_RV ret; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - /* Check if CPACF_WRAP mech supported */ - if (ep11tok_is_mechanism_supported(tokdata, CKM_IBM_CPACF_WRAP) != CKR_OK) { - TRACE_INFO("CKM_IBM_CPACF_WRAP not supported on this system.\n"); -@@ -717,7 +739,7 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata) - - /* Create an AES testkey with CKA_IBM_PROTKEY_EXTRACTABLE */ - ret = dll_m_GenerateKey(&mech, tmpl, tmpl_len, NULL, 0, -- blob, &blobsize, csum, &csum_l, ep11_data->target); -+ blob, &blobsize, csum, &csum_l, target_info->target); - if (ret != CKR_OK) { - TRACE_ERROR("dll_m_GenerateKey failed with rc=0x%lx\n",ret); - goto done; -@@ -749,6 +771,8 @@ done: - if (blob_attr) - free(blob_attr); - -+ put_target_info(tokdata, target_info); -+ - return ret; - } - -@@ -1337,7 +1361,7 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata, - OBJECT *obj, - CK_KEY_TYPE keytype) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; - CK_RV rc; - CK_BBOOL trusted, encrypt, decrypt, wrap, unwrap, sign, sign_recover, - verify, verify_recover, derive, extractable, local, -@@ -1367,9 +1391,16 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata, - CK_ATTRIBUTE *attr; - CK_BBOOL cktrue = TRUE; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - rc = dll_m_GetAttributeValue(blob, blob_len, attrs, - sizeof(attrs) / sizeof(CK_ATTRIBUTE), -- ep11_data->target); -+ target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - TRACE_ERROR("Retrieving attributes from AB unwrapped key failed, rc=0x%lx\n", - rc); -@@ -2117,10 +2148,10 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess, - * calls the ep11 lib (which in turns sends the request to the card), - * all m_ function are ep11 functions - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, &mech, key, -- ksize, cipher, &clen, ep11_data->target); -+ ksize, cipher, &clen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2146,12 +2177,12 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess, - /* the encrypted key is decrypted and a blob is build, - * card accepts only blobs as keys - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, clen, ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, ep11_pin_blob_len, &mech, - new_p_attrs, new_attrs_len, blob, blen, csum, -- &cslen, ep11_data->target); -+ &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2194,14 +2225,20 @@ rawkey_2_blob_end: - CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output, - CK_ULONG bytes) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - -- CK_RV rc = dll_m_GenerateRandom(output, bytes, ep11_data->target); -+ CK_RV rc = dll_m_GenerateRandom(output, bytes, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s output=%p bytes=%lu rc=0x%lx\n", - __func__, (void *)output, bytes, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -2215,6 +2252,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; -+ ep11_target_info_t* target_info; - CK_BYTE csum[MAX_CSUMSIZE]; - size_t csum_l = sizeof(csum); - CK_RV rc; -@@ -2225,11 +2263,15 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - return CKR_OK; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - ep11_data->raw2key_wrap_blob_l = sizeof(ep11_data->raw2key_wrap_blob); - rc = dll_m_GenerateKey(&mech, tmpl_in, tmpl_len, NULL, 0, - ep11_data->raw2key_wrap_blob, - &ep11_data->raw2key_wrap_blob_l, csum, &csum_l, -- ep11_data->target); -+ target_info->target); - - - if (rc != CKR_OK) { -@@ -2240,6 +2282,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in, - __func__, ep11_data->raw2key_wrap_blob_l, rc); - } - -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -2479,6 +2522,14 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - if (ep11_data == NULL) - return CKR_HOST_MEMORY; - -+ if (pthread_rwlock_init(&ep11_data->target_rwlock, NULL) != 0) { -+ TRACE_DEVEL("Target Lock init failed.\n"); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to initialize the target lock\n", -+ __func__); -+ rc = CKR_CANT_LOCK; -+ goto error; -+ } -+ - tokdata->private_data = ep11_data; - - /* read ep11 specific config file with user specified -@@ -2513,13 +2564,28 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - } - #endif - -- rc = ep11tok_get_ep11_version(tokdata); -- if (rc != CKR_OK) -+ rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the Ep11 library version " -+ "(ep11tok_get_ep11_library_version rc=0x%lx)\n", __func__, -+ rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the EP11 library version " -+ "rc=0x%lx\n", __func__, rc); - goto error; -+ } - -- rc = ep11tok_setup_target(tokdata); -- if (rc != CKR_OK) -+ TRACE_INFO("%s Host library version: %d.%d\n", __func__, -+ ep11_data->ep11_lib_version.major, -+ ep11_data->ep11_lib_version.minor); -+ -+ rc = refresh_target_info(tokdata); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the target info (refresh_target_info " -+ "rc=0x%lx)\n", __func__, rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n", -+ __func__, rc); - goto error; -+ } - - if (ep11_data->digest_libica) { - rc = ep11tok_load_libica(tokdata); -@@ -2530,18 +2596,6 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber, - ep11_data->msa_level = get_msa_level(); - TRACE_INFO("MSA level = %i\n", ep11_data->msa_level); - -- ep11_data->control_points_len = sizeof(ep11_data->control_points); -- rc = get_control_points(tokdata, ep11_data->control_points, -- &ep11_data->control_points_len, -- &ep11_data->max_control_point_index); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s Failed to get the control points (get_control_points " -- "rc=0x%lx)\n", __func__, rc); -- OCK_SYSLOG(LOG_ERR, "%s: Failed to get the control points rc=0x%lx\n", -- __func__, rc); -- goto error; -- } -- - /* create an AES key needed for importing keys - * (encrypt by wrap_key and m_UnwrapKey by wrap key) - */ -@@ -2600,10 +2654,14 @@ CK_RV ep11tok_final(STDLL_TokData_t * tokdata) - TRACE_INFO("ep11 %s running\n", __func__); - - if (ep11_data != NULL) { -- if (dll_m_rm_module != NULL) -- dll_m_rm_module(NULL, ep11_data->target); -+ if (ep11_data->target_info != NULL) { -+ if (dll_m_rm_module != NULL) -+ dll_m_rm_module(NULL, ep11_data->target_info->target); -+ free_card_versions(ep11_data->target_info->card_versions); -+ free((void* )ep11_data->target_info); -+ } -+ pthread_rwlock_destroy(&ep11_data->target_rwlock); - free_cp_config(ep11_data->cp_config); -- free_card_versions(ep11_data->card_versions); - free(ep11_data); - tokdata->private_data = NULL; - } -@@ -2619,7 +2677,6 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess, - CK_BYTE *spki, CK_ULONG spki_len, - CK_BYTE *maced_spki, CK_ULONG *maced_spki_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - unsigned char *ep11_pin_blob = NULL; - CK_ULONG ep11_pin_blob_len = 0; - ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data; -@@ -2712,11 +2769,11 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess, - ep11_get_pin_blob(ep11_session, object_is_session_object(pub_key_obj), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(spki, spki_len, NULL, 0, NULL, 0, - ep11_pin_blob, ep11_pin_blob_len, &mech, - p_attrs, attrs_len, maced_spki, maced_spki_len, -- csum, &cslen, ep11_data->target); -+ csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -2870,11 +2927,11 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, &mech_w, - data, data_len, cipher, &cipher_l, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -2901,12 +2958,12 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private RSA key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, blob_size, -- csum, &cslen, ep11_data->target); -+ csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3101,11 +3158,11 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3133,14 +3190,14 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3295,11 +3352,11 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - -@@ -3327,14 +3384,14 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3478,11 +3535,11 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3509,14 +3566,14 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private EC key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3666,11 +3723,11 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, - } - - /* encrypt */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, - &mech_w, data, data_len, -- cipher, &cipher_l, ep11_data->target); -+ cipher, &cipher_l, target_info->target); - RETRY_END(rc, tokdata, sess) - - TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n", -@@ -3699,14 +3756,14 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess, - /* calls the card, it decrypts the private Dilithium key, - * reads its BER format and builds a blob. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(cipher, cipher_l, - ep11_data->raw2key_wrap_blob, - ep11_data->raw2key_wrap_blob_l, NULL, ~0, - ep11_pin_blob, - ep11_pin_blob_len, &mech_w, - new_p_attrs, new_attrs_len, blob, -- blob_size, csum, &cslen, ep11_data->target); -+ blob_size, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -3884,7 +3941,6 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM_PTR mech, CK_ATTRIBUTE_PTR attrs, - CK_ULONG attrs_len, CK_OBJECT_HANDLE_PTR handle) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_BYTE blob[MAX_BLOBSIZE]; - size_t blobsize = sizeof(blob); - CK_BYTE csum[MAX_CSUMSIZE]; -@@ -3936,10 +3992,10 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session, - ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKey(mech, new_attrs2, new_attrs2_len, ep11_pin_blob, - ep11_pin_blob_len, blob, &blobsize, -- csum, &csum_len, ep11_data->target); -+ csum, &csum_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4354,6 +4410,7 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - size_t state_len = MAX(MAX_DIGEST_STATE_BYTES, sizeof(libica_sha_context_t)); - CK_BYTE *state; - libica_sha_context_t *libica_ctx; -+ ep11_target_info_t* target_info; - - state = calloc(state_len, 1); /* freed by dig_mgr.c */ - if (!state) { -@@ -4361,15 +4418,21 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - return CKR_HOST_MEMORY; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - if (ep11tok_libica_digest_available(ep11_data, mech->mechanism)) { - libica_ctx = (libica_sha_context_t *)state; - state_len = sizeof(libica_sha_context_t); - libica_ctx->first = CK_TRUE; - rc = get_sha_block_size(mech->mechanism, &libica_ctx->block_size); - } else { -- rc = dll_m_DigestInit(state, &state_len, mech, ep11_data->target); -+ rc = dll_m_DigestInit(state, &state_len, mech, target_info->target); - } - -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); -@@ -4399,6 +4462,11 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism, -@@ -4408,7 +4476,7 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - SHA_MSG_PART_ONLY); - } else { - rc = dll_m_Digest(c->context, c->context_len, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - } - - if (rc != CKR_OK) { -@@ -4417,6 +4485,8 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - } else { - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4430,6 +4500,11 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - CK_ULONG out_len = sizeof(temp_out); - CK_ULONG len; - CK_RV rc = CKR_OK; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - if (libica_ctx->offset > 0 || in_data_len < libica_ctx->block_size) { -@@ -4479,7 +4554,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - } - } else { - rc = dll_m_DigestUpdate(c->context, c->context_len, -- in_data, in_data_len, ep11_data->target); -+ in_data, in_data_len, target_info->target); - } - - out: -@@ -4489,6 +4564,8 @@ out: - } else { - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } -+ -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4499,6 +4576,11 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - ep11_private_data_t *ep11_data = tokdata->private_data; - libica_sha_context_t *libica_ctx = (libica_sha_context_t *)c->context; - CK_RV rc; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) { - rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism, -@@ -4510,7 +4592,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - SHA_MSG_PART_FINAL); - } else { - rc = dll_m_DigestFinal(c->context, c->context_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - } - - if (rc != CKR_OK) { -@@ -4520,6 +4602,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c, - TRACE_INFO("%s rc=0x%lx\n", __func__, rc); - } - -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -4528,7 +4611,6 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG *out_data_len, - OBJECT *key_obj) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -4544,9 +4626,9 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4563,7 +4645,6 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *signature, CK_ULONG sig_len, - OBJECT *key_obj) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -4579,9 +4660,9 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4598,7 +4679,6 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *sig, CK_ULONG *sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -4616,9 +4696,9 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.ulParameterLen = ctx->mech.ulParameterLen; - mech.pParameter = ctx->mech.pParameter; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- sig, sig_len, ep11_data->target); -+ sig, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4638,7 +4718,6 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -4656,9 +4735,9 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.ulParameterLen = ctx->mech.ulParameterLen; - mech.pParameter = ctx->mech.pParameter; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4678,7 +4757,6 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG *out_data_len, - OBJECT *key_obj ) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - SIGN_VERIFY_CONTEXT *ctx = &(session->sign_ctx); - CK_RV rc; - size_t keyblobsize = 0; -@@ -4707,9 +4785,9 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4728,7 +4806,6 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *out_data, CK_ULONG out_data_len, - OBJECT *key_obj ) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - SIGN_VERIFY_CONTEXT *ctx = &(session->verify_ctx); - CK_RV rc; - CK_BYTE *spki; -@@ -4757,9 +4834,9 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION *session, - mech.pParameter = NULL; - mech.ulParameterLen = 0; - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4784,7 +4861,6 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata, - CK_BYTE *in_data, CK_ULONG in_data_len, - CK_BYTE *out_data, CK_ULONG *out_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *decr_key, *encr_key; - size_t decr_key_len = 0, encr_key_len = 0; -@@ -4813,10 +4889,10 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_ReencryptSingle(decr_key, decr_key_len, encr_key, encr_key_len, - decr_mech, encr_mech, in_data, in_data_len, -- out_data, out_data_len, ep11_data->target); -+ out_data, out_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -4892,7 +4968,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs, - CK_ULONG attrs_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *keyblob; - size_t keyblobsize; -@@ -4920,6 +4995,8 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_ULONG privlen; - int curve_type; - CK_BBOOL allocated = FALSE; -+ ep11_target_info_t* target_info; -+ CK_ULONG used_firmware_API_version; - - memset(newblob, 0, sizeof(newblob)); - -@@ -5009,7 +5086,15 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - * then we can pass the mechanism parameters as-is, otherwise we still - * need to use the old way. - */ -- if (ep11_data->used_firmware_API_version <= 2) { -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ -+ used_firmware_API_version = target_info->used_firmware_API_version; -+ -+ put_target_info(tokdata, target_info); -+ -+ if (used_firmware_API_version <= 2) { - if (ecdh1_parms->kdf != CKD_NULL) { - TRACE_ERROR("%s KDF for CKM_ECDH1_DERIVE not supported: %lu\n", - __func__, ecdh1_parms->kdf); -@@ -5133,11 +5218,11 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session, - ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = - dll_m_DeriveKey(mech, new_attrs2, new_attrs2_len, keyblob, keyblobsize, - NULL, 0, ep11_pin_blob, ep11_pin_blob_len, newblob, -- &newblobsize, csum, &cslen, ep11_data->target); -+ &newblobsize, csum, &cslen, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -5231,7 +5316,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE publblob[MAX_BLOBSIZE]; - size_t publblobsize = sizeof(publblob); -@@ -5418,13 +5502,13 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs, new_publ_attrs_len, - new_priv_attrs, new_priv_attrs_len, - ep11_pin_blob, ep11_pin_blob_len, - privblob, &privblobsize, -- publblob, &publblobsize, ep11_data->target); -+ publblob, &publblobsize, target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -5543,7 +5627,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE publblob[MAX_BLOBSIZE]; - size_t publblobsize = sizeof(publblob); -@@ -5752,13 +5835,13 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, privblob, - &privblobsize, publblob, &publblobsize, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, sess) - - if (rc != CKR_OK) { -@@ -5866,7 +5949,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_ATTRIBUTE *attr = NULL; - CK_ATTRIBUTE *n_attr = NULL; -@@ -5967,13 +6049,13 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, - privkey_blob, &privkey_blob_len, spki, -- &spki_len, ep11_data->target); -+ &spki_len, target_info->target); - RETRY_END(rc, tokdata, sess) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, sess); -@@ -6225,7 +6307,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata, - CK_ULONG ulPrivateKeyAttributeCount, - CK_SESSION_HANDLE h) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_ATTRIBUTE *attr = NULL; - CK_BYTE privkey_blob[MAX_BLOBSIZE]; -@@ -6308,13 +6389,13 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata, - ulPrivateKeyAttributeCount)), - &ep11_pin_blob, &ep11_pin_blob_len); - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_GenerateKeyPair(pMechanism, - new_publ_attrs2, new_publ_attrs2_len, - new_priv_attrs2, new_priv_attrs2_len, - ep11_pin_blob, ep11_pin_blob_len, - privkey_blob, &privkey_blob_len, spki, -- &spki_len, ep11_data->target); -+ &spki_len, target_info->target); - RETRY_END(rc, tokdata, sess) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, sess); -@@ -6914,7 +6995,6 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM * mech, CK_BBOOL recover_mode, - CK_OBJECT_HANDLE key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - size_t keyblobsize = 0; - CK_BYTE *keyblob; -@@ -6980,9 +7060,9 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignInit(ep11_sign_state, &ep11_sign_state_l, -- mech, keyblob, keyblobsize, ep11_data->target); -+ mech, keyblob, keyblobsize, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7017,7 +7097,6 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - CK_ULONG in_data_len, CK_BYTE * signature, - CK_ULONG * sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7049,9 +7128,9 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Sign(ctx->context, ctx->context_len, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7073,7 +7152,6 @@ done: - CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7095,9 +7173,9 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data, -- in_data_len, ep11_data->target); -+ in_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7120,7 +7198,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BBOOL length_only, CK_BYTE * signature, - CK_ULONG * sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx; - size_t keyblobsize = 0; -@@ -7139,9 +7216,9 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7169,7 +7246,6 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7186,9 +7262,9 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_SignSingle(keyblob, keyblobsize, mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7209,7 +7285,6 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM * mech, CK_BBOOL recover_mode, - CK_OBJECT_HANDLE key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *spki; - size_t spki_len = 0; -@@ -7285,9 +7360,9 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyInit(ep11_sign_state, &ep11_sign_state_l, mech, -- spki, spki_len, ep11_data->target); -+ spki, spki_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7320,7 +7395,6 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len, - CK_BYTE * signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7353,9 +7427,9 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Verify(ctx->context, ctx->context_len, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7377,7 +7451,6 @@ done: - CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * in_data, CK_ULONG in_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7399,9 +7472,9 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data, -- in_data_len, ep11_data->target); -+ in_data_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7423,7 +7496,6 @@ done: - CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE * signature, CK_ULONG sig_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx; - size_t keyblobsize = 0; -@@ -7442,9 +7514,9 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature, -- sig_len, ep11_data->target); -+ sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7471,7 +7543,6 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session, - CK_BYTE *spki; - size_t spki_len = 0; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - rc = h_opaque_2_blob(tokdata, key, &spki, &spki_len, &key_obj, READ_LOCK); - if (rc != CKR_OK) { -@@ -7495,9 +7566,9 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_VerifySingle(spki, spki_len, mech, in_data, in_data_len, -- signature, sig_len, ep11_data->target); -+ signature, sig_len, target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7517,7 +7588,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7538,10 +7608,10 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7564,7 +7634,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR input_data, CK_ULONG input_data_len, - CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE); -@@ -7586,10 +7655,10 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7613,7 +7682,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7640,10 +7708,10 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -- p_output_part_len, ep11_data->target); -+ p_output_part_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7671,7 +7739,6 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7688,10 +7755,10 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptSingle(keyblob, keyblobsize, mech, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7711,7 +7778,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7732,10 +7798,10 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7758,7 +7824,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR input_data, CK_ULONG input_data_len, - CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE); -@@ -7780,10 +7845,10 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7807,7 +7872,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE_PTR output_part, - CK_ULONG_PTR p_output_part_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - ENCR_DECR_CONTEXT *ctx = &session->encr_ctx; - CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE); -@@ -7834,10 +7898,10 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -- p_output_part_len, ep11_data->target); -+ p_output_part_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -7865,7 +7929,6 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - size_t keyblobsize = 0; - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; -- ep11_private_data_t *ep11_data = tokdata->private_data; - - UNUSED(length_only); - -@@ -7893,10 +7956,10 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session, - goto done; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptSingle(keyblob, keyblobsize, mech, input_data, - input_data_len, output_data, p_output_data_len, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -7916,7 +7979,6 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key, - int op) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = CKR_OK; - CK_BYTE *blob; - size_t blob_len = 0; -@@ -7979,9 +8041,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - - if (op == DECRYPT) { - ENCR_DECR_CONTEXT *ctx = &session->decr_ctx; -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_DecryptInit(ep11_state, &ep11_state_l, mech, blob, -- blob_len, ep11_data->target); -+ blob_len, target_info->target); - RETRY_END(rc, tokdata, session) - ctx->key = key; - ctx->active = TRUE; -@@ -8012,9 +8074,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - goto error; - } - -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_EncryptInit(ep11_state, &ep11_state_l, mech, blob, -- blob_len, ep11_data->target); -+ blob_len, target_info->target); - RETRY_END(rc, tokdata, session) - ctx->key = key; - ctx->active = TRUE; -@@ -8092,7 +8154,6 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE key, CK_BYTE_PTR wrapped_key, - CK_ULONG_PTR p_wrapped_key_len) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *wrapping_blob; - size_t wrapping_blob_len; -@@ -8192,11 +8253,11 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session, - * (wrapping blob). The wrapped key can be processed by any PKCS11 - * implementation. - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = - dll_m_WrapKey(wrap_target_blob, wrap_target_blob_len, wrapping_blob, - wrapping_blob_len, sign_blob, sign_blob_len, mech, -- wrapped_key, p_wrapped_key_len, ep11_data->target); -+ wrapped_key, p_wrapped_key_len, target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -8228,7 +8289,6 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session, - CK_OBJECT_HANDLE wrapping_key, - CK_OBJECT_HANDLE_PTR p_key) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - CK_BYTE *wrapping_blob, *temp; - size_t wrapping_blob_len; -@@ -8388,13 +8448,13 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session, - /* we need a blob for the new key created by unwrapping, - * the wrapped key comes in BER - */ -- RETRY_START -+ RETRY_START(rc, tokdata) - rc = dll_m_UnwrapKey(wrapped_key, wrapped_key_len, wrapping_blob, - wrapping_blob_len, verifyblob, verifyblobsize, - ep11_pin_blob, - ep11_pin_blob_len, mech, new_attrs2, new_attrs2_len, - keyblob, &keyblobsize, csum, &cslen, -- ep11_data->target); -+ target_info->target); - RETRY_END(rc, tokdata, session) - - if (rc != CKR_OK) { -@@ -8657,21 +8717,25 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - CK_MECHANISM_TYPE_PTR pMechanismList, - CK_ULONG_PTR pulCount) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc = 0; - CK_ULONG counter = 0, size = 0; - CK_MECHANISM_TYPE_PTR mlist = NULL; - CK_ULONG i; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - /* size querry */ - if (pMechanismList == NULL) { - rc = dll_m_GetMechanismList(0, pMechanismList, pulCount, -- ep11_data->target); -+ target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #1\n", - __func__, rc); -- return rc; -+ goto out; - } - - /* adjust the size according to the ban list, -@@ -8693,16 +8757,16 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - sizeof(CK_MECHANISM_TYPE) * counter); - if (!mlist) { - TRACE_ERROR("%s Memory allocation failed\n", __func__); -- return CKR_HOST_MEMORY; -+ rc = CKR_HOST_MEMORY; -+ goto out; - } -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #2\n", - __func__, rc); -- free(mlist); - if (rc != CKR_BUFFER_TOO_SMALL) -- return rc; -+ goto out; - } - } while (rc == CKR_BUFFER_TOO_SMALL); - -@@ -8722,12 +8786,12 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - * that comes as parameter, this is a 'reduced size', - * ep11 would complain about insufficient list size - */ -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #3\n", - __func__, rc); -- return rc; -+ goto out; - } - - /* -@@ -8744,17 +8808,17 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - sizeof(CK_MECHANISM_TYPE) * counter); - if (!mlist) { - TRACE_ERROR("%s Memory allocation failed\n", __func__); -- return CKR_HOST_MEMORY; -+ rc = CKR_HOST_MEMORY; -+ goto out; - } - /* all the card has */ -- rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target); -+ rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target); - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #4\n", - __func__, rc); -- free(mlist); - if (rc != CKR_BUFFER_TOO_SMALL) -- return rc; -+ goto out; - } - } while (rc == CKR_BUFFER_TOO_SMALL); - -@@ -8775,8 +8839,10 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata, - rc = CKR_BUFFER_TOO_SMALL; - } - -+out: - if (mlist) - free(mlist); -+ put_target_info(tokdata, target_info); - return rc; - } - -@@ -8790,6 +8856,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - CK_BBOOL found = FALSE; - CK_ULONG i; - int status; -+ CK_RV rc = CKR_OK; -+ ep11_target_info_t* target_info; - - for (i = 0; i < supported_mech_list_len; i++) { - if (type == ep11_supported_mech_list[i]) { -@@ -8804,13 +8872,18 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - return CKR_MECHANISM_INVALID; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - if (check_cps_for_mechanism(ep11_data->cp_config, -- type, ep11_data->control_points, -- ep11_data->control_points_len, -- ep11_data->max_control_point_index) != CKR_OK) { -+ type, target_info->control_points, -+ target_info->control_points_len, -+ target_info->max_control_point_index) != CKR_OK) { - TRACE_INFO("%s Mech '%s' banned due to control point\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - - switch(type) { -@@ -8840,14 +8913,17 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status == -1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - - case CKM_RSA_PKCS_OAEP: - /* CKM_RSA_PKCS_OAEP is not supported with EP11 host library <= 1.3 */ -- if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0) -- return CKR_MECHANISM_INVALID; -+ if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0) { -+ rc = CKR_MECHANISM_INVALID; -+ goto out; -+ } - break; - - case CKM_IBM_SHA3_224: -@@ -8863,7 +8939,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8876,7 +8953,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8887,7 +8965,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) < 0) { - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - - status = check_required_versions(tokdata, edwards_req_versions, -@@ -8895,7 +8974,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8903,14 +8983,16 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) <= 0) { - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - status = check_required_versions(tokdata, ibm_dilithium_req_versions, - NUM_DILITHIUM_REQ); - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - -@@ -8919,19 +9001,23 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata, - TRACE_INFO("%s Mech '%s' banned due to host library version\n", - __func__, ep11_get_ckm(type)); - -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - status = check_required_versions(tokdata, ibm_cpacf_wrap_req_versions, - NUM_CPACF_WRAP_REQ); - if (status != 1) { - TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n", - __func__, ep11_get_ckm(type)); -- return CKR_MECHANISM_INVALID; -+ rc = CKR_MECHANISM_INVALID; -+ goto out; - } - break; - } - -- return CKR_OK; -+out: -+ put_target_info(tokdata, target_info); -+ return rc; - } - - CK_RV ep11tok_is_mechanism_supported_ex(STDLL_TokData_t *tokdata, -@@ -8976,9 +9062,9 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata, - CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_RV rc; - int status; -+ ep11_target_info_t* target_info; - - rc = ep11tok_is_mechanism_supported(tokdata, type); - if (rc != CKR_OK) { -@@ -8987,7 +9073,14 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata, - return rc; - } - -- rc = dll_m_GetMechanismInfo(0, type, pInfo, ep11_data->target); -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ -+ rc = dll_m_GetMechanismInfo(0, type, pInfo, target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s m_GetMechanismInfo(0x%lx) failed with rc=0x%lx\n", -@@ -10265,6 +10358,11 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata, - CK_MECHANISM mech; - CK_ULONG len; - libica_sha_context_t ctx; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - session_id_data.handle = session->handle; - gettimeofday(&session_id_data.timeofday, NULL); -@@ -10286,7 +10384,9 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata, - rc = dll_m_DigestSingle(&mech, (CK_BYTE_PTR)&session_id_data, - sizeof(session_id_data), - ep11_session->session_id, &len, -- ep11_data->target); -+ target_info->target); -+ -+ put_target_info(tokdata, target_info); - - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, session); -@@ -10964,7 +11064,7 @@ static CK_RV get_card_type(uint_32 adapter, CK_ULONG *type) - - typedef struct query_version - { -- ep11_private_data_t *ep11_data; -+ ep11_target_info_t *target_info; - CK_CHAR serialNumber[16]; - CK_BBOOL first; - CK_BBOOL error; -@@ -11005,7 +11105,7 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain, - } - - /* Try to find existing version info for this card type */ -- card_version = qv->ep11_data->card_versions; -+ card_version = qv->target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type == card_type) - break; -@@ -11050,8 +11150,8 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain, - card_version->firmware_version = xcp_info.firmwareVersion; - #endif - -- card_version->next = qv->ep11_data->card_versions; -- qv->ep11_data->card_versions = card_version; -+ card_version->next = qv->target_info->card_versions; -+ qv->target_info->card_versions = card_version; - } else { - /* - * Version info for this card type is already available, so check this -@@ -11134,23 +11234,16 @@ static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version) - return CKR_OK; - } - --static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) -+static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) - { - ep11_private_data_t *ep11_data = tokdata->private_data; - ep11_card_version_t *card_version; - query_version_t qv; - CK_RV rc; - -- rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version); -- if (rc != CKR_OK) -- return rc; -- -- TRACE_INFO("%s Host library version: %d.%d\n", __func__, -- ep11_data->ep11_lib_version.major, -- ep11_data->ep11_lib_version.minor); -- - memset(&qv, 0, sizeof(qv)); -- qv.ep11_data = ep11_data; -+ qv.target_info = target_info; - qv.first = TRUE; - - rc = handle_all_ep11_cards(&ep11_data->target_list, version_query_handler, -@@ -11169,18 +11262,18 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) - return CKR_DEVICE_ERROR; - } - -- memcpy(ep11_data->serialNumber, qv.serialNumber, -- sizeof(ep11_data->serialNumber)); -+ memcpy(target_info->serialNumber, qv.serialNumber, -+ sizeof(target_info->serialNumber)); - -- TRACE_INFO("%s Serial number: %.16s\n", __func__, ep11_data->serialNumber); -+ TRACE_INFO("%s Serial number: %.16s\n", __func__, target_info->serialNumber); - - /* EP11 host lib version <= 2 only support API version 2 */ - if (ep11_data->ep11_lib_version.major <= 2) -- ep11_data->used_firmware_API_version = 2; -+ target_info->used_firmware_API_version = 2; - else -- ep11_data->used_firmware_API_version = 0; -+ target_info->used_firmware_API_version = 0; - -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - TRACE_INFO("%s Card type: CEX%luP\n", __func__, - card_version->card_type); -@@ -11190,19 +11283,19 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata) - card_version->firmware_version.major, - card_version->firmware_version.minor); - -- if (ep11_data->used_firmware_API_version == 0) -- ep11_data->used_firmware_API_version = -+ if (target_info->used_firmware_API_version == 0) -+ target_info->used_firmware_API_version = - card_version->firmware_API_version; - else -- ep11_data->used_firmware_API_version = -- MIN(ep11_data->used_firmware_API_version, -+ target_info->used_firmware_API_version = -+ MIN(target_info->used_firmware_API_version, - card_version->firmware_API_version); - - card_version = card_version->next; - } - - TRACE_INFO("%s Used Firmware API: %lu\n", __func__, -- ep11_data->used_firmware_API_version); -+ target_info->used_firmware_API_version); - - return CKR_OK; - } -@@ -11220,20 +11313,29 @@ static void free_card_versions(ep11_card_version_t *card_version) - } - } - --void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, -+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, - CK_TOKEN_INFO_PTR pInfo) - { - ep11_private_data_t *ep11_data = tokdata->private_data; -+ ep11_target_info_t* target_info; -+ -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; - - /* - * report the EP11 firmware version as hardware version, and - * the EP11 host library version as firmware version - */ -- if (ep11_data->card_versions != NULL) -- pInfo->hardwareVersion = ep11_data->card_versions->firmware_version; -+ if (target_info->card_versions != NULL) -+ pInfo->hardwareVersion = target_info->card_versions->firmware_version; - pInfo->firmwareVersion = ep11_data->ep11_lib_version; -- memcpy(pInfo->serialNumber, ep11_data->serialNumber, -+ memcpy(pInfo->serialNumber, target_info->serialNumber, - sizeof(pInfo->serialNumber)); -+ -+ put_target_info(tokdata, target_info); -+ -+ return CKR_OK; - } - - /** -@@ -11247,13 +11349,17 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - const version_req_t req[], - CK_ULONG num_req) - { -- ep11_private_data_t *ep11_data = tokdata->private_data; - CK_ULONG i, max_card_type = 0, min_card_type = 0xFFFFFFFF; - CK_BBOOL req_not_fullfilled = CK_FALSE; - CK_BBOOL req_fullfilled = CK_FALSE; - ep11_card_version_t *card_version; -+ ep11_target_info_t* target_info; - int status; - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return CKR_FUNCTION_FAILED; -+ - for (i = 0; i < num_req; i++) { - status = check_card_version(tokdata, req[i].card_type, - req[i].min_lib_version, -@@ -11268,7 +11374,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - } - - /* Are card types < min_card_type present? */ -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type < min_card_type) - req_not_fullfilled = CK_TRUE; -@@ -11276,7 +11382,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - } - - /* Are card types > max_card_type present? */ -- card_version = ep11_data->card_versions; -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type > max_card_type) { - /* -@@ -11285,9 +11391,10 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - * So all others must also meet the version requirements or be - * not present. - */ -+ status = 1; - if (req_not_fullfilled == CK_TRUE) -- return -1; -- return 1; -+ status = -1; -+ goto out; - } - card_version = card_version->next; - } -@@ -11298,13 +11405,19 @@ static int check_required_versions(STDLL_TokData_t *tokdata, - * At least one don't meet the requirements, so all other must not - * fulfill the requirements, too, or are not present. - */ -+ status = 0; - if (req_fullfilled == CK_TRUE) -- return -1; -- return 0; -+ status = -1; -+ goto out; - } else { - /* All of the cards that are present fulfill the requirements */ -- return 1; -+ status = 1; -+ goto out; - } -+ -+out: -+ put_target_info(tokdata, target_info); -+ return status; - } - - /** -@@ -11320,6 +11433,8 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - { - ep11_private_data_t *ep11_data = tokdata->private_data; - ep11_card_version_t *card_version; -+ ep11_target_info_t* target_info; -+ int status = 1; - - TRACE_DEBUG("%s checking versions for CEX%luP cards.\n", __func__, card_type); - -@@ -11331,21 +11446,28 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - } - } - -- card_version = ep11_data->card_versions; -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) -+ return -1; -+ -+ card_version = target_info->card_versions; - while (card_version != NULL) { - if (card_version->card_type == card_type) - break; - card_version = card_version->next; - } - -- if (card_version == NULL) -- return -1; -+ if (card_version == NULL) { -+ status = -1; -+ goto out; -+ } - - if (firmware_version != NULL) { - if (compare_ck_version(&card_version->firmware_version, - firmware_version) < 0) { - TRACE_DEBUG("%s firmware_version is less than required\n", __func__); -- return 0; -+ status = 0; -+ goto out; - } - } - -@@ -11353,53 +11475,57 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type, - if (card_version->firmware_API_version < *firmware_API_version) { - TRACE_DEBUG("%s firmware_API_version is less than required\n", - __func__); -- return 0; -+ status = 0; -+ goto out; - } - } - -- return 1; -+ out: -+ put_target_info(tokdata, target_info); -+ return status; - } - --static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata) -+static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) - { - ep11_private_data_t *ep11_data = tokdata->private_data; - struct XCP_Module module; -- CK_RV rc; -+ CK_RV rc = CKR_OK; - short i; - - if (dll_m_add_module == NULL) { - TRACE_WARNING("%s Function dll_m_add_module is not available, falling " - "back to old target handling\n", __func__); - -- if (ep11_data->used_firmware_API_version > 2) { -+ if (target_info->used_firmware_API_version > 2) { - TRACE_ERROR("%s selecting an API version is not possible with old " - "target handling\n", __func__); - return CKR_FUNCTION_FAILED; - } - -- ep11_data->target = (target_t)&ep11_data->target_list; -+ target_info->target = (target_t)&ep11_data->target_list; - return CKR_OK; - } - -- if (ep11_data->used_firmware_API_version > 2 && -+ if (target_info->used_firmware_API_version > 2 && - ep11_data->ep11_lib_version.major < 3) { - TRACE_ERROR("%s selecting an API version is not possible with an EP11" - " host library version < 3.0\n", __func__); - return CKR_FUNCTION_FAILED; - } - -- ep11_data->target = XCP_TGT_INIT; -+ target_info->target = XCP_TGT_INIT; - memset(&module, 0, sizeof(module)); - module.version = ep11_data->ep11_lib_version.major >= 3 ? XCP_MOD_VERSION_2 - : XCP_MOD_VERSION_1; - module.flags = XCP_MFL_VIRTUAL | XCP_MFL_MODULE; -- module.api = ep11_data->used_firmware_API_version; -+ module.api = target_info->used_firmware_API_version; - - TRACE_DEVEL("%s XCP_MOD_VERSION: %u\n", __func__, module.version); - - if (ep11_data->target_list.length == 0) { - /* APQN_ANY: Create an empty module group */ -- rc = dll_m_add_module(&module, &ep11_data->target); -+ rc = dll_m_add_module(&module, &target_info->target); - if (rc != CKR_OK) { - TRACE_ERROR("%s dll_m_add_module (ANY) failed: rc=%ld\n", - __func__, rc); -@@ -11414,11 +11540,12 @@ static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata) - XCPTGTMASK_SET_DOM(module.domainmask, - ep11_data->target_list.apqns[2 * i + 1]); - -- rc = dll_m_add_module(&module, &ep11_data->target); -+ rc = dll_m_add_module(&module, &target_info->target); - if (rc != CKR_OK) { - TRACE_ERROR("%s dll_m_add_module (%02x.%04x) failed: rc=%ld\n", - __func__, ep11_data->target_list.apqns[2 * i], - ep11_data->target_list.apqns[2 * i + 1], rc); -+ dll_m_rm_module(NULL, target_info->target); - return CKR_FUNCTION_FAILED; - } - } -@@ -11494,6 +11621,7 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj, - CK_ULONG num_attributes = 0; - CK_ATTRIBUTE *attr; - CK_RV rc; -+ ep11_target_info_t* target_info; - - rc = template_attribute_get_ulong(obj->template, CKA_CLASS, &class); - if (rc != CKR_OK) { -@@ -11575,9 +11703,18 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj, - goto out; - } - -+ target_info = get_target_info(tokdata); -+ if (target_info == NULL) { -+ rc = CKR_FUNCTION_FAILED; -+ goto out; -+ } -+ - rc = dll_m_SetAttributeValue(ibm_opaque_attr->pValue, - ibm_opaque_attr->ulValueLen, attributes, -- num_attributes, ep11_data->target); -+ num_attributes, target_info->target); -+ -+ put_target_info(tokdata, target_info); -+ - if (rc != CKR_OK) { - rc = ep11_error_to_pkcs11_error(rc, NULL); - TRACE_ERROR("%s m_SetAttributeValue failed rc=0x%lx\n", -@@ -11601,3 +11738,233 @@ out: - return rc; - } - -+/* -+ * ATTENTION: This function is called in a separate thread. All actions -+ * performed by this function must be thread save and use locks to lock -+ * against concurrent access by other threads. -+ */ -+static CK_RV ep11tok_handle_apqn_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ event_udev_apqn_data_t *apqn_data) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ CK_BBOOL found = FALSE; -+ CK_RV rc = CKR_OK; -+ char name[20]; -+ int i; -+ -+ /* Is it one of the configured APQNs ?*/ -+ if (ep11_data->target_list.length > 0) { -+ /* APQN_WHITELIST is specified */ -+ for (i = 0; i < ep11_data->target_list.length; i++) { -+ if (ep11_data->target_list.apqns[2 * i] == apqn_data->card && -+ ep11_data->target_list.apqns[2 * i + 1] == apqn_data->domain) { -+ found = TRUE; -+ break; -+ } -+ } -+ } else { -+ /* APQN_ANY is specified */ -+ found = TRUE; -+ if (event_type == EVENT_TYPE_APQN_ADD) { -+ snprintf(name, sizeof(name), "card%02x", apqn_data->card); -+ if (is_card_ep11_and_online(name) != CKR_OK) -+ found = FALSE; /* Not an EP11 APQN */ -+ } -+ } -+ if (!found) -+ return CKR_OK; -+ -+ TRACE_DEVEL("%s Refreshing target infos due to event for APQN %02x.%04x\n", -+ __func__, apqn_data->card, apqn_data->domain); -+ -+ rc = refresh_target_info(tokdata); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s Failed to get the target infos (refresh_target_info " -+ "rc=0x%lx)\n", __func__, rc); -+ OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n", -+ __func__, rc); -+ return rc; -+ } -+ -+ return CKR_OK; -+} -+ -+/* -+ * Called by the event thread, on receipt of an event. -+ * -+ * ATTENTION: This function is called in a separate thread. All actions -+ * performed by this function must be thread save and use locks to lock -+ * against concurrent access by other threads. -+ */ -+CK_RV token_specific_handle_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len) -+{ -+ UNUSED(event_flags); -+ -+ switch (event_type) { -+ case EVENT_TYPE_APQN_ADD: -+ case EVENT_TYPE_APQN_REMOVE: -+ if (payload_len != sizeof(event_udev_apqn_data_t)) -+ return CKR_FUNCTION_FAILED; -+ return ep11tok_handle_apqn_event(tokdata, event_type, -+ (event_udev_apqn_data_t *)payload); -+ -+ default: -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ } -+ -+ return CKR_OK; -+} -+ -+/* -+ * Refreshes the target info using the currently configured and available -+ * APQNs. Registers the newly allocated target info as the current one in a -+ * thread save way and gives back the previous one so that it is release when -+ * no longer used (i.e. by a concurrently running thread). -+ */ -+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ volatile ep11_target_info_t *prev_info; -+ ep11_target_info_t *target_info; -+ CK_RV rc; -+ -+ target_info = calloc(1, sizeof(ep11_target_info_t)); -+ if (target_info == NULL) { -+ TRACE_ERROR("%s Memory allocation failed\n", __func__); -+ return CKR_HOST_MEMORY; -+ } -+ -+ target_info->ref_count = 1; -+ -+ /* Get the version info freshly with the current set of APQNs */ -+ rc = ep11tok_get_ep11_version(tokdata, target_info); -+ if (rc != 0) -+ goto error; -+ -+ /* Get the control points freshly with the current set of APQNs */ -+ target_info->control_points_len = sizeof(target_info->control_points); -+ rc = get_control_points(tokdata, target_info->control_points, -+ &target_info->control_points_len, -+ &target_info->max_control_point_index); -+ if (rc != 0) -+ goto error; -+ -+ /* Setup the group target freshly with the current set of APQNs */ -+ rc = ep11tok_setup_target(tokdata, target_info); -+ if (rc != CKR_OK) -+ goto error; -+ -+ /* Set the new one as the current one (locked against concurrent get's) */ -+ if (pthread_rwlock_wrlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Write-Lock failed.\n"); -+ rc = CKR_CANT_LOCK; -+ goto error; -+ } -+ -+ prev_info = ep11_data->target_info; -+ ep11_data->target_info = target_info; -+ -+ if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Unlock failed.\n"); -+ return CKR_CANT_LOCK; -+ } -+ -+ /* Release the previous one */ -+ if (prev_info != NULL) -+ put_target_info(tokdata, (ep11_target_info_t *)prev_info); -+ -+ return CKR_OK; -+ -+error: -+ free_card_versions(target_info->card_versions); -+ free((void *)target_info); -+ return rc; -+} -+ -+/* -+ * Get the current EP11 target info. -+ * Do NOT use the ep11_data->target_info directly, always get a copy using -+ * this function. This will increment the reference count of the target info, -+ * and return the current target info in a thread save way. -+ * When no longer needed, put it back using put_target_info(). -+ */ -+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ volatile ep11_target_info_t *target_info; -+#ifdef DEBUG -+ unsigned long ref_count; -+#endif -+ -+ /* -+ * Lock until we have obtained the current target info and have -+ * increased the reference counter -+ */ -+ if (pthread_rwlock_rdlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Read-Lock failed.\n"); -+ return NULL; -+ } -+ -+ target_info = *((void * volatile *)&ep11_data->target_info); -+ if (target_info == NULL) { -+ TRACE_ERROR("%s: target_info is NULL\n", __func__); -+ return NULL; -+ } -+ -+#ifdef DEBUG -+ ref_count = __sync_add_and_fetch(&target_info->ref_count, 1); -+ -+ TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__, -+ (void *)target_info, ref_count); -+#else -+ __sync_add_and_fetch(&target_info->ref_count, 1); -+#endif -+ -+ if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) { -+ TRACE_DEVEL("Target Unlock failed.\n"); -+ return NULL; -+ } -+ -+ return (ep11_target_info_t *)target_info; -+} -+ -+/* -+ * Give back an EP11 target info. This will decrement the reference count, -+ * and will free it if the reference count reaches zero. -+ */ -+static void put_target_info(STDLL_TokData_t *tokdata, -+ ep11_target_info_t *target_info) -+{ -+ ep11_private_data_t *ep11_data = tokdata->private_data; -+ unsigned long ref_count; -+ -+ if (target_info == NULL) -+ return; -+ -+ if (target_info->ref_count > 0) { -+ ref_count = __sync_sub_and_fetch(&target_info->ref_count, 1); -+ -+ TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__, -+ (void *)target_info, ref_count); -+ } else { -+ TRACE_WARNING("%s: target_info: %p ref_count already 0.\n", __func__, -+ (void *)target_info); -+ ref_count = 0; -+ } -+ -+ if (ref_count == 0 && target_info != ep11_data->target_info) { -+ TRACE_DEBUG("%s: target_info: %p is freed\n", __func__, -+ (void *)target_info); -+ -+ if (dll_m_rm_module != NULL) -+ dll_m_rm_module(NULL, target_info->target); -+ free_card_versions(target_info->card_versions); -+ free(target_info); -+ } -+} -+ -diff --git a/usr/lib/ep11_stdll/ep11_specific.h b/usr/lib/ep11_stdll/ep11_specific.h -index 55fc023c..343f4b3d 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.h -+++ b/usr/lib/ep11_stdll/ep11_specific.h -@@ -161,7 +161,7 @@ CK_BBOOL ep11tok_libica_mech_available(STDLL_TokData_t *tokdata, - CK_MECHANISM_TYPE mech, - CK_OBJECT_HANDLE hKey); - --void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, -+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata, - CK_TOKEN_INFO_PTR pInfo); - - CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session, -diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c -index 4e592363..cd12604e 100644 ---- a/usr/lib/ep11_stdll/new_host.c -+++ b/usr/lib/ep11_stdll/new_host.c -@@ -298,7 +298,7 @@ CK_RV SC_GetTokenInfo(STDLL_TokData_t *tokdata, CK_SLOT_ID sid, - goto done; - } - copy_token_contents_sensibly(pInfo, tokdata->nv_token_data); -- ep11tok_copy_firmware_info(tokdata, pInfo); -+ rc = ep11tok_copy_firmware_info(tokdata, pInfo); - - /* Set the time */ - now = time((time_t *) NULL); -diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h -index 2c0af9cf..01268c67 100644 ---- a/usr/lib/ep11_stdll/tok_struct.h -+++ b/usr/lib/ep11_stdll/tok_struct.h -@@ -137,7 +137,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - &token_specific_set_attribute_values, - &token_specific_set_attrs_for_new_object, -- NULL, // handle_event -+ &token_specific_handle_event, - }; - - #endif diff --git a/SOURCES/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch b/SOURCES/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch deleted file mode 100644 index 76ce00d..0000000 --- a/SOURCES/opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch +++ /dev/null @@ -1,2159 +0,0 @@ -commit 342dfbeb8275f5ea6ed52dd3f30126614ec1d037 -Author: Ingo Franzki -Date: Mon Feb 15 14:33:07 2021 +0100 - - Event support: pkcsslotd changes - - Signed-off-by: Ingo Franzki - -diff --git a/configure.ac b/configure.ac -index e0ae4a82..a0b098e1 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -234,6 +234,12 @@ AC_ARG_WITH([systemd], - AS_HELP_STRING([--with-systemd@<:@=DIR@:>@],[systemd system unit files location]), - [], - [with_systemd=no]) -+ -+dnl --- libudev development files -+AC_ARG_WITH([libudev], -+ AS_HELP_STRING([--with-libudev@<:@=DIR@:>@],[libudev development files location]), -+ [], -+ [with_libudev=check]) - - dnl --- - dnl --- -@@ -438,6 +444,46 @@ fi - AC_SUBST([XCRYPTOLINZ_CFLAGS]) - AC_SUBST([XCRYPTOLINZ_LIBS]) - -+dnl --- with_libudev -+LIBUDEV_CFLAGS= -+LIBUDEV_LIBS= -+if test "x$with_libudev" != "xno"; then -+ if test "x$with_libudev" != "xyes" -a "x$with_libudev" != "xcheck"; then -+ LIBUDEV_CFLAGS="-I$with_libudev" -+ LIBUDEV_LIBS="-L$with_libudev" -+ fi -+ old_cflags="$CFLAGS" -+ old_libs="$LIBS" -+ CFLAGS="$CFLAGS $LIBUDEV_CFLAGS" -+ LIBS="$LIBS $LIBUDEV_LIBS" -+ # Use libudev only on s390 platforms, only s390 emits AP related uevents -+ case $target in -+ *s390x* | *s390*) -+ CFLAGS="$CFLAGS -DWITH_LIBUDEV" -+ ;; -+ *) -+ if test "x$with_libudev" != "xyes"; then -+ with_libudev=no -+ echo "Default to 'with_libudev=no' on non-s390 platforms" -+ fi -+ ;; -+ esac -+ if test "x$with_libudev" != "xno"; then -+ AC_CHECK_HEADER([libudev.h], [with_libudev=yes], [ -+ AC_MSG_ERROR([Build with libudev requested but libudev headers couldn't be found]) -+ ]) -+ AC_CHECK_LIB([udev], [udev_monitor_new_from_netlink], [with_libudev=yes], [ -+ AC_MSG_ERROR([Build with libudev requested but libudev libraries couldn't be found]) -+ ]) -+ fi -+ if test "x$with_libudev" = "xno"; then -+ CFLAGS="$old_cflags" -+ LIBS="$old_libs" -+ fi -+fi -+AC_SUBST([LIBUDEV_CFLAGS]) -+AC_SUBST([LIBUDEV_LIBS]) -+AM_CONDITIONAL([HAVE_LIBUDEV], [test "x$with_libudev" = "xyes"]) - - dnl --- - dnl --- Now check enabled features, while making sure every required -@@ -649,6 +695,7 @@ echo " Daemon build: $enable_daemon" - echo " Library build: $enable_library" - echo " Systemd service: $enable_systemd" - echo " Build with locks: $enable_locks" -+echo " Build with libudev: $with_libudev" - echo " Build p11sak tool: $enable_p11sak" - echo " token migrate tool: $enable_pkcstok_migrate" - echo -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index 4d038435..e37368a5 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -31,6 +31,7 @@ - #define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock" - - #define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" -+#define ADMIN_SOCKET_FILE_PATH "/var/run/pkcsslotd.admin.socket" - - #define PID_FILE_PATH "/var/run/pkcsslotd.pid" - #define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf" -@@ -45,6 +46,7 @@ - - #define NUMBER_SLOTS_MANAGED 1024 - #define NUMBER_PROCESSES_ALLOWED 1000 -+#define NUMBER_ADMINS_ALLOWED 1000 - - // - // Per Process Data structure -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index 69eb59f3..d7edcb3c 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -92,5 +92,8 @@ int init_socket_server(); - int term_socket_server(); - int init_socket_data(Slot_Mgr_Socket_t *sp); - int socket_connection_handler(int timeout_secs); -+#ifdef DEV -+void dump_socket_handler(); -+#endif - - #endif /* _SLOTMGR_H */ -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.mk b/usr/sbin/pkcsslotd/pkcsslotd.mk -index 2d36b4a9..c574edf8 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.mk -+++ b/usr/sbin/pkcsslotd/pkcsslotd.mk -@@ -8,6 +8,9 @@ CLEANFILES += usr/lib/common/parser.c usr/lib/common/parser.h \ - usr/lib/common/parser.output usr/lib/common/lexer.c - - usr_sbin_pkcsslotd_pkcsslotd_LDFLAGS = -lpthread -lcrypto -+if HAVE_LIBUDEV -+usr_sbin_pkcsslotd_pkcsslotd_LDFLAGS += -ludev -+endif - - usr_sbin_pkcsslotd_pkcsslotd_CFLAGS = -DPROGRAM_NAME=\"$(@)\" \ - -I${srcdir}/usr/include -I${srcdir}/usr/lib/common \ -diff --git a/usr/sbin/pkcsslotd/signal.c b/usr/sbin/pkcsslotd/signal.c -index 49482a2f..17167632 100644 ---- a/usr/sbin/pkcsslotd/signal.c -+++ b/usr/sbin/pkcsslotd/signal.c -@@ -21,7 +21,7 @@ - extern BOOL IsValidProcessEntry(pid_t_64 pid, time_t_64 RegTime); - - static int SigsToIntercept[] = { -- SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, -+ SIGHUP, SIGINT, SIGQUIT, SIGALRM, - SIGTERM, SIGTSTP, SIGTTIN, - SIGTTOU, SIGUSR1, SIGUSR2, SIGPROF - }; -@@ -32,8 +32,11 @@ static int SigsToIntercept[] = { - /* SIGCHLD - Don't want to exit. Should never receive, but we do, apparently - * when something tries to cancel the GC Thread */ - -+/* SIGPIPE - Don't want to exit. May happen when a connection to an admin -+ * event sender or a process is closed before all events are delivered. */ -+ - static int SigsToIgnore[] = { -- SIGCHLD, -+ SIGCHLD, SIGPIPE, - }; - - -@@ -71,6 +74,10 @@ void slotdGenericSignalHandler(int Signal) - CheckForGarbage(shmp); - #endif - -+#ifdef DEV -+ dump_socket_handler(); -+#endif -+ - for (procindex = 0; (procindex < NUMBER_PROCESSES_ALLOWED); procindex++) { - - Slot_Mgr_Proc_t_64 *pProc = &(shmp->proc_table[procindex]); -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index 1fae0b95..41408670 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -1,4 +1,6 @@ - /* -+ * COPYRIGHT (c) International Business Machines Corp. 2013, 2021 -+ * - * This program is provided under the terms of the Common Public License, - * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this - * software constitutes recipient's acceptance of CPL-1.0 terms which can be -@@ -12,6 +14,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -19,32 +23,1225 @@ - #include - #include - #include -+#include -+ -+#if defined(__GNUC__) && __GNUC__ >= 7 || defined(__clang__) && __clang_major__ >= 12 -+ #define FALL_THROUGH __attribute__ ((fallthrough)) -+#else -+ #define FALL_THROUGH ((void)0) -+#endif -+ -+#ifdef WITH_LIBUDEV -+#include -+#endif - - #include "log.h" - #include "slotmgr.h" - #include "pkcsslotd.h" - #include "apictl.h" -+#include "dlist.h" -+#include "events.h" -+ -+#define MAX_EPOLL_EVENTS 128 -+ -+#ifdef WITH_LIBUDEV -+#define UDEV_RECV_BUFFFER_SIZE 512 * 1024 -+#define UDEV_SUBSYSTEM_AP "ap" -+#define UDEV_ACTION_BIND "bind" -+#define UDEV_ACTION_UNBIND "unbind" -+#define UDEV_ACTION_DEVTYPE_APQN "ap_queue" -+#define UDEV_PROERTY_DEVTYPE "DEV_TYPE" -+#endif -+ -+struct epoll_info { -+ int (* notify)(int events, void *private); -+ void (* free)(void *private); -+ void *private; -+ unsigned long ref_count; -+}; -+ -+struct listener_info { -+ int socket; -+ const char *file_path; -+ int (* new_conn)(int socket, struct listener_info *listener); -+ struct epoll_info ep_info; -+ unsigned long num_clients; -+ unsigned long max_num_clients; -+}; -+ -+enum xfer_state { -+ XFER_IDLE = 0, -+ XFER_RECEIVE = 1, -+ XFER_SEND = 2, -+}; -+ -+struct client_info { -+ int socket; -+ int (* xfer_complete)(void *client); -+ void (* hangup)(void *client); -+ void (* free)(void *client); -+ void *client; -+ struct epoll_info ep_info; -+ enum xfer_state xfer_state; -+ char *xfer_buffer; -+ size_t xfer_size; -+ size_t xfer_offset; -+}; -+ -+enum proc_state { -+ PROC_INITIAL_SEND = 0, -+ PROC_WAIT_FOR_EVENT = 1, -+ PROC_SEND_EVENT = 2, -+ PROC_SEND_PAYLOAD = 3, -+ PROC_RECEIVE_REPLY = 4, -+ PROC_HANGUP = 5, -+}; -+ -+struct proc_conn_info { -+ struct client_info client_info; -+ enum proc_state state; -+ DL_NODE *events; -+ struct event_info *event; -+ event_reply_t reply; -+}; -+ -+enum admin_state { -+ ADMIN_RECEIVE_EVENT = 0, -+ ADMIN_RECEIVE_PAYLOAD = 1, -+ ADMIN_EVENT_DELIVERED = 2, -+ ADMIN_SEND_REPLY = 3, -+ ADMIN_WAIT_FOR_EVENT_LIMIT = 4, -+ ADMIN_HANGUP = 5, -+}; -+ -+struct admin_conn_info { -+ struct client_info client_info; -+ enum admin_state state; -+ struct event_info *event; -+}; -+ -+#ifdef WITH_LIBUDEV -+struct udev_mon { -+ struct udev *udev; -+ struct udev_monitor *mon; -+ int socket; -+ struct epoll_info ep_info; -+ struct event_info *delayed_event; -+}; -+#endif -+ -+struct event_info { -+ event_msg_t event; -+ char *payload; -+ event_reply_t reply; -+ unsigned long proc_ref_count; /* # of processes using this event */ -+ struct admin_conn_info *admin_ref; /* Admin connection to send reply back */ -+}; -+ -+static int epoll_fd = -1; -+static struct listener_info proc_listener; -+static DL_NODE *proc_connections = NULL; -+static struct listener_info admin_listener; -+static DL_NODE *admin_connections = NULL; -+#ifdef WITH_LIBUDEV -+static struct udev_mon udev_mon; -+#endif -+static DL_NODE *pending_events = NULL; -+static unsigned long pending_events_count = 0; -+ -+#define MAX_PENDING_EVENTS 1024 -+ -+/* -+ * Iterate over all connections in a safe way. Before actually iterating, -+ * increment the ref count of ALL connections, because any processing may -+ * cause any of the connections to be hang-up, and thus freed and removed -+ * from the list. We need to make sure that while we are iterating over the -+ * connections, none of them gets removed from the list. -+ */ -+#define FOR_EACH_CONN_SAFE_BEGIN(list, conn) { \ -+ DL_NODE *_node, *_next; \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); \ -+ client_socket_get(&(conn)->client_info); \ -+ _node = _next; \ -+ } \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); -+ -+#define FOR_EACH_CONN_SAFE_END(list, conn) \ -+ _node = _next; \ -+ } \ -+ _node = dlist_get_first(list); \ -+ while (_node != NULL) { \ -+ conn = _node->data; \ -+ _next = dlist_next(_node); \ -+ client_socket_put(&(conn)->client_info); \ -+ _node = _next; \ -+ } \ -+ } -+ -+ -+ -+static void listener_socket_close(int socketfd, const char *file_path); -+static int listener_client_hangup(struct listener_info *listener); -+static void event_delivered(struct event_info *event); -+static int client_socket_notify(int events, void *private); -+static void client_socket_free(void *private); -+static int proc_xfer_complete(void *client); -+static int proc_start_deliver_event(struct proc_conn_info *conn); -+static int proc_deliver_event(struct proc_conn_info *conn, -+ struct event_info *event); -+static int proc_event_delivered(struct proc_conn_info *conn, -+ struct event_info *event); -+static inline void proc_get(struct proc_conn_info *conn); -+static inline void proc_put(struct proc_conn_info *conn); -+static void proc_hangup(void *client); -+static void proc_free(void *client); -+static int admin_xfer_complete(void *client); -+static void admin_event_limit_underrun(struct admin_conn_info *conn); -+static int admin_event_delivered(struct admin_conn_info *conn, -+ struct event_info *event); -+static inline void admin_get(struct admin_conn_info *conn); -+static inline void admin_put(struct admin_conn_info *conn); -+static void admin_hangup(void *client); -+static void admin_free(void *client); -+#ifdef WITH_LIBUDEV -+static void udev_mon_term(struct udev_mon *udev_mon); -+static int udev_mon_notify(int events, void *private); -+#endif -+ -+static void epoll_info_init(struct epoll_info *epoll_info, -+ int (* notify)(int events, void *private), -+ void (* free_cb)(void *private), -+ void *private) -+{ -+ epoll_info->ref_count = 1; -+ epoll_info->notify = notify; -+ epoll_info->free = free_cb; -+ epoll_info->private = private; -+} -+ -+static void epoll_info_get(struct epoll_info *epoll_info) -+{ -+ epoll_info->ref_count++; -+ -+ DbgLog(DL3, "%s: private: %p, ref_count: %lu", __func__, -+ epoll_info->private, epoll_info->ref_count); -+} -+ -+static void epoll_info_put(struct epoll_info *epoll_info) -+{ -+ if (epoll_info->ref_count > 0) -+ epoll_info->ref_count--; -+ -+ DbgLog(DL3, "%s: private: %p, ref_count: %lu", __func__, -+ epoll_info->private, epoll_info->ref_count); -+ -+ if (epoll_info->ref_count == 0 && epoll_info->free != NULL) -+ epoll_info->free(epoll_info->private); -+} -+ -+static int client_socket_init(int socket, int (* xfer_complete)(void *client), -+ void (* hangup)(void *client), -+ void (* free_cb)(void *client), void *client, -+ struct client_info *client_info) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (xfer_complete == NULL || hangup == NULL) -+ return -EINVAL; -+ -+ epoll_info_init(&client_info->ep_info, client_socket_notify, -+ client_socket_free, client_info); -+ client_info->socket = socket; -+ client_info->xfer_complete = xfer_complete; -+ client_info->hangup = hangup; -+ client_info->free = free_cb; -+ client_info->client = client; -+ client_info->xfer_state = XFER_IDLE; -+ -+ rc = fcntl(socket, F_SETFL, O_NONBLOCK); -+ if (rc < 0) { -+ err = errno; -+ InfoLog("%s: Failed to set client socket %d to non-blocking, errno " -+ "%d (%s).", __func__, socket, err, strerror(err)); -+ return -err; -+ } -+ -+ evt.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLERR | EPOLLET; -+ evt.data.ptr = &client_info->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ InfoLog("%s: Failed to add client socket %d to epoll, errno %d (%s).", -+ __func__, socket, err, strerror(err)); -+ close(socket); -+ return -err; -+ } -+ -+ return 0; -+} -+ -+static inline void client_socket_get(struct client_info *client_info) -+{ -+ epoll_info_get(&client_info->ep_info); -+} -+ -+static inline void client_socket_put(struct client_info *client_info) -+{ -+ epoll_info_put(&client_info->ep_info); -+} -+ -+static void client_socket_term(struct client_info *client_info) -+{ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_info->socket, NULL); -+ close(client_info->socket); -+ client_info->socket = -1; -+} -+ -+static int client_socket_notify(int events, void *private) -+{ -+ struct client_info *client_info = private; -+ ssize_t num; -+ int rc, err, socket = client_info->socket; -+ -+ DbgLog(DL3, "%s: Epoll event on client %p socket %d: events: 0x%x xfer: %d", -+ __func__, client_info, socket, events, client_info->xfer_state); -+ -+ if (socket < 0) -+ return -ENOTCONN; -+ -+ if (events & (EPOLLHUP | EPOLLERR)) { -+ DbgLog(DL3, "EPOLLHUP | EPOLLERR"); -+ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } -+ -+ if (client_info->xfer_state == XFER_RECEIVE && (events & EPOLLIN)) { -+ DbgLog(DL3, "%s: EPOLLIN: buffer: %p size: %lu ofs: %lu", __func__, -+ client_info->xfer_buffer, client_info->xfer_size, -+ client_info->xfer_offset); -+ -+ num = read(client_info->socket, -+ client_info->xfer_buffer + client_info->xfer_offset, -+ client_info->xfer_size - client_info->xfer_offset); -+ if (num <= 0) { -+ err = errno; -+ -+ DbgLog(DL3, "%s: read failed with: num: %d errno: %d (%s)", -+ __func__, num, num < 0 ? err : 0, -+ num < 0 ? strerror(err) : "none"); -+ -+ if (num < 0 && err == EWOULDBLOCK) -+ return 0; /* Will be continued when socket becomes readable */ -+ -+ /* assume connection closed by peer */ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } else { -+ DbgLog(DL3, "%s: %lu bytes received", __func__, num); -+ -+ client_info->xfer_offset += num; -+ -+ DbgLog(DL3, "%s: %lu bytes left", __func__, -+ client_info->xfer_size - client_info->xfer_offset); -+ -+ if (client_info->xfer_offset >= client_info->xfer_size) { -+ client_info->xfer_state = XFER_IDLE; -+ client_info->xfer_buffer = NULL; -+ client_info->xfer_size = 0; -+ client_info->xfer_offset = 0; -+ -+ client_socket_get(client_info); -+ rc = client_info->xfer_complete(client_info->client); -+ if (rc != 0) { -+ InfoLog("%s: xfer_complete callback failed for client " -+ "socket %d, rc: %d", __func__, socket, -+ rc); -+ client_info->hangup(client_info->client); -+ } -+ client_socket_put(client_info); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return rc; -+ } -+ return 0; -+ } -+ } -+ -+ if (client_info->xfer_state == XFER_SEND && (events & EPOLLOUT)) { -+ DbgLog(DL3, "%s: EPOLLOUT: buffer: %p size: %lu ofs: %lu", __func__, -+ client_info->xfer_buffer, client_info->xfer_size, -+ client_info->xfer_offset); -+ -+ num = write(client_info->socket, -+ client_info->xfer_buffer + client_info->xfer_offset, -+ client_info->xfer_size - client_info->xfer_offset); -+ if (num < 0) { -+ err = errno; -+ -+ DbgLog(DL3, "%s: write failed with: errno: %d (%s)", __func__, err, -+ strerror(err)); -+ -+ if (err == EWOULDBLOCK) -+ return 0; /* Will be continued when socket becomes writable */ -+ -+ /* assume connection closed by peer */ -+ client_info->hangup(client_info->client); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return 0; -+ } else { -+ DbgLog(DL3, "%s: %lu bytes sent", __func__, num); -+ -+ client_info->xfer_offset += num; -+ -+ DbgLog(DL3, "%s: %lu bytes left", __func__, -+ client_info->xfer_size - client_info->xfer_offset); -+ -+ if (client_info->xfer_offset >= client_info->xfer_size) { -+ client_info->xfer_state = XFER_IDLE; -+ client_info->xfer_buffer = NULL; -+ client_info->xfer_size = 0; -+ client_info->xfer_offset = 0; -+ -+ client_socket_get(client_info); -+ rc = client_info->xfer_complete(client_info->client); -+ if (rc != 0) { -+ InfoLog("%s: xfer_complete callback failed for client " -+ "socket %d, rc: %d", __func__, socket, -+ rc); -+ client_info->hangup(client_info->client); -+ } -+ client_socket_put(client_info); -+ client_info = NULL; /* client_info may have been freed by now */ -+ return rc; -+ } -+ return 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static void client_socket_free(void *private) -+{ -+ struct client_info *client_info = private; -+ -+ DbgLog(DL3, "%s: %p", __func__, client_info); -+ -+ if (client_info->free != NULL) -+ client_info->free(client_info->client); -+} -+ -+static int client_socket_receive(struct client_info *client_info, -+ void *buffer, size_t size) -+{ -+ if (client_info->socket < 0) -+ return -ENOTCONN; -+ -+ client_info->xfer_state = XFER_RECEIVE; -+ client_info->xfer_buffer = (char *)buffer; -+ client_info->xfer_size = size; -+ client_info->xfer_offset = 0; -+ -+ DbgLog(DL3, "%s: Start receive on client socket %d: buffer: %p size: %lu", -+ __func__, client_info->socket, buffer, size); -+ -+ return client_socket_notify(EPOLLIN, client_info); -+} -+ -+ -+static int client_socket_send(struct client_info *client_info, -+ void *buffer, size_t size) -+{ -+ if (client_info->socket < 0) -+ return -ENOTCONN; -+ -+ client_info->xfer_state = XFER_SEND; -+ client_info->xfer_buffer = (char *)buffer; -+ client_info->xfer_size = size; -+ client_info->xfer_offset = 0; -+ -+ DbgLog(DL3, "%s: Start send on client socket %d: buffer: %p size: %lu", -+ __func__, client_info->socket, buffer, size); -+ -+ return client_socket_notify(EPOLLOUT, client_info); -+} -+ -+static struct event_info *event_new(unsigned int payload_len, -+ struct admin_conn_info *admin_conn) -+{ -+ struct event_info *event; -+ -+ event = calloc(1, sizeof(struct event_info)); -+ if (event == NULL) { -+ ErrLog("%s: Failed to allocate the event", __func__); -+ return NULL; -+ } -+ -+ event->event.version = EVENT_VERSION_1; -+ event->event.payload_len = payload_len; -+ if (payload_len > 0) { -+ event->payload = malloc(payload_len); -+ if (event->payload == NULL) { -+ ErrLog("%s: Failed to allocate the event payload", __func__); -+ free(event); -+ return NULL; -+ } -+ } -+ -+ event->reply.version = EVENT_VERSION_1; -+ -+ if (admin_conn != NULL) -+ admin_get(admin_conn); -+ event->admin_ref = admin_conn; -+ -+ DbgLog(DL3, "%s: allocated event: %p", __func__, event); -+ return event; -+} -+ -+static void event_limit_underrun() -+{ -+ struct admin_conn_info *conn; -+ -+ DbgLog(DL3, "%s: pending_events_count: %lu", __func__, pending_events_count); -+ -+#ifdef WITH_LIBUDEV -+ /* Notify the udev monitor */ -+ udev_mon_notify(EPOLLIN, &udev_mon); -+#endif -+ -+ /* Notify all admin connections */ -+ FOR_EACH_CONN_SAFE_BEGIN(admin_connections, conn) { -+ admin_event_limit_underrun(conn); -+ } -+ FOR_EACH_CONN_SAFE_END(admin_connections, conn) -+} -+ -+static void event_free(struct event_info *event) -+{ -+ DbgLog(DL3, "%s: free event: %p", __func__, event); -+ -+ if (event->payload != NULL) -+ free(event->payload); -+ free(event); -+} -+ -+static int event_add_to_pending_list(struct event_info *event) -+{ -+ DL_NODE *list; -+ -+ list = dlist_add_as_last(pending_events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of pending events", __func__); -+ return -ENOMEM; -+ } -+ pending_events = list; -+ -+ pending_events_count++; -+ -+ return 0; -+} -+ -+static void event_remove_from_pending_list(struct event_info *event) -+{ -+ DL_NODE *node; -+ int trigger = 0; -+ -+ node = dlist_find(pending_events, event); -+ if (node != NULL) { -+ pending_events = dlist_remove_node(pending_events, node); -+ -+ if (pending_events_count >= MAX_PENDING_EVENTS) -+ trigger = 1; -+ -+ if (pending_events_count > 0) -+ pending_events_count--; -+ -+ if (trigger) -+ event_limit_underrun(); -+ } -+} -+ -+static int event_start_deliver(struct event_info *event) -+{ -+ struct proc_conn_info *conn; -+ int rc; -+ -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ if (pending_events_count >= MAX_PENDING_EVENTS) { -+ InfoLog("%s: Max pending events reached", __func__); -+ return -ENOSPC; -+ } -+ -+ /* Add event of the list of pending events */ -+ rc = event_add_to_pending_list(event); -+ if (rc != 0) -+ return rc; -+ -+ /* -+ * Need to increment the event's ref count here, proc_deliver_event() may -+ * already complete the event delivery for one process, which then would -+ * free the event but it needs to be passed to other processes here, too. -+ */ -+ event->proc_ref_count++; -+ FOR_EACH_CONN_SAFE_BEGIN(proc_connections, conn) { -+ rc = proc_deliver_event(conn, event); -+ if (rc != 0) -+ proc_hangup(conn); -+ } -+ FOR_EACH_CONN_SAFE_END(proc_connections, conn) -+ event->proc_ref_count--; -+ -+ DbgLog(DL3, "%s: proc_ref_count: %u", __func__, event->proc_ref_count); -+ -+ if (event->proc_ref_count == 0) -+ event_delivered(event); -+ -+ return 0; -+} -+ -+static void event_delivered(struct event_info *event) -+{ -+ struct admin_conn_info *conn; -+ int rc; -+ -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ event_remove_from_pending_list(event); -+ -+ /* Notify owning admin connection (if available), free otherwise */ -+ if (event->admin_ref != NULL) { -+ conn = event->admin_ref; -+ admin_get(conn); -+ rc = admin_event_delivered(conn, event); -+ if (rc != 0) { -+ admin_hangup(conn); -+ event_free(event); -+ } -+ admin_put(conn); -+ } else { -+ event_free(event); -+ } -+} -+ -+static int proc_new_conn(int socket, struct listener_info *listener) -+{ -+ struct proc_conn_info *conn; -+ struct event_info *event; -+ DL_NODE *list, *node; -+ int rc = 0; -+ -+ UNUSED(listener); -+ -+ DbgLog(DL0, "%s: Accepted connection from process: socket: %d", __func__, -+ socket); -+ -+ conn = calloc(1, sizeof(struct proc_conn_info)); -+ if (conn == NULL) { -+ ErrLog("%s: Failed to to allocate memory for the process connection", -+ __func__); -+ return -ENOMEM; -+ /* Caller will close socket */ -+ } -+ -+ DbgLog(DL3, "%s: process conn: %p", __func__, conn); -+ -+ /* Add currently pending events to this connection */ -+ node = dlist_get_first(pending_events); -+ while (node != NULL) { -+ event = (struct event_info *)node->data; -+ DbgLog(DL3, "%s: event: %p", __func__, event); -+ -+ list = dlist_add_as_last(conn->events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of process's pending events", -+ __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ conn->events = list; -+ -+ event->proc_ref_count++; -+ -+ node = dlist_next(node); -+ } -+ -+ conn->state = PROC_INITIAL_SEND; -+ -+ rc = client_socket_init(socket, proc_xfer_complete, proc_hangup, proc_free, -+ conn, &conn->client_info); -+ if (rc != 0) -+ goto out; -+ -+ /* Add it to the process connections list */ -+ list = dlist_add_as_first(proc_connections, conn); -+ if (list == NULL) { -+ rc = -ENOMEM; -+ goto out; -+ } -+ proc_connections = list; -+ -+ proc_get(conn); -+ rc = client_socket_send(&conn->client_info, &socketData, -+ sizeof(socketData)); -+ proc_put(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ -+out: -+ if (rc != 0 && conn != NULL) { -+ proc_hangup(conn); -+ rc = 0; /* Don't return an error, we have already handled it */ -+ } -+ -+ return rc; -+} -+ -+static int proc_xfer_complete(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ int rc; -+ -+ DbgLog(DL0, "%s: Xfer completed: process: %p socket: %d state: %d", -+ __func__, conn, conn->client_info.socket, conn->state); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call proc_hangup(). Thus, no need to call proc_hangup() ourselves. -+ */ -+ -+ switch (conn->state) { -+ case PROC_INITIAL_SEND: -+ conn->state = PROC_WAIT_FOR_EVENT; -+ rc = proc_start_deliver_event(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case PROC_WAIT_FOR_EVENT: -+ /* handled in proc_start_deliver_event */ -+ break; -+ -+ case PROC_SEND_EVENT: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.payload_len > 0) { -+ conn->state = PROC_SEND_PAYLOAD; -+ rc = client_socket_send(&conn->client_info, conn->event->payload, -+ conn->event->event.payload_len); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case PROC_SEND_PAYLOAD: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ conn->state = PROC_RECEIVE_REPLY; -+ rc = client_socket_receive(&conn->client_info, &conn->reply, -+ sizeof(conn->reply)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case PROC_RECEIVE_REPLY: -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event to handle", __func__); -+ return -EINVAL; -+ } -+ -+ if (conn->event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ if (conn->reply.version != EVENT_VERSION_1) { -+ InfoLog("%s: Reply has a wrong version: %u", __func__, -+ conn->reply.version); -+ return -EINVAL; -+ } -+ -+ /* Update reply counters in event */ -+ conn->event->reply.positive_replies += conn->reply.positive_replies; -+ conn->event->reply.negative_replies += conn->reply.negative_replies; -+ conn->event->reply.nothandled_replies += -+ conn->reply.nothandled_replies; -+ } -+ -+ conn->state = PROC_WAIT_FOR_EVENT; -+ -+ rc = proc_event_delivered(conn, conn->event); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case PROC_HANGUP: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int proc_start_deliver_event(struct proc_conn_info *conn) -+{ -+ DL_NODE *node; -+ int rc; -+ -+ if (conn->state != PROC_WAIT_FOR_EVENT) -+ return 0; -+ -+ node = dlist_get_first(conn->events); -+ if (node == NULL) -+ return 0; -+ -+ conn->event = node->data; -+ memset(&conn->reply, 0, sizeof(conn->reply)); -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, conn->event); -+ -+ conn->state = PROC_SEND_EVENT; -+ rc = client_socket_send(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+} -+ -+static int proc_deliver_event(struct proc_conn_info *conn, -+ struct event_info *event) -+{ -+ DL_NODE *list; -+ int rc; -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, event); -+ -+ if (conn->state == PROC_HANGUP) -+ return 0; -+ -+ /* Add to process's event list and incr. reference count */ -+ list = dlist_add_as_last(conn->events, event); -+ if (list == NULL) { -+ ErrLog("%s: failed add event to list of process's pending events", -+ __func__); -+ return -ENOMEM; -+ } -+ conn->events = list; -+ -+ event->proc_ref_count++; -+ -+ rc = proc_start_deliver_event(conn); -+ return rc; -+} -+ -+static int proc_event_delivered(struct proc_conn_info *conn, -+ struct event_info *event) -+{ -+ DL_NODE *node; -+ int rc; -+ -+ DbgLog(DL3, "%s: process: %p event: %p", __func__, conn, event); -+ -+ conn->event = NULL; -+ -+ /* Remove from process's event list and decr. reference count */ -+ node = dlist_find(conn->events, event); -+ if (node != NULL) { -+ conn->events = dlist_remove_node(conn->events, node); -+ event->proc_ref_count--; -+ } -+ -+ DbgLog(DL3, "%s: proc_ref_count: %u", __func__, event->proc_ref_count); -+ -+ if (event->proc_ref_count == 0) -+ event_delivered(event); -+ -+ /* Deliver further pending events, if any */ -+ rc = proc_start_deliver_event(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+} -+ -+static inline void proc_get(struct proc_conn_info *conn) -+{ -+ client_socket_get(&conn->client_info); -+} -+ -+static inline void proc_put(struct proc_conn_info *conn) -+{ -+ client_socket_put(&conn->client_info); -+} -+ -+static void proc_hangup(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ struct event_info *event; -+ DL_NODE *node; -+ -+ DbgLog(DL0, "%s: process: %p socket: %d state: %d", __func__, conn, -+ conn->client_info.socket, conn->state); -+ -+ if (conn->state == PROC_HANGUP) -+ return; -+ conn->state = PROC_HANGUP; -+ -+ /* Unlink all pending events */ -+ while ((node = dlist_get_first(conn->events)) != NULL) { -+ event = node->data; -+ /* We did not handle this event */ -+ event->reply.nothandled_replies++; -+ proc_event_delivered(conn, event); -+ } -+ -+ client_socket_term(&conn->client_info); -+ proc_put(conn); -+} -+ -+static void proc_free(void *client) -+{ -+ struct proc_conn_info *conn = client; -+ DL_NODE *node; -+ -+ /* Remove it from the process connections list */ -+ node = dlist_find(proc_connections, conn); -+ if (node != NULL) { -+ proc_connections = dlist_remove_node(proc_connections, node); -+ listener_client_hangup(&proc_listener); -+ } -+ -+ DbgLog(DL0, "%s: process: %p", __func__, conn); -+ free(conn); -+} -+ -+static int admin_new_conn(int socket, struct listener_info *listener) -+{ -+ struct admin_conn_info *conn; -+ DL_NODE *list; -+ int rc = 0; -+ -+ UNUSED(listener); -+ -+ DbgLog(DL0, "%s: Accepted connection from admin: socket: %d", __func__, -+ socket); -+ -+ conn = calloc(1, sizeof(struct admin_conn_info)); -+ if (conn == NULL) { -+ ErrLog("%s: Failed to to allocate memory for the admin connection", -+ __func__); -+ return -ENOMEM; -+ /* Caller will close socket */ -+ } -+ -+ DbgLog(DL3, "%s: admin conn: %p", __func__, conn); -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ -+ rc = client_socket_init(socket, admin_xfer_complete, admin_hangup, -+ admin_free, conn, &conn->client_info); -+ if (rc != 0) -+ goto out; -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ -+ /* Add it to the admin connections list */ -+ list = dlist_add_as_first(admin_connections, conn); -+ if (list == NULL) { -+ ErrLog("%s: Failed to add connection to list of admin connections", -+ __func__); -+ rc = -ENOMEM; -+ goto out; -+ } -+ admin_connections = list; -+ -+ admin_get(conn); -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ admin_put(conn); -+ conn = NULL; /* conn may have been freed by now */ -+ -+out: -+ if (rc != 0 && conn != NULL) { -+ admin_hangup(conn); -+ rc = 0; /* Don't return an error, we have already handled it */ -+ } -+ -+ return rc; -+} -+ -+static int admin_xfer_complete(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ int rc; -+ -+ DbgLog(DL0, "%s: Xfer completed: admin: %p socket: %d state: %d", -+ __func__, conn, conn->client_info.socket, conn->state); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call admin_hangup(). Thus, no need to call admin_hangup() ourselves. -+ */ -+ -+ if (conn->event == NULL) { -+ TraceLog("%s: No current event", __func__); -+ return -EINVAL; -+ } -+ -+ switch (conn->state) { -+ case ADMIN_RECEIVE_EVENT: -+ /* We have received the event from the admin */ -+ DbgLog(DL3, "%s: Event version: %u", __func__, -+ conn->event->event.version); -+ DbgLog(DL3, "%s: Event type: 0x%08x", __func__, -+ conn->event->event.type); -+ DbgLog(DL3, "%s: Event flags: 0x%08x", __func__, -+ conn->event->event.flags); -+ DbgLog(DL3, "%s: Event token_type: 0x%08x", __func__, -+ conn->event->event.token_type); -+ DbgLog(DL3, "%s: Event token_name: '%.32s'", __func__, -+ conn->event->event.token_label); -+ DbgLog(DL3, "%s: Event process_id: %u", __func__, -+ conn->event->event.process_id); -+ DbgLog(DL3, "%s: Event payload_len: %u", __func__, -+ conn->event->event.payload_len); -+ -+ if (conn->event->event.version != EVENT_VERSION_1) { -+ InfoLog("%s: Admin event has invalid version: %d", __func__, -+ conn->event->event.version); -+ return -EINVAL; -+ } -+ if (conn->event->event.payload_len > EVENT_MAX_PAYLOAD_LENGTH) { -+ InfoLog("%s: Admin event payload is too large: %u", __func__, -+ conn->event->event.payload_len); -+ return -EMSGSIZE; -+ } -+ -+ if (conn->event->event.payload_len > 0) { -+ conn->event->payload = malloc(conn->event->event.payload_len); -+ if (conn->event->payload == NULL) { -+ ErrLog("%s: Failed to allocate the payload buffer", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_PAYLOAD; -+ rc = client_socket_receive(&conn->client_info, conn->event->payload, -+ conn->event->event.payload_len); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ } -+ FALL_THROUGH; -+ /* fall through */ -+ -+ case ADMIN_RECEIVE_PAYLOAD: -+ /* We have received the payload (if any) from the admin */ -+ conn->state = ADMIN_EVENT_DELIVERED; -+ rc = event_start_deliver(conn->event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay */ -+ conn->state = ADMIN_WAIT_FOR_EVENT_LIMIT; -+ return 0; -+ } -+ return rc; -+ } -+ break; -+ -+ case ADMIN_WAIT_FOR_EVENT_LIMIT: -+ /* This state is handled in admin_event_limit_underrun() */ -+ break; -+ -+ case ADMIN_EVENT_DELIVERED: -+ /* This state is handled in admin_event_delivered() */ -+ break; -+ -+ case ADMIN_SEND_REPLY: -+ /* The reply has been sent to the admin */ -+ if (conn->event->admin_ref != NULL) -+ admin_put(conn->event->admin_ref); -+ conn->event->admin_ref = NULL; -+ event_free(conn->event); -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ conn = NULL; /* conn may have been freed by now */ -+ return rc; -+ -+ case ADMIN_HANGUP: -+ break; -+ } -+ -+ return 0; -+} -+ -+static void admin_event_limit_underrun(struct admin_conn_info *conn) -+{ -+ int rc; -+ -+ DbgLog(DL3, "%s: admin: %p state: %d", __func__, conn, conn->state); -+ -+ if (conn->state != ADMIN_WAIT_FOR_EVENT_LIMIT) -+ return; -+ -+ conn->state = ADMIN_EVENT_DELIVERED; -+ -+ rc = event_start_deliver(conn->event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay */ -+ conn->state = ADMIN_WAIT_FOR_EVENT_LIMIT; -+ return; -+ } -+ admin_hangup(conn); -+ } -+} -+ -+static int admin_event_delivered(struct admin_conn_info *conn, -+ struct event_info *event) -+{ -+ int rc; -+ -+ DbgLog(DL3, "%s: admin: %p event: %p", __func__, conn, event); -+ -+ /* -+ * A non-zero return code returned by this function causes the caller to -+ * call admin_hangup(). Thus, no need to call admin_hangup() ourselves. -+ */ -+ -+ if (conn->state != ADMIN_EVENT_DELIVERED) { -+ TraceLog("%s: wrong state: %d", __func__, conn->state); -+ return -EINVAL; -+ } -+ -+ if (event->event.flags & EVENT_FLAGS_REPLY_REQ) { -+ if (conn->event != event) { -+ TraceLog("%s: event not the current event", __func__); -+ return -EINVAL; -+ } -+ -+ DbgLog(DL3, "%s: Reply version: %u", __func__, -+ event->reply.version); -+ DbgLog(DL3, "%s: Reply positive: %lu", __func__, -+ event->reply.positive_replies); -+ DbgLog(DL3, "%s: Reply negative: %lu", __func__, -+ event->reply.negative_replies); -+ DbgLog(DL3, "%s: Reply not-handled: %lu", __func__, -+ event->reply.nothandled_replies); -+ -+ conn->state = ADMIN_SEND_REPLY; -+ rc = client_socket_send(&conn->client_info, &event->reply, -+ sizeof(event->reply)); -+ return rc; -+ } -+ -+ /* No reply required, free the event, and receive the next one */ -+ if (event->admin_ref != NULL) -+ admin_put(event->admin_ref); -+ event->admin_ref = NULL; -+ event_free(event); -+ -+ conn->event = event_new(0, conn); -+ if (conn->event == NULL) { -+ ErrLog("%s: Failed to allocate a new event", __func__); -+ return -ENOMEM; -+ } -+ -+ conn->state = ADMIN_RECEIVE_EVENT; -+ rc = client_socket_receive(&conn->client_info, &conn->event->event, -+ sizeof(conn->event->event)); -+ return rc; -+} -+ -+static inline void admin_get(struct admin_conn_info *conn) -+{ -+ client_socket_get(&conn->client_info); -+} -+ -+static inline void admin_put(struct admin_conn_info *conn) -+{ -+ client_socket_put(&conn->client_info); -+} -+ -+static void admin_hangup(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ -+ DbgLog(DL0, "%s: admin: %p socket: %d state: %d", __func__, conn, -+ conn->client_info.socket, conn->state); -+ -+ if (conn->state == ADMIN_HANGUP) -+ return; -+ conn->state = ADMIN_HANGUP; -+ -+ /* Unlink pending event (if any) */ -+ if (conn->event != NULL) { -+ if (conn->event->admin_ref != NULL) -+ admin_put(conn->event->admin_ref); -+ conn->event->admin_ref = NULL; -+ if (conn->event->proc_ref_count == 0) { -+ event_remove_from_pending_list(conn->event); -+ event_free(conn->event); -+ } -+ conn->event = NULL; -+ } -+ -+ client_socket_term(&conn->client_info); -+ admin_put(conn); -+} -+ -+static void admin_free(void *client) -+{ -+ struct admin_conn_info *conn = client; -+ DL_NODE *node; - --int proc_listener_socket = -1; -+ /* Remove it from the admin connections list */ -+ node = dlist_find(admin_connections, conn); -+ if (node != NULL) { -+ admin_connections = dlist_remove_node(admin_connections, node); -+ listener_client_hangup(&admin_listener); -+ } - --static void close_listener_socket(int socketfd, const char *file_path); -+ DbgLog(DL0, "%s: admin: %p", __func__, conn); -+ free(conn); -+} - --// Creates the daemon's listener socket, to which clients will connect and --// retrieve slot information through. Returns the file descriptor of the --// created socket. --static int create_listener_socket(const char *file_path) -+static int listener_socket_create(const char *file_path) - { - struct sockaddr_un address; - struct group *grp; -- int socketfd; -+ int listener_socket, err; - -- socketfd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); -- if (socketfd < 0) { -- ErrLog("Failed to create listener socket, errno 0x%X.", errno); -+ listener_socket = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); -+ if (listener_socket < 0) { -+ err = errno; -+ ErrLog("%s: Failed to create listener socket, errno %d (%s).", -+ __func__, err, strerror(err)); - return -1; - } - if (unlink(file_path) && errno != ENOENT) { -- ErrLog("Failed to unlink socket file, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Failed to unlink socket file, errno %d (%s).", __func__, -+ err, strerror(err)); - goto error; - } - -@@ -52,50 +1249,389 @@ static int create_listener_socket(const char *file_path) - address.sun_family = AF_UNIX; - strcpy(address.sun_path, file_path); - -- if (bind(socketfd, -+ if (bind(listener_socket, - (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { -- ErrLog("Failed to bind to socket, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Failed to bind to socket, errno %d (%s).", __func__, err, -+ strerror(err)); - goto error; - } - // make socket file part of the pkcs11 group, and write accessable - // for that group - grp = getgrnam("pkcs11"); - if (!grp) { -- ErrLog("Group PKCS#11 does not exist"); -+ ErrLog("%s: Group PKCS#11 does not exist", __func__); - goto error; - } - if (chown(file_path, 0, grp->gr_gid)) { -- ErrLog("Could not change file group on socket, errno 0x%X.", errno); -+ err = errno; -+ ErrLog("%s: Could not change file group on socket, errno %d (%s).", -+ __func__, err, strerror(err)); - goto error; - } - if (chmod(file_path, -- S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP | S_IXUSR | S_IXGRP)) { -- ErrLog("Could not change file permissions on socket, errno 0x%X.", -- errno); -+ S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) { -+ err = errno; -+ ErrLog("%s: Could not change file permissions on socket, errno %d (%s).", -+ __func__, err, strerror(err)); - goto error; - } - -- if (listen(socketfd, 20) != 0) { -- ErrLog("Failed to listen to socket, errno 0x%X.", errno); -+ if (listen(listener_socket, 20) != 0) { -+ err = errno; -+ ErrLog("%s: Failed to listen to socket, errno %d (%s).", __func__, err, -+ strerror(err)); - goto error; - } - -- return socketfd; -+ return listener_socket; - - error: -- if (socketfd >= 0) -- close_listener_socket(socketfd, file_path); -+ if (listener_socket >= 0) -+ listener_socket_close(listener_socket, file_path); - - return -1; - } - - --static void close_listener_socket(int socketfd, const char *file_path) -+static void listener_socket_close(int listener_socket, const char *file_path) - { -- close(socketfd); -+ close(listener_socket); - unlink(file_path); - } - -+ -+ -+static int listener_notify(int events, void *private) -+{ -+ struct listener_info *listener = private; -+ struct sockaddr_un address; -+ socklen_t address_length = sizeof(address); -+ int client_socket, rc, err; -+ -+ if ((events & EPOLLIN) == 0) -+ return 0; -+ -+ /* epoll is edge triggered. We must call accept until we get EWOULDBLOCK */ -+ while (listener->num_clients < listener->max_num_clients) { -+ client_socket = accept(listener->socket, (struct sockaddr *) &address, -+ &address_length); -+ if (client_socket < 0) { -+ err = errno; -+ if (err == EWOULDBLOCK) -+ break; -+ InfoLog("%s: Failed to accept connection on socket %d, errno %d (%s).", -+ __func__, listener->socket, err, strerror(err)); -+ return -err; -+ } -+ -+ rc = listener->new_conn(client_socket, listener); -+ if (rc != 0) { -+ TraceLog("%s: new_conn callback failed for client socket %d, rc: %d", -+ __func__, client_socket, rc); -+ close(client_socket); -+ continue; -+ } -+ -+ listener->num_clients++; -+ } -+ -+ return 0; -+} -+ -+static int listener_client_hangup(struct listener_info *listener) -+{ -+ int rc, trigger = 0; -+ -+ if (listener->num_clients >= listener->max_num_clients) -+ trigger = 1; /* We were at max clients, trigger accept now */ -+ -+ if (listener->num_clients > 0) -+ listener->num_clients--; -+ -+ if (trigger && listener->num_clients < listener->max_num_clients) { -+ rc = listener_notify(EPOLLIN, listener); -+ if (rc != 0) -+ return rc; -+ } -+ -+ return 0; -+} -+ -+static int listener_create(const char *file_path, -+ struct listener_info *listener, -+ int (* new_conn)(int socket, -+ struct listener_info *listener), -+ unsigned long max_num_clients) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (listener == NULL || new_conn == NULL) -+ return FALSE; -+ -+ memset(listener, 0, sizeof(*listener)); -+ epoll_info_init(&listener->ep_info, listener_notify, NULL, listener); -+ listener->file_path = file_path; -+ listener->new_conn = new_conn; -+ listener->max_num_clients = max_num_clients; -+ -+ listener->socket = listener_socket_create(file_path); -+ if (listener->socket < 0) -+ return FALSE; -+ -+ evt.events = EPOLLIN | EPOLLET; -+ evt.data.ptr = &listener->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listener->socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ TraceLog("%s: Failed add listener socket %d to epoll, errno %d (%s).", -+ __func__, listener->socket, err, strerror(err)); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+static void listener_term(struct listener_info *listener) -+{ -+ if (listener == NULL || listener->socket < 0) -+ return; -+ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, listener->socket, NULL); -+ listener_socket_close(listener->socket, listener->file_path); -+} -+ -+#ifdef WITH_LIBUDEV -+ -+static int udev_mon_init(const char *subsystem, struct udev_mon *udev_mon) -+{ -+ struct epoll_event evt; -+ int rc, err; -+ -+ if (subsystem == NULL || udev_mon == NULL) -+ return FALSE; -+ -+ udev_mon->delayed_event = 0; -+ -+ udev_mon->udev = udev_new(); -+ if (udev_mon->udev == NULL) { -+ ErrLog("%s: udev_new failed", __func__); -+ goto error; -+ } -+ -+ udev_mon->mon = udev_monitor_new_from_netlink(udev_mon->udev, "udev"); -+ if (udev_mon->mon == NULL) { -+ ErrLog("%s: udev_monitor_new_from_netlink failed", __func__); -+ goto error; -+ } -+ -+ /* -+ * Try to increase the receive buffer size. This may fail if the required -+ * privileges are not given. Ignore if it fails. -+ */ -+ udev_monitor_set_receive_buffer_size(udev_mon->mon, UDEV_RECV_BUFFFER_SIZE); -+ -+ rc = udev_monitor_filter_add_match_subsystem_devtype(udev_mon->mon, -+ subsystem, NULL); -+ if (rc != 0) { -+ ErrLog("%s: udev_monitor_filter_add_match_subsystem_devtype failed: " -+ "rc=%d", __func__, rc); -+ goto error; -+ } -+ -+ rc = udev_monitor_enable_receiving(udev_mon->mon); -+ if (rc != 0) { -+ ErrLog("%s: udev_monitor_enable_receiving failed: rc=%d", __func__, rc); -+ goto error; -+ } -+ -+ udev_mon->socket = udev_monitor_get_fd(udev_mon->mon); -+ if (udev_mon->socket < 0) { -+ ErrLog("%s: udev_monitor_get_fd failed", __func__); -+ goto error; -+ } -+ -+ epoll_info_init(&udev_mon->ep_info, udev_mon_notify, NULL, udev_mon); -+ -+ evt.events = EPOLLIN | EPOLLET; -+ evt.data.ptr = &udev_mon->ep_info; -+ rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, udev_mon->socket, &evt); -+ if (rc != 0) { -+ err = errno; -+ ErrLog("%s: Failed add udev_mon socket %d to epoll, errno %d (%s).", -+ __func__, udev_mon->socket, err, strerror(err)); -+ goto error; -+ } -+ -+ /* Epoll is edge triggered, thus try to receive once */ -+ rc = udev_mon_notify(EPOLLIN, udev_mon); -+ if (rc != 0) -+ goto error; -+ -+ return TRUE; -+ -+error: -+ udev_mon_term(udev_mon); -+ return FALSE; -+} -+ -+ -+static int udev_mon_handle_device(struct udev_mon *udev_mon, -+ struct udev_device *dev) -+{ -+ const char *action, *devname, *devpath, *devtype, *dev_type_prop; -+ unsigned int card, domain, dev_type; -+ struct event_info *event; -+ event_udev_apqn_data_t *apqn_data; -+ int rc; -+ -+ UNUSED(udev_mon); -+ -+ action = udev_device_get_action(dev); -+ devname = udev_device_get_sysname(dev); -+ devpath = udev_device_get_devpath(dev); -+ devtype = udev_device_get_devtype(dev); -+ dev_type_prop = udev_device_get_property_value(dev, UDEV_PROERTY_DEVTYPE); -+ -+ if (action == NULL || devname == NULL || devpath == NULL || -+ devtype == NULL || dev_type_prop == NULL) -+ return 0; -+ -+ DbgLog(DL3, "%s: Uevent: ACTION=%s DEVNAME=%s DEVPATH=%s DEVTYPE=%s " -+ "DEV_TYPE=%s", __func__, action, devname, devpath, devtype, -+ dev_type_prop); -+ -+ /* We are only interested in bind and unbind events ... */ -+ if (strcmp(action, UDEV_ACTION_BIND) != 0 && -+ strcmp(action, UDEV_ACTION_UNBIND) != 0) -+ return 0; -+ -+ /* ... for an APQN device */ -+ if (strcmp(devtype, UDEV_ACTION_DEVTYPE_APQN) != 0) -+ return 0; -+ -+ if (sscanf(devname, "%x.%x", &card, &domain) != 2) { -+ TraceLog("%s: failed to parse APQN from DEVNAME: %s", __func__, devname); -+ return -EIO; -+ } -+ if (sscanf(dev_type_prop, "%x", &dev_type) != 1) { -+ TraceLog("%s: failed to parse DEV_TYPE: %s", __func__, dev_type_prop); -+ return -EIO; -+ } -+ -+ event = event_new(sizeof(event_udev_apqn_data_t), NULL); -+ if (event == NULL) { -+ ErrLog("%s: failed to allocate an event", __func__); -+ return -ENOMEM; -+ } -+ -+ if (strcmp(udev_device_get_action(dev), UDEV_ACTION_BIND) == 0) -+ event->event.type = EVENT_TYPE_APQN_ADD; -+ else -+ event->event.type = EVENT_TYPE_APQN_REMOVE; -+ event->event.flags = EVENT_FLAGS_NONE; -+ event->event.token_type = EVENT_TOK_TYPE_ALL; -+ memset(event->event.token_label, ' ', -+ sizeof(event->event.token_label)); -+ -+ apqn_data = (event_udev_apqn_data_t *)event->payload; -+ apqn_data->card = card; -+ apqn_data->domain = domain; -+ apqn_data->device_type = dev_type; -+ -+ DbgLog(DL3, "%s: Event version: %u", __func__, event->event.version); -+ DbgLog(DL3, "%s: Event type: 0x%08x", __func__, event->event.type); -+ DbgLog(DL3, "%s: Event flags: 0x%08x", __func__, event->event.flags); -+ DbgLog(DL3, "%s: Event token_type: 0x%08x", __func__, -+ event->event.token_type); -+ DbgLog(DL3, "%s: Event token_name: '%.32s'", __func__, -+ event->event.token_label); -+ DbgLog(DL3, "%s: Event process_id: %u", __func__, event->event.process_id); -+ DbgLog(DL3, "%s: Event payload_len: %u", __func__, -+ event->event.payload_len); -+ -+ DbgLog(DL3, "%s: Payload: card: %u", __func__, apqn_data->card); -+ DbgLog(DL3, "%s: Payload: domain: %u", __func__, apqn_data->domain); -+ DbgLog(DL3, "%s: Payload: dev.type: %u", __func__, apqn_data->device_type); -+ -+ rc = event_start_deliver(event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay event delivery */ -+ udev_mon->delayed_event = event; -+ return -ENOSPC; -+ } -+ event_free(event); -+ return rc; -+ } -+ -+ return 0; -+} -+ -+static int udev_mon_notify(int events, void *private) -+{ -+ struct udev_mon *udev_mon = private; -+ struct udev_device *dev; -+ struct event_info *event; -+ int rc; -+ -+ DbgLog(DL3, "%s: Epoll event on udev_mon socket %d: events: 0x%x", -+ __func__, udev_mon->socket, events); -+ -+ if (udev_mon->delayed_event != NULL) { -+ /* Deliver delayed event first */ -+ event = udev_mon->delayed_event; -+ udev_mon->delayed_event = NULL; -+ -+ rc = event_start_deliver(event); -+ if (rc != 0) { -+ if (rc == -ENOSPC) { -+ /* Event limit reached, delay event delivery */ -+ udev_mon->delayed_event = event; -+ return 0; -+ } -+ event_free(event); -+ return rc; -+ } -+ } -+ -+ while (1) { -+ dev = udev_monitor_receive_device(udev_mon->mon); -+ if (dev == NULL) -+ break; /* this is just like EWOULDBLOCK */ -+ -+ rc = udev_mon_handle_device(udev_mon, dev); -+ if (rc != 0) -+ TraceLog("%s: udev_mon_handle_device failed, rc: %d", __func__, rc); -+ -+ udev_device_unref(dev); -+ -+ /* If event limit reached, stop receiving more events */ -+ if (rc == -ENOSPC) -+ break; -+ }; -+ -+ return 0; -+} -+ -+static void udev_mon_term(struct udev_mon *udev_mon) -+{ -+ if (udev_mon == NULL) -+ return; -+ -+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL); -+ if (udev_mon->udev != NULL) -+ udev_unref(udev_mon->udev); -+ if (udev_mon->mon != NULL) -+ udev_monitor_unref(udev_mon->mon); -+ -+ if (udev_mon->delayed_event != NULL) -+ event_free(udev_mon->delayed_event); -+} -+ -+#endif -+ - int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; -@@ -106,7 +1642,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - - /* check that we read in correct amount of slots */ - if (processed != NumberSlotsInDB) { -- ErrLog("Failed to populate slot info.\n"); -+ ErrLog("%s: Failed to populate slot info.", __func__); - return FALSE; - } - -@@ -115,72 +1651,277 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - - int socket_connection_handler(int timeout_secs) - { -- int returnVal; -- fd_set set; -- struct timeval timeout; -- -- FD_ZERO(&set); -- FD_SET(proc_listener_socket, &set); -+ struct epoll_event events[MAX_EPOLL_EVENTS]; -+ int num_events, i, rc, err; -+ struct epoll_info *info; - -- timeout.tv_sec = timeout_secs; -- timeout.tv_usec = 0; -- -- returnVal = select(proc_listener_socket + 1, &set, NULL, NULL, &timeout); -- if (returnVal == -1) { -- ErrLog("select failed on socket connection, errno 0x%X.", errno); -- return FALSE; -- } else if (returnVal == 0) { -- // select call timed out, return -- return FALSE; -- } else { -- struct sockaddr_un address; -- socklen_t address_length = sizeof(address); -- -- int connectionfd = accept(proc_listener_socket, -- (struct sockaddr *) &address, -- &address_length); -- if (connectionfd < 0) { -- if (errno != EAGAIN && errno != EWOULDBLOCK) { -- /* These errors are allowed since -- * socket is non-blocking -- */ -- ErrLog("Failed to accept socket connection, errno 0x%X.", -- errno); -- } -+ do { -+ num_events = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENTS, -+ timeout_secs * 1000); -+ if (num_events < 0) { -+ err = errno; -+ if (err == EINTR) -+ continue; -+ ErrLog("%s: epoll_wait failed, errno %d (%s).", __func__, err, -+ strerror(err)); - return FALSE; - } - -- DbgLog(DL0, "Accepted connection from process: socket: %d", -- connectionfd); -+ /* -+ * Inc ref count of all epoll_infos returned by epoll before handling -+ * any of them via notify. The notify callback may hangup any of -+ * the connections associated with the returned epoll_infos, and we -+ * need to avoid them getting freed before we all handled them. -+ */ -+ for (i = 0; i < num_events; i++) -+ epoll_info_get(events[i].data.ptr); - -- if (write(connectionfd, &socketData, sizeof(socketData)) != -- sizeof(socketData)) { -- ErrLog("Failed to write socket data, errno 0x%X.", errno); -- close(connectionfd); -- return FALSE; -+ for (i = 0; i < num_events; i++) { -+ info = events[i].data.ptr; -+ if (info == NULL || info->notify == NULL) -+ continue; -+ -+ rc = info->notify(events[i].events, info->private); -+ if (rc != 0) -+ TraceLog("%s: notify callback failed, rc: %d", __func__, rc); -+ -+ epoll_info_put(info); - } -- close(connectionfd); -- return TRUE; -- } -+ } while (num_events > 0 && rc == 0); /* num_events = 0: timeout */ -+ -+ return TRUE; - } - - int init_socket_server() - { -- proc_listener_socket = create_listener_socket(PROC_SOCKET_FILE_PATH); -- if (proc_listener_socket < 0) -+ int err; -+ -+ epoll_fd = epoll_create1(0); -+ if (epoll_fd < 0) { -+ err = errno; -+ ErrLog("%s: Failed to open epoll socket, errno %d (%s).", __func__, err, -+ strerror(err)); -+ return FALSE; -+ } -+ -+ if (!listener_create(PROC_SOCKET_FILE_PATH, &proc_listener, -+ proc_new_conn, NUMBER_PROCESSES_ALLOWED)) { -+ term_socket_server(); -+ return FALSE; -+ } -+ -+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -+ term_socket_server(); - return FALSE; -+ } -+ -+#ifdef WITH_LIBUDEV -+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -+ term_socket_server(); -+ return FALSE; -+ } -+#endif - -- DbgLog(DL0, "Socket server started"); -+ DbgLog(DL0, "%s: Socket server started", __func__); - - return TRUE; - } - - int term_socket_server() - { -- if (proc_listener_socket >= 0) -- close_listener_socket(proc_listener_socket, PROC_SOCKET_FILE_PATH); -+ DL_NODE *node, *next; -+ -+#ifdef WITH_LIBUDEV -+ udev_mon_term(&udev_mon); -+#endif -+ -+ listener_term(&proc_listener); -+ listener_term(&admin_listener); -+ -+ node = dlist_get_first(proc_connections); -+ while (node != NULL) { -+ next = dlist_next(node); -+ proc_hangup(node->data); -+ node = next; -+ } -+ dlist_purge(proc_connections); - -- DbgLog(DL0, "Socket server stopped"); -+ node = dlist_get_first(admin_connections); -+ while (node != NULL) { -+ next = dlist_next(node); -+ admin_hangup(node->data); -+ node = next; -+ } -+ dlist_purge(admin_connections); -+ -+ node = dlist_get_first(pending_events); -+ while (node != NULL) { -+ next = dlist_next(node); -+ event_free((struct event_info *)node->data); -+ node = next; -+ } -+ dlist_purge(pending_events); -+ -+ if (epoll_fd >= 0) -+ close(epoll_fd); -+ epoll_fd = -1; -+ -+ DbgLog(DL0, "%s: Socket server stopped", __func__); - - return TRUE; - } -+ -+#ifdef DEV -+ -+static void dump_listener(struct listener_info *listener) -+{ -+ DbgLog(DL0, " socket: %d", listener->socket); -+ DbgLog(DL0, " file_path: %s", listener->file_path); -+ DbgLog(DL0, " ep_info.ref_count: %lu", listener->ep_info.ref_count); -+ DbgLog(DL0, " num_clients: %lu", listener->num_clients); -+ DbgLog(DL0, " max_num_clients: %lu", listener->max_num_clients); -+} -+ -+static void dump_event_msg(event_msg_t *event, int indent) -+{ -+ DbgLog(DL0, "%*sevent version: %u", indent, "", event->version); -+ DbgLog(DL0, "%*sevent type: %08x", indent, "", event->type); -+ DbgLog(DL0, "%*sevent flags: %08x", indent, "", event->flags); -+ DbgLog(DL0, "%*sevent token_type: %08x", indent, "", event->token_type); -+ DbgLog(DL0, "%*sevent token_label: '%.32s'", indent, "", event->token_label); -+ DbgLog(DL0, "%*sevent process_id: %lu", indent, "", event->process_id); -+ DbgLog(DL0, "%*sevent payload_len: %u", indent, "", event->payload_len); -+} -+ -+static void dump_event_reply(event_reply_t *reply, int indent) -+{ -+ DbgLog(DL0, "%*sreply version: %u", indent, "", reply->version); -+ DbgLog(DL0, "%*sreply positive_replies: %u", indent, "", reply->positive_replies); -+ DbgLog(DL0, "%*sreply negative_replies: %u", indent, "", reply->negative_replies); -+ DbgLog(DL0, "%*sreply nothandled_replies: %u", indent, "", reply->nothandled_replies); -+} -+ -+static void dump_event_info(struct event_info *event, int indent) -+{ -+ dump_event_msg(&event->event, indent); -+ dump_event_reply(&event->reply, indent); -+ DbgLog(DL0, "%*sproc_ref_count: %lu", indent, "", event->proc_ref_count); -+ if (event->admin_ref != NULL) -+ DbgLog(DL0, "%*sadmin_ref: %p", indent, "", event->admin_ref); -+ else -+ DbgLog(DL0, "%*sadmin_ref: None", indent, ""); -+} -+ -+static void dump_proc_conn(struct proc_conn_info *proc_conn) -+{ -+ DL_NODE *node; -+ unsigned long i; -+ -+ DbgLog(DL0, " socket: %d", proc_conn->client_info.socket); -+ DbgLog(DL0, " state: %d", proc_conn->state); -+ DbgLog(DL0, " ref-count: %lu", proc_conn->client_info.ep_info.ref_count); -+ DbgLog(DL0, " xfer state: %d", proc_conn->client_info.xfer_state); -+ DbgLog(DL0, " xfer size: %d", proc_conn->client_info.xfer_size); -+ DbgLog(DL0, " xfer offset: %d", proc_conn->client_info.xfer_offset); -+ DbgLog(DL0, " pending events:"); -+ node = dlist_get_first(proc_conn->events); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " event %lu (%p):", i, node->data); -+ dump_event_info(node->data, 10); -+ node = dlist_next(node); -+ i++; -+ } -+ if (proc_conn->event != NULL) { -+ DbgLog(DL0, " current event:"); -+ dump_event_info(proc_conn->event, 8); -+ DbgLog(DL0, " current reply:"); -+ dump_event_reply(&proc_conn->reply, 8); -+ } else { -+ DbgLog(DL0, " current event: none"); -+ } -+} -+ -+static void dump_admin_conn(struct admin_conn_info *admin_conn) -+{ -+ DbgLog(DL0, " socket: %d", admin_conn->client_info.socket); -+ DbgLog(DL0, " state: %d", admin_conn->state); -+ DbgLog(DL0, " ref-count: %lu", admin_conn->client_info.ep_info.ref_count); -+ DbgLog(DL0, " xfer state: %d", admin_conn->client_info.xfer_state); -+ DbgLog(DL0, " xfer size: %d", admin_conn->client_info.xfer_size); -+ DbgLog(DL0, " xfer offset: %d", admin_conn->client_info.xfer_offset); -+ if (admin_conn->event != NULL) { -+ DbgLog(DL0, " current event (%p):", admin_conn->event); -+ dump_event_info(admin_conn->event, 8); -+ } else { -+ DbgLog(DL0, " current event: none"); -+ } -+} -+ -+#ifdef WITH_LIBUDEV -+void dump_udev_mon(struct udev_mon *udev_mon) -+{ -+ DbgLog(DL0, " socket: %d", udev_mon->socket); -+ DbgLog(DL0, " udev: %p", udev_mon->udev); -+ DbgLog(DL0, " mon: %p", udev_mon->mon); -+ DbgLog(DL0, " ep_info.ref_count: %lu", udev_mon->ep_info.ref_count); -+ if (udev_mon->delayed_event != NULL) { -+ DbgLog(DL0, " delayed_event (%p):", udev_mon->delayed_event); -+ dump_event_info(udev_mon->delayed_event, 6); -+ } else { -+ DbgLog(DL0, " delayed_event: node"); -+ } -+} -+#endif -+ -+void dump_socket_handler() -+{ -+ DL_NODE *node; -+ unsigned long i; -+ -+ DbgLog(DL0, "%s: Dump of socket handler data:", __func__); -+ DbgLog(DL0, " epoll_fd: %d", epoll_fd); -+ -+ DbgLog(DL0, " proc_listener (%p): ", &proc_listener); -+ dump_listener(&proc_listener); -+ -+ DbgLog(DL0, " proc_connections: "); -+ node = dlist_get_first(proc_connections); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " proc_connection %lu (%p): ", i, node->data); -+ dump_proc_conn(node->data); -+ i++; -+ node = dlist_next(node); -+ } -+ -+ DbgLog(DL0, " admin_listener (%p): ", &admin_listener); -+ dump_listener(&admin_listener); -+ -+ DbgLog(DL0, " admin_connections: "); -+ node = dlist_get_first(admin_connections); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " admin_connection %lu (%p): ", i, node->data); -+ dump_admin_conn(node->data); -+ i++; -+ node = dlist_next(node); -+ } -+ -+#ifdef WITH_LIBUDEV -+ DbgLog(DL0, " udev_mon (%p): ", &udev_mon); -+ dump_udev_mon(&udev_mon); -+#endif -+ -+ DbgLog(DL0, " pending events (%lu): ", pending_events_count); -+ node = dlist_get_first(pending_events); -+ i = 1; -+ while (node != NULL) { -+ DbgLog(DL0, " event %lu (%p): ", i, node->data); -+ dump_event_info(node->data, 6); -+ i++; -+ node = dlist_next(node); -+ } -+} -+#endif diff --git a/SOURCES/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch b/SOURCES/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch deleted file mode 100644 index 8a3d581..0000000 --- a/SOURCES/opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit 4e3b43c3d8844402c04a66b55c6c940f965109f0 -Author: Ingo Franzki -Date: Mon May 3 10:05:07 2021 +0200 - - SOFT: Check the EC Key on C_CreateObject and C_DeriveKey - - When constructing an OpenSSL EC public or private key from PKCS#11 - attributes or ECDH public data, check that the key is valid, i.e. that - the point is on the curve. - - This prevents one from creating an EC key object via C_CreateObject with - invalid key data. It also prevents C_DeriveKey to derive a secret using - ECDH with an EC public key (public data) that uses a different curve - or is invalid by other means. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c -index c30be1da..aeff39a9 100644 ---- a/usr/lib/soft_stdll/soft_specific.c -+++ b/usr/lib/soft_stdll/soft_specific.c -@@ -4365,6 +4365,12 @@ static CK_RV fill_ec_key_from_pubkey(EC_KEY *ec_key, const CK_BYTE *data, - goto out; - } - -+ if (!EC_KEY_check_key(ec_key)) { -+ TRACE_ERROR("EC_KEY_check_key failed\n"); -+ rc = CKR_PUBLIC_KEY_INVALID; -+ goto out; -+ } -+ - out: - if (allocated && ecpoint != NULL) - free(ecpoint); -@@ -4404,6 +4410,12 @@ static CK_RV fill_ec_key_from_privkey(EC_KEY *ec_key, const CK_BYTE *data, - goto out; - } - -+ if (!EC_KEY_check_key(ec_key)) { -+ TRACE_ERROR("EC_KEY_check_key failed\n"); -+ rc = CKR_FUNCTION_FAILED; -+ goto out; -+ } -+ - out: - if (point != NULL) - EC_POINT_free(point); diff --git a/SOURCES/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch b/SOURCES/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch deleted file mode 100644 index c38fef0..0000000 --- a/SOURCES/opencryptoki-3.16.0-5824364d995e5d2418f885ee57e377e11d1b3302.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 5824364d995e5d2418f885ee57e377e11d1b3302 -Author: Ingo Franzki -Date: Wed Jul 7 13:44:46 2021 +0200 - - pkcstok_migrate: Quote strings with spaces in opencryptoki.conf - - When modifying opencryptoki.conf during token migration, put quotes - around strings that contain spaces, e.g. for the slot description and - manufacturer. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 94fd1196..3df1596e 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2107,7 +2107,10 @@ static int parseupdate_key_str(void *private, int tok, const char *val) - { - struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_TOKVERSION) -+ if (tok != KW_HWVERSION && tok != KW_FWVERSION && -+ strchr(val, ' ') != NULL) -+ fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -+ else if (tok != KW_TOKVERSION) - fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); - return 0; - } diff --git a/SOURCES/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch b/SOURCES/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch deleted file mode 100644 index 0494a35..0000000 --- a/SOURCES/opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 69244a5e0d9dfec3ef534b19b89a541576bb17dc -Author: Ingo Franzki -Date: Tue Feb 9 10:47:57 2021 +0100 - - TRACE: Use gettid() if SYS_gettid is not defined - - Also print the thread ID in the trace, if SYS_gettid is not defined. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/trace.c b/usr/lib/common/trace.c -index 678c0b96..bdc5256a 100644 ---- a/usr/lib/common/trace.c -+++ b/usr/lib/common/trace.c -@@ -33,6 +33,8 @@ - - #ifdef SYS_gettid - #define __gettid() syscall(SYS_gettid) -+#else -+#define __gettid() gettid() - #endif - - pthread_mutex_t tlmtx = PTHREAD_MUTEX_INITIALIZER; diff --git a/SOURCES/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch b/SOURCES/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch deleted file mode 100644 index 86ba3f0..0000000 --- a/SOURCES/opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch +++ /dev/null @@ -1,367 +0,0 @@ -commit 7b7d83c571ceb3050969359817d4145600f14ae8 -Author: Ingo Franzki -Date: Fri Apr 9 17:07:31 2021 +0200 - - Check CKF_LIBRARY_CANT_CREATE_OS_THREADS at C_Initialize - - Fail if flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set at C_Initialize, - and event support is enabled (this is the default). We need to use pthreads - for the event thread, so we can't work if CKF_LIBRARY_CANT_CREATE_OS_THREADS - is set. Fail with CKR_NEED_TO_CREATE_THREADS if so. - - The event support can be globally disabled using keyword 'disable-event-support' - in opencryptoki.conf. This disables pkcsslots to accept admin connections, - and it does not monitor for AP UDEV events (on s390 platform). No event - thread is started in the opencryptoki processes, thus we can accept if flag - CKF_LIBRARY_CANT_CREATE_OS_THREADS is set in that case. - - Signed-off-by: Ingo Franzki - -diff --git a/man/man5/opencryptoki.conf.5.in b/man/man5/opencryptoki.conf.5.in -index 71218f79..7dc676ab 100644 ---- a/man/man5/opencryptoki.conf.5.in -+++ b/man/man5/opencryptoki.conf.5.in -@@ -10,8 +10,16 @@ pkcs#11 slots. At startup, the pkcsslotd daemon parses this file to - determine which slots will be made available. - - .SH SYNTAX --This file is made up of slot descriptions. Each slot description --is composed of a slot number, brackets and key-value pairs. -+This file is made up of optional global definitions, and slot descriptions. -+ -+The following global definitions are valid: -+ -+.TP -+.BR disable-event-support -+If this keyword is specified the openCryptoki event support is disabled. -+ -+.P -+Each slot description is composed of a slot number, brackets and key-value pairs. - - slot number - { -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index e37368a5..451a8cf1 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -99,6 +99,7 @@ typedef struct { - LW_SHM_TYPE *shm_addr; // token specific shm address - } Slot_Info_t; - -+#define FLAG_EVENT_SUPPORT_DISABLED 0x01 - - #ifdef PKCS64 - -@@ -200,6 +201,7 @@ typedef struct { - - typedef struct { - uint8 num_slots; -+ uint8 flags; - CK_INFO_64 ck_info; - Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED]; - } Slot_Mgr_Socket_t; -@@ -214,6 +216,7 @@ typedef struct { - - typedef struct { - uint8 num_slots; -+ uint8 flags; - CK_INFO ck_info; - Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED]; - } Slot_Mgr_Socket_t; -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index 2873a20a..6517ca6c 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -308,7 +308,8 @@ void parent_fork_after() - return; - - /* Restart the event thread in the parent when fork is complete */ -- if (Anchor->event_thread == 0) -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ Anchor->event_thread == 0) - start_event_thread(); - } - -@@ -2752,13 +2753,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - goto error; - } - } -- // If we EVER need to create threads from this library we must -- // check the Flags for the Can_Create_OS_Threads flag -- // Right now the library DOES NOT create threads and therefore this -- // check is irrelavant. -- if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) { -- TRACE_DEVEL("Can't create OS threads...This is OK\n"); -- } -+ - // Since this is an initialization path, we will be verbose in the - // code rather than efficient. - // -@@ -2848,7 +2843,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - rc = CKR_FUNCTION_FAILED; - goto error_shm; - } -- // Initialize structure values -+ -+ if (pVoid != NULL) { -+ pArg = (CK_C_INITIALIZE_ARGS *) pVoid; -+ -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) != 0) { -+ TRACE_ERROR("Flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set and " -+ "event support is enabled\n"); -+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Application specified that " -+ "library can't create OS threads. PKCS11 Module requires " -+ "to create threads when event support is enabled.\n"); -+ rc = CKR_NEED_TO_CREATE_THREADS; -+ goto error; -+ } -+ } - - //Register with pkcsslotd - if (!API_Register()) { -@@ -2867,7 +2876,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - - /* Start event receiver thread */ -- if (start_event_thread() != 0) { -+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 && -+ start_event_thread() != 0) { - TRACE_ERROR("Failed to start event thread\n"); - - // unload all the STDLL's from the application -diff --git a/usr/lib/common/configparser.h b/usr/lib/common/configparser.h -index 13ca648d..b3c32496 100644 ---- a/usr/lib/common/configparser.h -+++ b/usr/lib/common/configparser.h -@@ -35,6 +35,7 @@ typedef int (*end_slot_f)(void *private); - typedef int (*key_str_f)(void *private, int tok, const char *val); - typedef int (*key_vers_f)(void *private, int tok, unsigned int vers); - typedef void (*eolcomment_f)(void *private, const char *comment); -+typedef void (*disab_event_supp_f)(void *private); - /* - * Report an error. If the error is not reported by the parser itself - * but via one of the parse functions, \c parsermsg will be \c NULL. -@@ -52,6 +53,7 @@ typedef void (*error_f)(void *private, int line, const char *parsermsg); - */ - struct parsefuncs { - ockversion_f version; -+ disab_event_supp_f disab_event_supp; - eol_f eol; - begin_slot_f begin_slot; - end_slot_f end_slot; -diff --git a/usr/lib/common/lexer.l b/usr/lib/common/lexer.l -index b35a0b72..38cbcb70 100644 ---- a/usr/lib/common/lexer.l -+++ b/usr/lib/common/lexer.l -@@ -69,6 +69,7 @@ extern char *configparse_strdup(const char *s); - - version return OCKVERSION; - slot return SLOT; -+disable-event-support return DISABLE_EVENT_SUPPORT; - - [^\"= \t\n]+ { - yylval.str = configparse_strdup(yytext); -diff --git a/usr/lib/common/parser.y b/usr/lib/common/parser.y -index 86806fcb..40c3994d 100644 ---- a/usr/lib/common/parser.y -+++ b/usr/lib/common/parser.y -@@ -65,7 +65,7 @@ int lookup_keyword(const char *key); - int err; - } - --%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF -+%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF DISABLE_EVENT_SUPPORT - %token STRING - %token KEYWORD - %token INTEGER -@@ -81,6 +81,7 @@ config_file: - - sections: - version_def eolcomment -+ | disable_event_support_def eolcomment - | SLOT INTEGER BEGIN_DEF - { - if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) { -@@ -125,6 +126,13 @@ version_def: - } - configparse_freestringsfrom($2); - } -+ -+disable_event_support_def: -+ DISABLE_EVENT_SUPPORT -+ { -+ if (parsefuncs->disab_event_supp) -+ parsefuncs->disab_event_supp(parsedata); -+ } - - line_def: - STRING EQUAL TOKVERSION -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index d7edcb3c..1dd0bac9 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -88,7 +88,7 @@ int XProcLock(void); - int XProcUnLock(void); - int CreateXProcLock(void); - --int init_socket_server(); -+int init_socket_server(int event_support_disabled); - int term_socket_server(); - int init_socket_data(Slot_Mgr_Socket_t *sp); - int socket_connection_handler(int timeout_secs); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index efbfe8fd..3b328a6c 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -34,6 +34,7 @@ int shmid; - key_t tok; - Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; - unsigned int NumberSlotsInDB = 0; -+int event_support_disabled = 0; - - Slot_Info_t_64 *psinfo; - -@@ -467,6 +468,13 @@ static int slotmgr_key_vers(void *private, int tok, unsigned int vers) - return 1; - } - -+static void slotmgr_disab_event_supp(void *private) -+{ -+ UNUSED(private); -+ -+ event_support_disabled = 1; -+} -+ - static void slotmgr_parseerror(void *private, int line, const char *parsermsg) - { - struct parse_data *d = (struct parse_data *)private; -@@ -480,6 +488,7 @@ static struct parsefuncs slotmgr_parsefuncs = { - .end_slot = slotmgr_end_slot, - .key_str = slotmgr_key_str, - .key_vers = slotmgr_key_vers, -+ .disab_event_supp = slotmgr_disab_event_supp, - .parseerror = slotmgr_parseerror - }; - -@@ -568,7 +577,7 @@ int main(int argc, char *argv[], char *envp[]) - if (!XProcUnLock()) - return 4; - -- if (!init_socket_server()) { -+ if (!init_socket_server(event_support_disabled)) { - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -582,6 +591,8 @@ int main(int argc, char *argv[], char *envp[]) - DestroySharedMemory(); - return 6; - } -+ if (event_support_disabled) -+ socketData.flags |= FLAG_EVENT_SUPPORT_DISABLED; - - /* Create customized token directories */ - psinfo = &socketData.slot_info[0]; -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index 41408670..3aa40267 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -139,12 +139,12 @@ struct event_info { - }; - - static int epoll_fd = -1; --static struct listener_info proc_listener; -+static struct listener_info proc_listener = { .socket = -1 }; - static DL_NODE *proc_connections = NULL; --static struct listener_info admin_listener; -+static struct listener_info admin_listener = { .socket = -1 }; - static DL_NODE *admin_connections = NULL; - #ifdef WITH_LIBUDEV --static struct udev_mon udev_mon; -+static struct udev_mon udev_mon = { .socket = -1 }; - #endif - static DL_NODE *pending_events = NULL; - static unsigned long pending_events_count = 0; -@@ -1620,6 +1620,9 @@ static void udev_mon_term(struct udev_mon *udev_mon) - if (udev_mon == NULL) - return; - -+ if (udev_mon->socket < 0) -+ return; -+ - epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL); - if (udev_mon->udev != NULL) - udev_unref(udev_mon->udev); -@@ -1636,6 +1639,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; - -+ socketData->flags = 0; - PopulateCKInfo(&(socketData->ck_info)); - socketData->num_slots = NumberSlotsInDB; - PopulateSlotInfo(socketData->slot_info, &processed); -@@ -1692,7 +1696,7 @@ int socket_connection_handler(int timeout_secs) - return TRUE; - } - --int init_socket_server() -+int init_socket_server(int event_support_disabled) - { - int err; - -@@ -1710,18 +1714,20 @@ int init_socket_server() - return FALSE; - } - -- if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -- admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -- term_socket_server(); -- return FALSE; -- } -+ if (!event_support_disabled) { -+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener, -+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) { -+ term_socket_server(); -+ return FALSE; -+ } - - #ifdef WITH_LIBUDEV -- if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -- term_socket_server(); -- return FALSE; -- } -+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) { -+ term_socket_server(); -+ return FALSE; -+ } - #endif -+ } - - DbgLog(DL0, "%s: Socket server started", __func__); - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 7c225730..94fd1196 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2066,6 +2066,13 @@ static int parseupdate_ockversion(void *private, const char *version) - return 0; - } - -+static void parseupdate_disab_event_supp(void *private) -+{ -+ struct parseupdate *u = (struct parseupdate *)private; -+ -+ fprintf(u->f, "disable-event-support"); -+} -+ - static void parseupdate_eol(void *private) - { - struct parseupdate *u = (struct parseupdate *)private; -@@ -2124,6 +2131,7 @@ static void parseupdate_eolcomment(void *private, const char *comment) - - static struct parsefuncs parseupdatefuncs = { - .version = parseupdate_ockversion, -+ .disab_event_supp = parseupdate_disab_event_supp, - .eol = parseupdate_eol, - .begin_slot = parseupdate_begin_slot, - .end_slot = parseupdate_end_slot, diff --git a/SOURCES/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch b/SOURCES/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch deleted file mode 100644 index fd0c13c..0000000 --- a/SOURCES/opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch +++ /dev/null @@ -1,1023 +0,0 @@ -commit b048be548508dd1958bb7271568f388d0f6cbcf8 -Author: Ingo Franzki -Date: Mon Feb 8 16:50:00 2021 +0100 - - Event support: API and token level changes - - Signed-off-by: Ingo Franzki - -diff --git a/usr/include/apictl.h b/usr/include/apictl.h -index 8898cae3..81c65dad 100644 ---- a/usr/include/apictl.h -+++ b/usr/include/apictl.h -@@ -57,6 +57,8 @@ typedef struct { - API_Slot_t SltList[NUMBER_SLOTS_MANAGED]; - DLL_Load_t DLLs[NUMBER_SLOTS_MANAGED]; // worst case we have a separate DLL - // per slot -+ int socketfd; -+ pthread_t event_thread; - } API_Proc_Struct_t; - - #endif -diff --git a/usr/include/events.h b/usr/include/events.h -new file mode 100644 -index 00000000..dac6ad52 ---- /dev/null -+++ b/usr/include/events.h -@@ -0,0 +1,83 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "local_types.h" -+#include "pkcs32.h" -+ -+#ifndef _EVENTS_H -+#define _EVENTS_H -+ -+typedef struct { -+ unsigned int version; /* EVENT_VERSION_xxx */ -+ unsigned int type; /* EVENT_TYPE_xxx */ -+ unsigned int flags; /* EVENT_FLAGS_xxx */ -+ unsigned int token_type; /* Destination token type: EVENT_TOK_TYPE_xxx */ -+ char token_label[member_size(CK_TOKEN_INFO_32, label)]; -+ /* Label of destination token (or blanks) */ -+ pid_t process_id; /* Process ID of destination process (or 0) */ -+ unsigned int payload_len; /* Length of payload in bytes */ -+ /* Followed by payload_len bytes of payload (event specific) */ -+} __attribute__ ((__packed__)) event_msg_t; -+ -+typedef struct { -+ unsigned int version; /* EVENT_VERSION_xxx */ -+ unsigned int positive_replies; /* Number of tokens that replied a */ -+ unsigned int negative_replies; /* positive, or negative feedback, */ -+ unsigned int nothandled_replies; /* or that did not handle the event. */ -+ /* Note: Only tokens matching the event -+ * destination fields (pid, label, -+ * token-type) are counted. */ -+} __attribute__ ((__packed__)) event_reply_t; -+ -+/* Event and reply versions */ -+#define EVENT_VERSION_1 1 -+ -+/* Event classes (encoded into event type) */ -+#define EVENT_CLASS_MASK 0xffff0000 -+#define EVENT_CLASS_UDEV 0x00010000 -+#define EVENT_CLASS_ADMIN 0x00020000 -+ -+/* Event types */ -+#define EVENT_TYPE_APQN_ADD EVENT_CLASS_UDEV + 0x00000001 -+#define EVENT_TYPE_APQN_REMOVE EVENT_CLASS_UDEV + 0x00000002 -+ -+/* Event flags */ -+#define EVENT_FLAGS_NONE 0x00000000 -+#define EVENT_FLAGS_REPLY_REQ 0x00000001 -+ -+/* Event token destination types */ -+#define EVENT_TOK_TYPE_ALL 0x00000000 -+#define EVENT_TOK_TYPE_CCA 0x00000001 -+#define EVENT_TOK_TYPE_EP11 0x00000002 -+ -+/* Maximum event payload length 128k */ -+#define EVENT_MAX_PAYLOAD_LENGTH (128 * 1024) -+ -+/* Event payload for EVENT_TYPE_APQN_ADD and EVENT_TYPE_APQN_REMOVE */ -+typedef struct { -+ unsigned short card; -+ unsigned short domain; -+ unsigned int device_type; /* from uevent DEV_TYPE property */ -+} __attribute__ ((__packed__)) event_udev_apqn_data_t; -+ -+/* AP device types */ -+#define AP_DEVICE_TYPE_CEX3A 8 -+#define AP_DEVICE_TYPE_CEX3C 9 -+#define AP_DEVICE_TYPE_CEX4 10 -+#define AP_DEVICE_TYPE_CEX5 11 -+#define AP_DEVICE_TYPE_CEX6 12 -+#define AP_DEVICE_TYPE_CEX7 13 -+ -+#endif -diff --git a/usr/include/include.mk b/usr/include/include.mk -index a36afb25..79e593d7 100644 ---- a/usr/include/include.mk -+++ b/usr/include/include.mk -@@ -7,4 +7,5 @@ opencryptokiinclude_HEADERS = \ - - noinst_HEADERS += \ - usr/include/apictl.h usr/include/local_types.h \ -- usr/include/pkcs32.h usr/include/slotmgr.h usr/include/stdll.h -+ usr/include/pkcs32.h usr/include/slotmgr.h usr/include/stdll.h \ -+ usr/include/events.h -diff --git a/usr/include/local_types.h b/usr/include/local_types.h -index f03c6629..c7c7f5ec 100644 ---- a/usr/include/local_types.h -+++ b/usr/include/local_types.h -@@ -11,6 +11,8 @@ - #ifndef __LOCAL_TYPES - #define __LOCAL_TYPES - -+#define member_size(type, member) sizeof(((type *)0)->member) -+ - typedef unsigned char uint8; - - typedef unsigned short uint16; -diff --git a/usr/include/stdll.h b/usr/include/stdll.h -index 57f6c6e8..9a3b760c 100644 ---- a/usr/include/stdll.h -+++ b/usr/include/stdll.h -@@ -350,6 +350,11 @@ typedef CK_RV (CK_PTR ST_C_IBM_ReencryptSingle)(STDLL_TokData_t *tokdata, - CK_BYTE_PTR pReencryptedData, - CK_ULONG_PTR pulReencryptedDataLen); - -+typedef CK_RV (CK_PTR ST_C_HandleEvent)(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len); - - struct ST_FCN_LIST { - -@@ -424,6 +429,9 @@ struct ST_FCN_LIST { - ST_C_CancelFunction ST_CancelFunction; - - ST_C_IBM_ReencryptSingle ST_IBM_ReencryptSingle; -+ -+ /* The functions defined below are not part of the external API */ -+ ST_C_HandleEvent ST_HandleEvent; - }; - - typedef struct ST_FCN_LIST STDLL_FcnList_t; -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index f1ee9132..b74b763f 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -286,7 +286,31 @@ void child_fork_initializer() - if (Anchor != NULL) - C_Finalize(NULL); - in_child_fork_initializer = FALSE; -- } -+} -+ -+void parent_fork_prepare() -+{ -+ if (Anchor == NULL) -+ return; -+ -+ /* -+ * Stop the event thread in the fork parent, since having the event thread -+ * active when a fork is performed causes various problems (e.g. deadlocks -+ * in glibc). -+ */ -+ if (Anchor->event_thread > 0) -+ stop_event_thread(); -+} -+ -+void parent_fork_after() -+{ -+ if (Anchor == NULL) -+ return; -+ -+ /* Restart the event thread in the parent when fork is complete */ -+ if (Anchor->event_thread == 0) -+ start_event_thread(); -+} - - //------------------------------------------------------------------------ - // API function C_CancelFunction -@@ -1501,6 +1525,20 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) - - shData = &(Anchor->SocketDataP); - -+ /* -+ * Stop the event thread and close the socket. -+ * If C_Finalize is called as part of the fork initializer, don't stop -+ * the thread, since a forked process does not have any threads, and don't -+ * close the socket, as this would close the connection of the parent -+ * process to the pkcsslotd as well. -+ * */ -+ if (!in_child_fork_initializer) { -+ if (Anchor->event_thread > 0) -+ stop_event_thread(); -+ if (Anchor->socketfd >= 0) -+ close(Anchor->socketfd); -+ } -+ - // unload all the STDLL's from the application - // This is in case the APP decides to do the re-initialize and - // continue on -@@ -2642,6 +2680,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - CK_C_INITIALIZE_ARGS *pArg; - char fcnmap = 0; - CK_RV rc = CKR_OK; -+ CK_SLOT_ID slotID; -+ API_Slot_t *sltp; - - /* - * Lock so that only one thread can run C_Initialize or C_Finalize at -@@ -2674,6 +2714,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - // This must be done prior to all goto error calls, else bt_destroy() - // will fail because it accesses uninitialized memory when t->size > 0. - memset(Anchor, 0, sizeof(API_Proc_Struct_t)); -+ Anchor->socketfd = -1; - - TRACE_DEBUG("Anchor allocated at %s\n", (char *) Anchor); - -@@ -2789,11 +2830,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP); - -- if (!init_socket_data()) { -+ /* Connect to slot daemon and retrieve slot infos */ -+ Anchor->socketfd = connect_socket(SOCKET_FILE_PATH); -+ if (Anchor->socketfd < 0) { - OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a " - "socket. Verify that the slot management daemon is " - "running.\n"); -- TRACE_ERROR("Cannot attach to socket.\n"); -+ TRACE_ERROR("Failed to connect to slot daemon\n"); -+ rc = CKR_FUNCTION_FAILED; -+ goto error_shm; -+ } -+ -+ if (!init_socket_data(Anchor->socketfd)) { -+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to retrieve slot " -+ "infos from slot deamon.\n"); -+ TRACE_ERROR("Failed to receive slot infos from socket.\n"); - rc = CKR_FUNCTION_FAILED; - goto error_shm; - } -@@ -2810,15 +2861,35 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - } - // - // load all the slot DLL's here -- { -- CK_SLOT_ID slotID; -- API_Slot_t *sltp; -+ for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { -+ sltp = &(Anchor->SltList[slotID]); -+ slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); -+ } - -+ /* Start event receiver thread */ -+ if (start_event_thread() != 0) { -+ TRACE_ERROR("Failed to start event thread\n"); -+ -+ // unload all the STDLL's from the application -+ // This is in case the APP decides to do the re-initialize and -+ // continue on - for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { - sltp = &(Anchor->SltList[slotID]); -- slot_loaded[slotID] = DL_Load_and_Init(sltp, slotID); -+ if (slot_loaded[slotID]) { -+ if (sltp->pSTfini) { -+ // call the terminate function.. -+ sltp->pSTfini(sltp->TokData, slotID, -+ &Anchor->SocketDataP.slot_info[slotID], -+ &trace, 0); -+ } -+ } -+ DL_UnLoad(sltp, slotID); - } - -+ API_UnRegister(); -+ -+ rc = CKR_FUNCTION_FAILED; -+ goto error_shm; - } - - pthread_mutex_unlock(&GlobMutex); -@@ -2829,6 +2900,8 @@ error_shm: - - error: - bt_destroy(&Anchor->sess_btree); -+ if (Anchor->socketfd >= 0) -+ close(Anchor->socketfd); - - free((void *) Anchor); - Anchor = NULL; -@@ -5052,7 +5125,8 @@ void api_init(void) - { - // Should only have to do the atfork stuff at load time... - if (!Initialized) { -- pthread_atfork(NULL, NULL, (void (*)()) child_fork_initializer); -+ pthread_atfork(parent_fork_prepare, parent_fork_after, -+ child_fork_initializer); - Initialized = 1; - } - } -diff --git a/usr/lib/api/apiproto.h b/usr/lib/api/apiproto.h -index 871f3778..8523fb8e 100644 ---- a/usr/lib/api/apiproto.h -+++ b/usr/lib/api/apiproto.h -@@ -50,6 +50,9 @@ void CK_Info_From_Internal(CK_INFO_PTR dest, CK_INFO_PTR_64 src); - int sessions_exist(CK_SLOT_ID); - - void CloseAllSessions(CK_SLOT_ID slot_id, CK_BBOOL in_fork_initializer); --int init_socket_data(); -+int connect_socket(const char *file_path); -+int init_socket_data(int socketfd); -+int start_event_thread(); -+int stop_event_thread(); - - #endif -diff --git a/usr/lib/api/socket_client.c b/usr/lib/api/socket_client.c -index 6bacf151..e344ddbf 100644 ---- a/usr/lib/api/socket_client.c -+++ b/usr/lib/api/socket_client.c -@@ -23,114 +23,421 @@ - #include - #include - #include -+#include -+#include - - #include "apiproto.h" - #include "slotmgr.h" - #include "apictl.h" -+#include "trace.h" - #include "ock_syslog.h" -+#include "events.h" - - extern API_Proc_Struct_t *Anchor; --// --// Will fill out the Slot_Mgr_Socket_t structure in the Anchor global data --// structure with the values passed by the pkcsslotd via a socket RPC. --int init_socket_data() -+ -+int connect_socket(const char *file_path) - { - int socketfd; - struct sockaddr_un daemon_address; - struct stat file_info; - struct group *grp; -- int n; -- unsigned int bytes_received = 0; -- Slot_Mgr_Socket_t *daemon_socket_data = NULL; -- int ret = FALSE; - -- if (stat(SOCKET_FILE_PATH, &file_info)) { -+ if (stat(file_path, &file_info)) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to find socket file, errno=%d", -+ "connect_socket: failed to find socket file, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - grp = getgrnam("pkcs11"); - if (!grp) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: pkcs11 group does not exist, errno=%d", -+ "connect_socket: pkcs11 group does not exist, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - if (file_info.st_uid != 0 || file_info.st_gid != grp->gr_gid) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: incorrect permissions on socket file"); -- return FALSE; -+ "connect_socket: incorrect permissions on socket file"); -+ return -1; - } - - if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to create socket, errno=%d", -+ "connect_socket: failed to create socket, errno=%d", - errno); -- return FALSE; -+ return -1; - } - - memset(&daemon_address, 0, sizeof(struct sockaddr_un)); - daemon_address.sun_family = AF_UNIX; -- strcpy(daemon_address.sun_path, SOCKET_FILE_PATH); -+ strcpy(daemon_address.sun_path, file_path); - - if (connect(socketfd, (struct sockaddr *) &daemon_address, - sizeof(struct sockaddr_un)) != 0) { - OCK_SYSLOG(LOG_ERR, -- "init_socket_data: failed to connect to slotmanager daemon, " -+ "connect_socket: failed to connect to slotmanager daemon, " - "errno=%d", - errno); -- goto exit; -- } -- // allocate data buffer -- daemon_socket_data = -- (Slot_Mgr_Socket_t *) malloc(sizeof(*daemon_socket_data)); -- if (!daemon_socket_data) { -- OCK_SYSLOG(LOG_ERR, "init_socket_data: failed to \ -- allocate %lu bytes \ -- for daemon data, errno=%d", -- sizeof(*daemon_socket_data), errno); -- goto exit; -+ goto error; - } - -- while (bytes_received < sizeof(*daemon_socket_data)) { -- n = read(socketfd, ((char *) daemon_socket_data) + bytes_received, -- sizeof(*daemon_socket_data) - bytes_received); -+ return socketfd; -+ -+error: -+ close(socketfd); -+ return -1; -+} -+ -+static ssize_t read_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_received = 0; -+ ssize_t n; -+ -+ while (bytes_received < size) { -+ n = read(socketfd, buffer + bytes_received, size - bytes_received); - if (n < 0) { - // read error - if (errno == EINTR) - continue; -- OCK_SYSLOG(LOG_ERR, "init_socket_data: read error \ -- on daemon socket, errno=%d", errno); -- goto exit; -- } else if (n == 0) { -- // eof but we still expect some bytes -- OCK_SYSLOG(LOG_ERR, "init_socket_data: read returned \ -- with eof but we still \ -- expect %lu bytes from daemon", -- sizeof(*daemon_socket_data) - bytes_received); -- goto exit; -- } else { -- // n > 0, we got some bytes -- bytes_received += n; -+ return -errno; - } -+ if (n == 0) -+ break; -+ -+ bytes_received += n; - } - -- ret = TRUE; -+ return bytes_received; -+} -+ -+static ssize_t send_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_sent = 0; -+ ssize_t n; - -- // copy the Slot_Mgr_Socket_t struct into global -- // Anchor SocketDataPdata buffer -- memcpy(&(Anchor->SocketDataP), daemon_socket_data, -- sizeof(*daemon_socket_data)); -+ while (bytes_sent < size) { -+ n = send(socketfd, buffer + bytes_sent, size - bytes_sent, 0); -+ if (n < 0) { -+ // send error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; - --exit: -- //free the data buffer after copy -- if (daemon_socket_data) -- free(daemon_socket_data); -+ bytes_sent += n; -+ } - -- close(socketfd); -+ return bytes_sent; -+} -+ -+// -+// Will fill out the Slot_Mgr_Socket_t structure in the Anchor global data -+// structure with the values passed by the pkcsslotd via a socket RPC. -+int init_socket_data(int socketfd) -+{ -+ ssize_t n; -+ int ret = TRUE; -+ -+ n = read_all(socketfd, (char *)&Anchor->SocketDataP, -+ sizeof(Anchor->SocketDataP)); -+ if (n < 0) { -+ // read error -+ OCK_SYSLOG(LOG_ERR, "init_socket_data: read error \ -+ on daemon socket, errno=%d", -n); -+ ret = FALSE; -+ } -+ if (n != sizeof(Anchor->SocketDataP)) { -+ // eof but we still expect some bytes -+ OCK_SYSLOG(LOG_ERR, "init_socket_data: read returned \ -+ with eof but we still \ -+ expect %lu bytes from daemon", -+ sizeof(Anchor->SocketDataP) - n); -+ ret = FALSE; -+ } - - return ret; - } -+ -+static bool match_token_label_filter(event_msg_t *event, API_Slot_t *sltp) -+{ -+ if (event->token_label[0] == ' ' || event->token_label[0] == '\0') -+ return true; -+ -+ return memcmp(event->token_label, -+ sltp->TokData->nv_token_data->token_info.label, -+ sizeof(event->token_label)) == 0; -+} -+ -+struct type_model { -+ unsigned int type; -+ char model[member_size(CK_TOKEN_INFO_32, model)]; -+}; -+ -+static const struct type_model type_model_flt[] = { -+ { .type = EVENT_TOK_TYPE_CCA, .model = "CCA " }, -+ { .type = EVENT_TOK_TYPE_EP11, .model = "EP11 " }, -+}; -+ -+static bool match_token_type_filter(event_msg_t *event, API_Slot_t *sltp) -+{ -+ size_t i; -+ -+ if (event->token_type == EVENT_TOK_TYPE_ALL) -+ return true; -+ -+ for (i = 0; i < sizeof(type_model_flt) / sizeof(struct type_model); i++) { -+ if (memcmp(sltp->TokData->nv_token_data->token_info.model, -+ type_model_flt[i].model, -+ sizeof(type_model_flt[i].model)) == 0 && -+ (event->token_type & type_model_flt[i].type) != 0) -+ return true; -+ } -+ -+ return false; -+} -+ -+static int handle_event(API_Proc_Struct_t *anchor, event_msg_t *event, -+ char *payload, event_reply_t *reply) -+{ -+ CK_SLOT_ID slotID; -+ API_Slot_t *sltp; -+ CK_RV rc; -+ -+ /* If its not for our process, ignore it, don't increment reply counters */ -+ if (event->process_id != 0 && event->process_id != anchor->Pid) -+ return 0; -+ -+ for (slotID = 0; slotID < NUMBER_SLOTS_MANAGED; slotID++) { -+ sltp = &anchor->SltList[slotID]; -+ if (sltp->DLLoaded == FALSE || sltp->FcnList == NULL) -+ continue; -+ -+ if (!match_token_label_filter(event, sltp)) -+ continue; -+ if (!match_token_type_filter(event, sltp)) -+ continue; -+ -+ if (sltp->FcnList->ST_HandleEvent != NULL) -+ rc = sltp->FcnList->ST_HandleEvent(sltp->TokData, event->type, -+ event->flags, payload, -+ event->payload_len); -+ else -+ rc = CKR_FUNCTION_NOT_SUPPORTED; -+ -+ TRACE_DEVEL("Slot %lu ST_HandleEvent rc: 0x%lx\n", slotID, rc); -+ switch (rc) { -+ case CKR_OK: -+ reply->positive_replies++; -+ break; -+ case CKR_FUNCTION_NOT_SUPPORTED: -+ reply->nothandled_replies++; -+ break; -+ default: -+ reply->negative_replies++; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static void event_thread_cleanup(void *arg) -+{ -+ API_Proc_Struct_t *anchor = arg; -+ -+ UNUSED(anchor); -+ -+ TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); -+} -+ -+static void *event_thread(void *arg) -+{ -+ API_Proc_Struct_t *anchor = arg; -+ int oldstate, oldtype; -+ struct pollfd pollfd; -+ event_msg_t event; -+ char *payload; -+ event_reply_t reply; -+ ssize_t num; -+ int rc; -+ -+ UNUSED(arg); -+ -+ TRACE_DEVEL("Event thread %lu running\n", pthread_self()); -+ -+ if (anchor->socketfd < 0) { -+ TRACE_ERROR("socket is already closed.\n"); -+ TRACE_DEVEL("Event thread %lu terminating\n", pthread_self()); -+ return NULL; -+ } -+ -+ /* Enable cancellation */ -+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); -+ pthread_cleanup_push(event_thread_cleanup, anchor); -+ -+ pollfd.fd = anchor->socketfd; -+ pollfd.events = POLLIN | POLLHUP | POLLERR; -+ -+ while (1) { -+ pollfd.revents = 0; -+ rc = poll(&pollfd, 1, -1); -+ if (rc < 0) { -+ if (errno == EINTR) -+ continue; -+ TRACE_ERROR("poll failed: %d\n", errno); -+ break; -+ } -+ -+ if (rc == 0) -+ continue; -+ -+ if (pollfd.revents & (POLLHUP | POLLERR)) { -+ TRACE_ERROR("Error on socket, possibly closed by slot daemon\n"); -+ break; -+ } -+ if ((pollfd.revents & POLLIN) == 0) -+ continue; -+ -+ /* Disable for cancellation while we are working on an event */ -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); -+ -+ TRACE_DEVEL("Receive new event ....\n"); -+ -+ num = read_all(anchor->socketfd, (char *)&event, sizeof(event)); -+ if (num != sizeof(event)) { -+ TRACE_ERROR("Error receiving the event, rc: %ld\n", num); -+ break; -+ } -+ -+ TRACE_DEBUG("Event version: %u\n", event.version); -+ TRACE_DEBUG("Event type: 0x%08x\n", event.type); -+ TRACE_DEBUG("Event flags: 0x%08x\n", event.flags); -+ TRACE_DEBUG("Event token_type: 0x%08x\n", event.token_type); -+ TRACE_DEBUG("Event token_name: '%.32s'\n", event.token_label); -+ TRACE_DEBUG("Event process_id: %u\n", event.process_id); -+ TRACE_DEBUG("Event payload_len: %u\n", event.payload_len); -+ -+ if (event.version != EVENT_VERSION_1) { -+ TRACE_ERROR("Event version invalid: %u\n", event.version); -+ break; -+ } -+ -+ payload = NULL; -+ if (event.payload_len > 0) { -+ payload = malloc(event.payload_len); -+ if (payload == NULL) { -+ TRACE_ERROR("Failed to allocate buffer for event payload\n"); -+ break; -+ } -+ -+ num = read_all(anchor->socketfd, payload, event.payload_len); -+ if (num != event.payload_len) { -+ TRACE_ERROR("Error receiving the event payload, rc: %ld\n", num); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ -+ TRACE_DEBUG("Event payload:\n"); -+ TRACE_DEBUG_DUMP(" ", payload, event.payload_len); -+ } -+ -+ memset(&reply, 0, sizeof(reply)); -+ reply.version = EVENT_VERSION_1; -+ rc = handle_event(anchor, &event, payload, &reply); -+ if (rc != 0) { -+ TRACE_ERROR("Error handling the event, rc: %d\n", rc); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ -+ TRACE_DEBUG("Reply version: %u\n", reply.version); -+ TRACE_DEBUG("Reply positive: %u\n", reply.positive_replies); -+ TRACE_DEBUG("Reply negative: %u\n", reply.negative_replies); -+ TRACE_DEBUG("Reply not-handled: %u\n", reply.nothandled_replies); -+ -+ if (event.flags & EVENT_FLAGS_REPLY_REQ) { -+ num = send_all(anchor->socketfd, (char *)&reply, sizeof(reply)); -+ if (num != sizeof(reply)) { -+ TRACE_ERROR("Error sending the event reply, rc: %ld\n", num); -+ if (payload != NULL) -+ free(payload); -+ break; -+ } -+ } -+ -+ if (payload != NULL) -+ free(payload); -+ -+ /* Re-enable for and test if we got canceled in the meantime */ -+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); -+ pthread_testcancel(); -+ } -+ -+ /* -+ * Close the socket if we encounter an unrecoverable error (e.g. received -+ * invalid event) and stop the thread because of that. -+ * If the thread is stopped via stop_event_thread(), then it gets canceled -+ * via pthread_cancel(), and will not reach this place, thus the socket is -+ * not closed. This is intended, and the socket will then be closed by -+ * C_Finalize(). The atfork 'prepare' handler in the parent process also -+ * stops the thread (via stop_event_thread()), and the socket must not be -+ * closed in this case, because the thread is restarted in the atfork -+ * 'parent' handler, and should continue to receive events from the -+ * socket. -+ */ -+ close(anchor->socketfd); -+ anchor->socketfd = -1; -+ -+ pthread_cleanup_pop(1); -+ return NULL; -+} -+ -+int start_event_thread() -+{ -+ int rc; -+ -+ rc = pthread_create(&Anchor->event_thread, NULL, event_thread, Anchor); -+ if (rc != 0) { -+ OCK_SYSLOG(LOG_ERR, "start_event_thread: pthread_create failed, " -+ "errno=%d", rc); -+ TRACE_ERROR("Failed to start event thread, errno=%d\n", rc); -+ return rc; -+ } -+ -+ TRACE_DEVEL("Event thread %lu has been started\n", Anchor->event_thread); -+ return 0; -+} -+ -+int stop_event_thread() -+{ -+ int rc; -+ void *status; -+ -+ TRACE_DEVEL("Canceling event thread %lu\n", Anchor->event_thread); -+ rc = pthread_cancel(Anchor->event_thread); -+ if (rc != 0 && rc != ESRCH) -+ return rc; -+ -+ TRACE_DEVEL("Waiting for event thread %lu to terminate\n", -+ Anchor->event_thread); -+ rc = pthread_join(Anchor->event_thread, &status); -+ if (rc != 0) -+ return rc; -+ -+ if (status != PTHREAD_CANCELED) { -+ TRACE_ERROR("Event thread was stopped, but did not return the " -+ "expected status\n"); -+ } -+ -+ TRACE_DEVEL("Event thread %lu has terminated\n", Anchor->event_thread); -+ -+ Anchor->event_thread = 0; -+ return 0; -+} -diff --git a/usr/lib/cca_stdll/tok_struct.h b/usr/lib/cca_stdll/tok_struct.h -index 2b43fa8e..182e2ac2 100644 ---- a/usr/lib/cca_stdll/tok_struct.h -+++ b/usr/lib/cca_stdll/tok_struct.h -@@ -134,6 +134,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c -index aae00984..a3749d26 100644 ---- a/usr/lib/common/new_host.c -+++ b/usr/lib/common/new_host.c -@@ -4039,6 +4039,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -4104,4 +4122,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/common/tok_spec_struct.h b/usr/lib/common/tok_spec_struct.h -index 30ffcf02..0e90d411 100644 ---- a/usr/lib/common/tok_spec_struct.h -+++ b/usr/lib/common/tok_spec_struct.h -@@ -278,6 +278,10 @@ struct token_specific_struct { - - CK_RV(*t_set_attrs_for_new_object) (STDLL_TokData_t *, CK_OBJECT_CLASS, - CK_ULONG, TEMPLATE *); -+ -+ CK_RV(*t_handle_event) (STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len); - }; - - typedef struct token_specific_struct token_spec_t; -diff --git a/usr/lib/common/tok_specific.h b/usr/lib/common/tok_specific.h -index ffb72909..997fa7e1 100644 ---- a/usr/lib/common/tok_specific.h -+++ b/usr/lib/common/tok_specific.h -@@ -326,4 +326,10 @@ CK_RV token_specific_set_attrs_for_new_object(STDLL_TokData_t *, - CK_OBJECT_CLASS, CK_ULONG, - TEMPLATE *); - -+CK_RV token_specific_handle_event(STDLL_TokData_t *tokdata, -+ unsigned int event_type, -+ unsigned int event_flags, -+ const char *payload, -+ unsigned int payload_len); -+ - #endif -diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c -index 6fcef68a..4e592363 100644 ---- a/usr/lib/ep11_stdll/new_host.c -+++ b/usr/lib/ep11_stdll/new_host.c -@@ -4262,6 +4262,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -4327,4 +4345,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h -index 51aae6fb..2c0af9cf 100644 ---- a/usr/lib/ep11_stdll/tok_struct.h -+++ b/usr/lib/ep11_stdll/tok_struct.h -@@ -137,6 +137,7 @@ token_spec_t token_specific = { - &token_specific_reencrypt_single, - &token_specific_set_attribute_values, - &token_specific_set_attrs_for_new_object, -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/ica_s390_stdll/tok_struct.h b/usr/lib/ica_s390_stdll/tok_struct.h -index 13ee72c9..a260a276 100644 ---- a/usr/lib/ica_s390_stdll/tok_struct.h -+++ b/usr/lib/ica_s390_stdll/tok_struct.h -@@ -147,6 +147,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c -index 0f93ce5c..cfef7425 100644 ---- a/usr/lib/icsf_stdll/new_host.c -+++ b/usr/lib/icsf_stdll/new_host.c -@@ -3332,6 +3332,24 @@ done: - return rc; - } - -+CK_RV SC_HandleEvent(STDLL_TokData_t *tokdata, unsigned int event_type, -+ unsigned int event_flags, const char *payload, -+ unsigned int payload_len) -+{ -+ CK_RV rc; -+ -+ if (token_specific.t_handle_event == NULL) -+ return CKR_FUNCTION_NOT_SUPPORTED; -+ -+ rc = token_specific.t_handle_event(tokdata, event_type, event_flags, -+ payload, payload_len); -+ -+ TRACE_INFO("SC_HandleEvent: rc = 0x%08lx, event_type = 0x%08x, " -+ "event_flags = 0x%08x\n", rc, event_type, event_flags); -+ -+ return rc; -+} -+ - void SC_SetFunctionList(void) - { - function_list.ST_Initialize = ST_Initialize; -@@ -3397,4 +3415,6 @@ void SC_SetFunctionList(void) - function_list.ST_CancelFunction = NULL; // SC_CancelFunction; - - function_list.ST_IBM_ReencryptSingle = SC_IBM_ReencryptSingle; -+ -+ function_list.ST_HandleEvent = SC_HandleEvent; - } -diff --git a/usr/lib/icsf_stdll/tok_struct.h b/usr/lib/icsf_stdll/tok_struct.h -index fb1619ee..0f930a29 100644 ---- a/usr/lib/icsf_stdll/tok_struct.h -+++ b/usr/lib/icsf_stdll/tok_struct.h -@@ -129,6 +129,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/soft_stdll/tok_struct.h b/usr/lib/soft_stdll/tok_struct.h -index acf7c5d7..e43df038 100644 ---- a/usr/lib/soft_stdll/tok_struct.h -+++ b/usr/lib/soft_stdll/tok_struct.h -@@ -172,6 +172,7 @@ token_spec_t token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; - - #endif -diff --git a/usr/lib/tpm_stdll/tok_struct.h b/usr/lib/tpm_stdll/tok_struct.h -index d48b93e5..8903f123 100644 ---- a/usr/lib/tpm_stdll/tok_struct.h -+++ b/usr/lib/tpm_stdll/tok_struct.h -@@ -120,4 +120,5 @@ struct token_specific_struct token_specific = { - NULL, // reencrypt_single - NULL, // set_attribute_values - NULL, // set_attrs_for_new_object -+ NULL, // handle_event - }; diff --git a/SOURCES/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch b/SOURCES/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch deleted file mode 100644 index 6936783..0000000 --- a/SOURCES/opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit b07505993dd8b2f367cf3b630f6da186e4e8550d -Author: Ingo Franzki -Date: Wed Feb 10 15:12:25 2021 +0100 - - Avoid deadlock in dlclose() after a fork - - Calling dlclose() in a atfork handler may cause a deadlock. - dlclose() may itself modify the atfork handler table to remove - any fork handlers that the to be unloaded library has registered. - Since the atfork handler table is currently locked when we are in - an atfork handler, this would produce a deadlock. - - Skip the dlclose() if we are in an atfork handler to avoid the deadlock. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index 3ccb6d41..f1ee9132 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -1516,7 +1516,15 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) - } - } - -- DL_UnLoad(sltp, slotID); -+ /* -+ * Calling dlclose() in a atfork handler may cause a deadlock. -+ * dlclose() may itself modify the atfork handler table to remove -+ * any fork handlers that the to be unloaded library has registered. -+ * Since the atfork handler table is currently locked when we are in -+ * an atfork handler, this would produce a deadlock. -+ */ -+ if (!in_child_fork_initializer) -+ DL_UnLoad(sltp, slotID); - } - - // Un register from Slot D diff --git a/SOURCES/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch b/SOURCES/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch deleted file mode 100644 index f5a7617..0000000 --- a/SOURCES/opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch +++ /dev/null @@ -1,21 +0,0 @@ -commit bf812c652c49d7e248b115d121a4f7f6568941a2 -Author: Ingo Franzki -Date: Tue Apr 6 13:41:55 2021 +0200 - - Update travis yaml file to install libudev development files - - Signed-off-by: Ingo Franzki - -diff --git a/.travis.yml b/.travis.yml -index d2907246..fd4092e3 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -5,7 +5,7 @@ language: c - - before_install: - - sudo apt-get -qq update -- - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget -+ - sudo apt-get install -y expect trousers libldap2-dev libtspi-dev wget libudev-dev - - sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica3_3.4.0-0ubuntu1_s390x.deb - - sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/libica-dev_3.4.0-0ubuntu1_s390x.deb - - sudo dpkg -i libica3_3.4.0-0ubuntu1_s390x.deb || true # icatok needs libica >= 3.3 diff --git a/SOURCES/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch b/SOURCES/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch deleted file mode 100644 index d515e15..0000000 --- a/SOURCES/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch +++ /dev/null @@ -1,462 +0,0 @@ -commit c79e899d77a5724635a9d4451a34a240e2c7e891 -Author: Ingo Franzki -Date: Fri Apr 16 13:41:41 2021 +0200 - - Fix potential deadlock situation with double read-locks - - Do not get and read-lock an object twice within the same thread via - function object_mgr_find_in_map1(), as this would read-lock the object - twice. - - This could cause a deadlock situation, when in-between the first - and the second call to object_mgr_find_in_map1() the token object is - modified by another process. The second object_mgr_find_in_map1() would - detect that the object has been modified (object_mgr_check_shm()), and - would try to re-load the object from the disk. For re-loading, the - object is unlocked once, and a write-lock is acquired instead. - However, if the current thread has read-locked the object twice, but - releases only one read-lock, then it will never get the write lock, - because it still owns the read lock itself. - - To avoid this situation, release the read-lock before calling another - function that also acquires the read lock of the object. That way, only - one read-lock is held by the current thread, and re-loading the object - will not cause a deadlock. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/decr_mgr.c b/usr/lib/common/decr_mgr.c -index 317ef995..9842302b 100644 ---- a/usr/lib/common/decr_mgr.c -+++ b/usr/lib/common/decr_mgr.c -@@ -540,6 +540,10 @@ CK_RV decr_mgr_init(STDLL_TokData_t *tokdata, - } - memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT)); - -+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 0); - if (rc) { - TRACE_ERROR("Could not initialize AES_GCM parms.\n"); -diff --git a/usr/lib/common/encr_mgr.c b/usr/lib/common/encr_mgr.c -index d3ecdeee..3e85ceab 100644 ---- a/usr/lib/common/encr_mgr.c -+++ b/usr/lib/common/encr_mgr.c -@@ -537,6 +537,10 @@ CK_RV encr_mgr_init(STDLL_TokData_t *tokdata, - } - memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT)); - -+ /* Release obj lock, token specific aes-gcm may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 1); - if (rc != CKR_OK) { - TRACE_ERROR("Could not initialize AES_GCM parms.\n"); -diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c -index 1652f90a..e35b383c 100644 ---- a/usr/lib/common/mech_rsa.c -+++ b/usr/lib/common/mech_rsa.c -@@ -602,6 +602,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_oaep_encrypt(tokdata, ctx, in_data, - in_data_len, out_data, - out_data_len, hash, hlen); -@@ -625,6 +629,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa-oaep may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_oaep_decrypt(tokdata, ctx, in_data, - in_data_len, out_data, - out_data_len, hash, hlen); -@@ -1331,6 +1339,10 @@ CK_RV rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_pss_sign(tokdata, sess, ctx, in_data, in_data_len, - out_data, out_data_len); - if (rc != CKR_OK) -@@ -1389,6 +1401,10 @@ CK_RV rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess, - goto done; - } - -+ /* Release obj lock, token specific rsa_pss may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = token_specific.t_rsa_pss_verify(tokdata, sess, ctx, in_data, - in_data_len, signature, sig_len); - if (rc != CKR_OK) -diff --git a/usr/lib/common/sign_mgr.c b/usr/lib/common/sign_mgr.c -index 937a371a..c7268e01 100644 ---- a/usr/lib/common/sign_mgr.c -+++ b/usr/lib/common/sign_mgr.c -@@ -424,6 +424,10 @@ CK_RV sign_mgr_init(STDLL_TokData_t *tokdata, - ctx->context_len = 0; - ctx->context = NULL; - -+ /* Release obj lock, token specific hmac-sign may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = hmac_sign_init(tokdata, sess, mech, key); - if (rc != CKR_OK) { - TRACE_ERROR("Failed to initialize hmac.\n"); -diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c -index 3ac3768a..52f95d7a 100644 ---- a/usr/lib/ep11_stdll/ep11_specific.c -+++ b/usr/lib/ep11_stdll/ep11_specific.c -@@ -6948,6 +6948,13 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* -+ * Release obj lock, sign_mgr_init or ep11tok_sign_verify_init_ibm_ed -+ * may re-acquire the lock -+ */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - /* Note that Edwards curves in general are not yet supported in - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ -@@ -7029,11 +7036,16 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session, - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ - if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 || -- ctx->mech.mechanism == CKM_IBM_ED448_SHA3) -+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) { - rc = pkey_ibm_ed_sign(key_obj, in_data, in_data_len, signature, sig_len); -- else -+ } else { -+ /* Release obj lock, sign_mgr_sign may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = sign_mgr_sign(tokdata, session, length_only, ctx, in_data, - in_data_len, signature, sig_len); -+ } - goto done; /* no ep11 fallback possible */ - } - -@@ -7071,6 +7083,11 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - if (!in_data || !in_data_len) - return CKR_OK; - -+ if (ctx->pkey_active) { -+ rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7078,11 +7095,6 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data, - in_data_len, ep11_data->target); -@@ -7115,6 +7127,11 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7122,11 +7139,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len, - ep11_data->target); -@@ -7241,6 +7253,13 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* -+ * Release obj lock, verify_mgr_init or ep11tok_sign_verify_init_ibm_ed -+ * may re-acquire the lock -+ */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - /* Note that Edwards curves in general are not yet supported in - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ -@@ -7320,12 +7339,17 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session, - * opencryptoki. These two special IBM specific ED mechs are only - * supported by the ep11token, so let's keep them local here. */ - if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 || -- ctx->mech.mechanism == CKM_IBM_ED448_SHA3) -+ ctx->mech.mechanism == CKM_IBM_ED448_SHA3) { - rc = pkey_ibm_ed_verify(key_obj, in_data, in_data_len, - signature, sig_len); -- else -+ } else { -+ /* Release obj lock, verify_mgr_verify may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - rc = verify_mgr_verify(tokdata, session, ctx, in_data, - in_data_len, signature, sig_len); -+ } - goto done; /* no ep11 fallback possible */ - } - -@@ -7363,6 +7387,11 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - if (!in_data || !in_data_len) - return CKR_OK; - -+ if (ctx->pkey_active) { -+ rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7370,11 +7399,6 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data, - in_data_len, ep11_data->target); -@@ -7406,6 +7430,11 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7413,11 +7442,6 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature, - sig_len, ep11_data->target); -@@ -7501,6 +7525,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = decr_mgr_decrypt_final(tokdata, session, length_only, -+ ctx, output_part, p_output_part_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7508,12 +7538,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = decr_mgr_decrypt_final(tokdata, session, length_only, -- ctx, output_part, p_output_part_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_DecryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -@@ -7548,13 +7572,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = decr_mgr_decrypt(tokdata, session, length_only, ctx, - input_data, input_data_len, output_data, -@@ -7562,6 +7579,13 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -@@ -7602,13 +7626,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return CKR_OK; /* nothing to update, keep context */ - } - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = decr_mgr_decrypt_update(tokdata, session, length_only, - ctx, input_part, input_part_len, -@@ -7616,6 +7633,13 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -@@ -7695,6 +7719,12 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -+ if (ctx->pkey_active) { -+ rc = encr_mgr_encrypt_final(tokdata, session, length_only, -+ ctx, output_part, p_output_part_len); -+ goto done; /* no ep11 fallback possible */ -+ } -+ - rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, - READ_LOCK); - if (rc != CKR_OK) { -@@ -7702,12 +7732,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session, - return rc; - } - -- if (ctx->pkey_active) { -- rc = encr_mgr_encrypt_final(tokdata, session, length_only, -- ctx, output_part, p_output_part_len); -- goto done; /* no ep11 fallback possible */ -- } -- - RETRY_START - rc = dll_m_EncryptFinal(ctx->context, ctx->context_len, - output_part, p_output_part_len, -@@ -7742,13 +7766,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - CK_BYTE *keyblob; - OBJECT *key_obj = NULL; - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = encr_mgr_encrypt(tokdata, session, length_only, ctx, - input_data, input_data_len, output_data, -@@ -7756,6 +7773,13 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data, - input_data_len, output_data, p_output_data_len, -@@ -7796,13 +7820,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - return CKR_OK; /* nothing to update, keep context */ - } - -- rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -- READ_LOCK); -- if (rc != CKR_OK) { -- TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -- return rc; -- } -- - if (ctx->pkey_active) { - rc = encr_mgr_encrypt_update(tokdata, session, length_only, ctx, - input_part, input_part_len, output_part, -@@ -7810,6 +7827,13 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session, - goto done; /* no ep11 fallback possible */ - } - -+ rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj, -+ READ_LOCK); -+ if (rc != CKR_OK) { -+ TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc); -+ return rc; -+ } -+ - RETRY_START - rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len, - input_part, input_part_len, output_part, -@@ -7921,6 +7945,10 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session, - rc = ep11tok_pkey_check(tokdata, session, key_obj, mech); - switch (rc) { - case CKR_OK: -+ /* Release obj lock, encr/decr_mgr_init may re-acquire the lock */ -+ object_put(tokdata, key_obj, TRUE); -+ key_obj = NULL; -+ - if (op == DECRYPT) { - rc = decr_mgr_init(tokdata, session, &session->decr_ctx, - OP_DECRYPT_INIT, mech, key); diff --git a/SOURCES/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch b/SOURCES/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch deleted file mode 100644 index 8f1477c..0000000 --- a/SOURCES/opencryptoki-3.16.0-d2f137cce5e6efb123842509352c7c49f889c67f.patch +++ /dev/null @@ -1,104 +0,0 @@ -commit d2f137cce5e6efb123842509352c7c49f889c67f -Author: Ingo Franzki -Date: Thu Jul 22 15:55:02 2021 +0200 - - pkcstok_migrate: Rework string quoting for opencryptoki.conf migration - - Due to the way the parser works, a slot description like - 'description = "slot"' works, but not without quotes ('description = slot'). - The word 'slot' is treated as a keyword if not quoted (besides other keywords, - too), so if the word 'slot' would appear in an unquoted string, the - configuration file would fail to parse. - - Always quote the value of 'description' and 'manufacturer'. Quote the - value of 'stdll', 'confname', and 'tokname' if it contains spaces, and - never quote the value of 'hwversion', 'firmwareversion', and 'tokversion'. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index a29dc8f7..853986e8 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2060,7 +2060,7 @@ done: - */ - static int parseupdate_ockversion(void *private, const char *version) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fprintf(u->f, "version %s", version); - return 0; -@@ -2075,14 +2075,14 @@ static void parseupdate_disab_event_supp(void *private) - - static void parseupdate_eol(void *private) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fputc('\n', u->f); - } - - static int parseupdate_begin_slot(void *private, int slot, int nl_before_begin) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - u->activeslot = (slot == u->slotnum); - if (nl_before_begin) -@@ -2094,7 +2094,7 @@ static int parseupdate_begin_slot(void *private, int slot, int nl_before_begin) - - static int parseupdate_end_slot(void *private) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - if (u->activeslot) - fprintf(u->f, " tokversion = 3.12\n"); -@@ -2105,19 +2105,32 @@ static int parseupdate_end_slot(void *private) - - static int parseupdate_key_str(void *private, int tok, const char *val) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_HWVERSION && tok != KW_FWVERSION && -- strchr(val, ' ') != NULL) -+ switch (tok) { -+ case KW_SLOTDESC: -+ case KW_MANUFID: - fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -- else if (tok != KW_TOKVERSION) -+ break; -+ case KW_STDLL: -+ case KW_CONFNAME: -+ case KW_TOKNAME: -+ if (strchr(val, ' ') != NULL) -+ fprintf(u->f, " %s = \"%s\"", keyword_token_to_str(tok), val); -+ else -+ fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); -+ break; -+ case KW_HWVERSION: -+ case KW_FWVERSION: - fprintf(u->f, " %s = %s", keyword_token_to_str(tok), val); -+ break; -+ } - return 0; - } - - static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - if (tok == KW_TOKVERSION && !u->activeslot) - fprintf(u->f, " %s = %d.%d", keyword_token_to_str(tok), -@@ -2127,7 +2140,7 @@ static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - - static void parseupdate_eolcomment(void *private, const char *comment) - { -- struct parseupdate *u = (struct parseupdate *)private; -+ struct parseupdate *u = (struct parseupdate *)private; - - fprintf(u->f, "#%s", comment); - } diff --git a/SOURCES/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch b/SOURCES/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch deleted file mode 100644 index 40a4962..0000000 --- a/SOURCES/opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch +++ /dev/null @@ -1,239 +0,0 @@ -commit d7de5092247a0efc2c397f12977a7c9925420143 -Author: Ingo Franzki -Date: Tue Feb 16 17:15:20 2021 +0100 - - TESTCASES: Add event support tests - - Signed-off-by: Ingo Franzki - -diff --git a/testcases/misc_tests/events.c b/testcases/misc_tests/events.c -new file mode 100644 -index 00000000..fecc7bfe ---- /dev/null -+++ b/testcases/misc_tests/events.c -@@ -0,0 +1,190 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include "event_client.h" -+#include "regress.h" -+#include "defs.h" -+ -+const char payload[20] = "12345678901234567890"; -+ -+static inline void init_event_destination(struct event_destination *dest, -+ unsigned int token_type, -+ const char *label, -+ pid_t process_id) -+{ -+ size_t len; -+ -+ dest->token_type = token_type; -+ dest->process_id = process_id; -+ -+ memset(dest->token_label, ' ', sizeof(dest->token_label)); -+ if (label != NULL) { -+ len = strlen(label); -+ memcpy(dest->token_label, label, len > sizeof(dest->token_label) ? -+ sizeof(dest->token_label) : len); -+ } -+} -+ -+int main(int argc, char **argv) -+{ -+ CK_C_INITIALIZE_ARGS cinit_args; -+ int rc, fd = -1, ret = 1; -+ struct event_destination dest; -+ struct event_reply reply; -+ -+ UNUSED(argc); -+ UNUSED(argv); -+ -+ rc = do_GetFunctionList(); -+ if (!rc) { -+ testcase_error("do_getFunctionList(), rc=%s", p11_get_ckr(rc)); -+ return rc; -+ } -+ -+ /* -+ * Initialize Opencryptoki in this process, so that at least one -+ * process is receiving the events. -+ */ -+ memset(&cinit_args, 0x0, sizeof(cinit_args)); -+ cinit_args.flags = CKF_OS_LOCKING_OK; -+ funcs->C_Initialize(&cinit_args); -+ -+ testcase_setup(0); -+ testcase_begin("Starting event tests"); -+ -+ // Test fork before C_Initialize -+ testcase_new_assertion(); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (simple, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (simple, one-shot)"); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload, -+ NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (payload, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (payload, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_CCA, NULL, 0); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (token-type, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (token-type, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, "cca", 0); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (token-label, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (token-label, one-shot)"); -+ -+ init_event_destination(&dest, EVENT_TOK_TYPE_ALL, NULL, 12345); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_NONE, 0, NULL, &dest, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (pid, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (pid, one-shot)"); -+ -+ memset(&reply, 0, sizeof(reply)); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply); -+ if (rc != 0) { -+ testcase_fail("send_event (reply, one-shot) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ printf("Reply: positive_replies: %lu\n", reply.positive_replies); -+ printf(" negative_replies: %lu\n", reply.negative_replies); -+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies); -+ if (reply.positive_replies + reply.negative_replies + -+ reply.nothandled_replies == 0) { -+ testcase_fail("send_event (reply, one-shot) replies all zero"); -+ goto out; -+ } -+ testcase_pass("send_event (reply, one-shot)"); -+ -+ -+ fd = init_event_client(); -+ if (fd < 0) { -+ testcase_fail("init_event_client rc = %d (%s)", fd, strerror(-fd)); -+ goto out; -+ } -+ testcase_pass("init_event_client()"); -+ -+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, 0, NULL, NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (simple) rc = %d (%s)", rc, strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (simple)"); -+ -+ rc = send_event(fd, 0x12345, EVENT_FLAGS_NONE, sizeof(payload), payload, -+ NULL, NULL); -+ if (rc != 0) { -+ testcase_fail("send_event (payload) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ testcase_pass("send_event (payload)"); -+ -+ memset(&reply, 0, sizeof(reply)); -+ -+ rc = send_event(-1, 0x12345, EVENT_FLAGS_REPLY_REQ, 0, NULL, NULL, &reply); -+ if (rc != 0) { -+ testcase_fail("send_event (reply) rc = %d (%s)", rc, -+ strerror(-rc)); -+ goto out; -+ } -+ printf("Reply: positive_replies: %lu\n", reply.positive_replies); -+ printf(" negative_replies: %lu\n", reply.negative_replies); -+ printf(" nothandled_replies: %lu\n", reply.nothandled_replies); -+ if (reply.positive_replies + reply.negative_replies + -+ reply.nothandled_replies == 0) { -+ testcase_fail("send_event (reply) replies all zero"); -+ goto out; -+ } -+ testcase_pass("send_event (reply)"); -+ -+ term_event_client(fd); -+ fd = -1; -+ -+ ret = 0; -+ -+out: -+ if (fd >= 0) -+ term_event_client(fd); -+ -+ funcs->C_Finalize(NULL); -+ -+ testcase_print_result(); -+ return ret; -+} -diff --git a/testcases/misc_tests/misc_tests.mk b/testcases/misc_tests/misc_tests.mk -index 3de11ebe..fb7cc0a1 100644 ---- a/testcases/misc_tests/misc_tests.mk -+++ b/testcases/misc_tests/misc_tests.mk -@@ -7,7 +7,8 @@ noinst_PROGRAMS += \ - testcases/misc_tests/fork testcases/misc_tests/multi_instance \ - testcases/misc_tests/obj_lock testcases/misc_tests/tok2tok_transport \ - testcases/misc_tests/obj_lock testcases/misc_tests/reencrypt \ -- testcases/misc_tests/cca_export_import_test -+ testcases/misc_tests/cca_export_import_test \ -+ testcases/misc_tests/events - - testcases_misc_tests_obj_mgmt_tests_CFLAGS = ${testcases_inc} - testcases_misc_tests_obj_mgmt_tests_LDADD = \ -@@ -73,3 +74,8 @@ testcases_misc_tests_cca_export_import_test_LDADD = \ - testcases/common/libcommon.la - testcases_misc_tests_cca_export_import_test_SOURCES = \ - testcases/misc_tests/cca_export_import_test.c -+ -+testcases_misc_tests_events_CFLAGS = ${testcases_inc} -+testcases_misc_tests_events_LDADD = testcases/common/libcommon.la -+testcases_misc_tests_events_SOURCES = testcases/misc_tests/events.c \ -+ usr/lib/common/event_client.c -diff --git a/testcases/ock_tests.sh.in b/testcases/ock_tests.sh.in -index 64c77a7d..6558b031 100755 ---- a/testcases/ock_tests.sh.in -+++ b/testcases/ock_tests.sh.in -@@ -53,6 +53,7 @@ OCK_TESTS+=" pkcs11/findobjects pkcs11/generate_keypair" - OCK_TESTS+=" pkcs11/get_interface pkcs11/getobjectsize pkcs11/sess_opstate" - OCK_TESTS+=" misc_tests/fork misc_tests/obj_mgmt_tests" - OCK_TESTS+=" misc_tests/obj_mgmt_lock_tests misc_tests/reencrypt" -+OCK_TESTS+=" misc_tests/events" - OCK_TEST="" - OCK_BENCHS="pkcs11/*bench" - diff --git a/SOURCES/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch b/SOURCES/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch deleted file mode 100644 index 5e9a346..0000000 --- a/SOURCES/opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch +++ /dev/null @@ -1,619 +0,0 @@ -commit d929fe8470e99f4dcbbd889e7aa87e147d0d5b48 -Author: Ingo Franzki -Date: Fri Feb 12 11:25:21 2021 +0100 - - Externalize linked list functions - - Externalize the linked list functions (dlist_xxx), so that they - can also be used on pkcsslotd. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/cca_stdll/cca_stdll.mk b/usr/lib/cca_stdll/cca_stdll.mk -index bd230b9f..c5e86fa7 100644 ---- a/usr/lib/cca_stdll/cca_stdll.mk -+++ b/usr/lib/cca_stdll/cca_stdll.mk -@@ -35,7 +35,8 @@ opencryptoki_stdll_libpkcs11_cca_la_SOURCES = \ - usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \ - usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ -- usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c -+ usr/lib/cca_stdll/cca_specific.c usr/lib/common/attributes.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_cca_la_SOURCES += \ -diff --git a/usr/lib/common/dlist.c b/usr/lib/common/dlist.c -new file mode 100644 -index 00000000..1fee1ea9 ---- /dev/null -+++ b/usr/lib/common/dlist.c -@@ -0,0 +1,218 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dlist.h" -+#include "host_defs.h" -+#include "h_extern.h" -+ -+ -+// Function: dlist_add_as_first() -+// -+// Adds the specified node to the start of the list -+// -+// Returns: pointer to the start of the list -+// -+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = NULL; -+ -+ if (!data) -+ return list; -+ -+ node = (DL_NODE *) malloc(sizeof(DL_NODE)); -+ if (!node) -+ return NULL; -+ -+ node->data = data; -+ node->prev = NULL; -+ node->next = list; -+ if (list) -+ list->prev = node; -+ -+ return node; -+} -+ -+// Function: dlist_add_as_last() -+// -+// Adds the specified node to the end of the list -+// -+// Returns: pointer to the start of the list -+// -+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = NULL; -+ -+ if (!data) -+ return list; -+ -+ node = (DL_NODE *) malloc(sizeof(DL_NODE)); -+ if (!node) -+ return NULL; -+ -+ node->data = data; -+ node->next = NULL; -+ -+ if (!list) { -+ node->prev = NULL; -+ return node; -+ } else { -+ DL_NODE *temp = dlist_get_last(list); -+ temp->next = node; -+ node->prev = temp; -+ -+ return list; -+ } -+} -+ -+// Function: dlist_find() -+// -+DL_NODE *dlist_find(DL_NODE *list, void *data) -+{ -+ DL_NODE *node = list; -+ -+ while (node && node->data != data) -+ node = node->next; -+ -+ return node; -+} -+ -+// Function: dlist_get_first() -+// -+// Returns the last node in the list or NULL if list is empty -+// -+DL_NODE *dlist_get_first(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list) -+ return NULL; -+ -+ while (temp->prev != NULL) -+ temp = temp->prev; -+ -+ return temp; -+} -+ -+// Function: dlist_get_last() -+// -+// Returns the last node in the list or NULL if list is empty -+// -+DL_NODE *dlist_get_last(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list) -+ return NULL; -+ -+ while (temp->next != NULL) -+ temp = temp->next; -+ -+ return temp; -+} -+ -+// -+// -+CK_ULONG dlist_length(DL_NODE *list) -+{ -+ DL_NODE *temp = list; -+ CK_ULONG len = 0; -+ -+ while (temp) { -+ len++; -+ temp = temp->next; -+ } -+ -+ return len; -+} -+ -+// -+// -+DL_NODE *dlist_next(DL_NODE *node) -+{ -+ if (!node) -+ return NULL; -+ -+ return node->next; -+} -+ -+// -+// -+DL_NODE *dlist_prev(DL_NODE *node) -+{ -+ if (!node) -+ return NULL; -+ -+ return node->prev; -+} -+ -+// -+// -+void dlist_purge(DL_NODE *list) -+{ -+ DL_NODE *node; -+ -+ if (!list) -+ return; -+ -+ do { -+ node = list->next; -+ free(list); -+ list = node; -+ } while (list); -+} -+ -+// Function: dlist_remove_node() -+// -+// Attempts to remove the specified node from the list. The caller is -+// responsible for freeing the data associated with the node prior to -+// calling this routine -+// -+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node) -+{ -+ DL_NODE *temp = list; -+ -+ if (!list || !node) -+ return NULL; -+ -+ // special case: removing head of the list -+ // -+ if (list == node) { -+ temp = list->next; -+ if (temp) -+ temp->prev = NULL; -+ -+ free(list); -+ return temp; -+ } -+ // we have no guarantee that the node is in the list -+ // so search through the list to find it -+ // -+ while ((temp != NULL) && (temp->next != node)) -+ temp = temp->next; -+ -+ if (temp != NULL) { -+ DL_NODE *next = node->next; -+ -+ temp->next = next; -+ if (next) -+ next->prev = temp; -+ -+ free(node); -+ } -+ -+ return list; -+} -diff --git a/usr/lib/common/dlist.h b/usr/lib/common/dlist.h -new file mode 100644 -index 00000000..eda4af9c ---- /dev/null -+++ b/usr/lib/common/dlist.h -@@ -0,0 +1,32 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+ -+#ifndef _DLIST_H_ -+#define _DLIST_H_ -+ -+#include "pkcs11types.h" -+#include "defs.h" -+ -+// linked-list routines -+// -+DL_NODE *dlist_add_as_first(DL_NODE *list, void *data); -+DL_NODE *dlist_add_as_last(DL_NODE *list, void *data); -+DL_NODE *dlist_find(DL_NODE *list, void *data); -+DL_NODE *dlist_get_first(DL_NODE *list); -+DL_NODE *dlist_get_last(DL_NODE *list); -+CK_ULONG dlist_length(DL_NODE *list); -+DL_NODE *dlist_next(DL_NODE *list); -+DL_NODE *dlist_prev(DL_NODE *list); -+void dlist_purge(DL_NODE *list); -+DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node); -+ -+#endif -diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h -index 63aff79f..5e251d95 100644 ---- a/usr/lib/common/h_extern.h -+++ b/usr/lib/common/h_extern.h -@@ -24,6 +24,7 @@ - #define _H_EXTERN_H - - #include -+#include "dlist.h" - - // global variables - // -@@ -1759,19 +1760,6 @@ int ec_point_from_public_data(const CK_BYTE *data, CK_ULONG data_len, - CK_BBOOL *allocated, CK_BYTE **ec_point, - CK_ULONG *ec_point_len); - --// linked-list routines --// --DL_NODE *dlist_add_as_first(DL_NODE *list, void *data); --DL_NODE *dlist_add_as_last(DL_NODE *list, void *data); --DL_NODE *dlist_find(DL_NODE *list, void *data); --DL_NODE *dlist_get_first(DL_NODE *list); --DL_NODE *dlist_get_last(DL_NODE *list); --CK_ULONG dlist_length(DL_NODE *list); --DL_NODE *dlist_next(DL_NODE *list); --DL_NODE *dlist_prev(DL_NODE *list); --void dlist_purge(DL_NODE *list); --DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node); -- - CK_RV attach_shm(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id); - CK_RV detach_shm(STDLL_TokData_t *tokdata, CK_BBOOL ignore_ref_count); - -diff --git a/usr/lib/common/utility.c b/usr/lib/common/utility.c -index 38d8d959..b2c6ee50 100644 ---- a/usr/lib/common/utility.c -+++ b/usr/lib/common/utility.c -@@ -40,203 +40,6 @@ - #include - #include - --// Function: dlist_add_as_first() --// --// Adds the specified node to the start of the list --// --// Returns: pointer to the start of the list --// --DL_NODE *dlist_add_as_first(DL_NODE *list, void *data) --{ -- DL_NODE *node = NULL; -- -- if (!data) -- return list; -- -- node = (DL_NODE *) malloc(sizeof(DL_NODE)); -- if (!node) -- return NULL; -- -- node->data = data; -- node->prev = NULL; -- node->next = list; -- if (list) -- list->prev = node; -- -- return node; --} -- --// Function: dlist_add_as_last() --// --// Adds the specified node to the end of the list --// --// Returns: pointer to the start of the list --// --DL_NODE *dlist_add_as_last(DL_NODE *list, void *data) --{ -- DL_NODE *node = NULL; -- -- if (!data) -- return list; -- -- node = (DL_NODE *) malloc(sizeof(DL_NODE)); -- if (!node) -- return NULL; -- -- node->data = data; -- node->next = NULL; -- -- if (!list) { -- node->prev = NULL; -- return node; -- } else { -- DL_NODE *temp = dlist_get_last(list); -- temp->next = node; -- node->prev = temp; -- -- return list; -- } --} -- --// Function: dlist_find() --// --DL_NODE *dlist_find(DL_NODE *list, void *data) --{ -- DL_NODE *node = list; -- -- while (node && node->data != data) -- node = node->next; -- -- return node; --} -- --// Function: dlist_get_first() --// --// Returns the last node in the list or NULL if list is empty --// --DL_NODE *dlist_get_first(DL_NODE *list) --{ -- DL_NODE *temp = list; -- -- if (!list) -- return NULL; -- -- while (temp->prev != NULL) -- temp = temp->prev; -- -- return temp; --} -- --// Function: dlist_get_last() --// --// Returns the last node in the list or NULL if list is empty --// --DL_NODE *dlist_get_last(DL_NODE *list) --{ -- DL_NODE *temp = list; -- -- if (!list) -- return NULL; -- -- while (temp->next != NULL) -- temp = temp->next; -- -- return temp; --} -- --// --// --CK_ULONG dlist_length(DL_NODE *list) --{ -- DL_NODE *temp = list; -- CK_ULONG len = 0; -- -- while (temp) { -- len++; -- temp = temp->next; -- } -- -- return len; --} -- --// --// --DL_NODE *dlist_next(DL_NODE *node) --{ -- if (!node) -- return NULL; -- -- return node->next; --} -- --// --// --DL_NODE *dlist_prev(DL_NODE *node) --{ -- if (!node) -- return NULL; -- -- return node->prev; --} -- --// --// --void dlist_purge(DL_NODE *list) --{ -- DL_NODE *node; -- -- if (!list) -- return; -- -- do { -- node = list->next; -- free(list); -- list = node; -- } while (list); --} -- --// Function: dlist_remove_node() --// --// Attempts to remove the specified node from the list. The caller is --// responsible for freeing the data associated with the node prior to --// calling this routine --// --DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node) --{ -- DL_NODE *temp = list; -- -- if (!list || !node) -- return NULL; -- -- // special case: removing head of the list -- // -- if (list == node) { -- temp = list->next; -- if (temp) -- temp->prev = NULL; -- -- free(list); -- return temp; -- } -- // we have no guarantee that the node is in the list -- // so search through the list to find it -- // -- while ((temp != NULL) && (temp->next != node)) -- temp = temp->next; -- -- if (temp != NULL) { -- DL_NODE *next = node->next; -- -- temp->next = next; -- if (next) -- next->prev = temp; -- -- free(node); -- } -- -- return list; --} -- - CK_RV CreateXProcLock(char *tokname, STDLL_TokData_t *tokdata) - { - char lockfile[PATH_MAX]; -diff --git a/usr/lib/ep11_stdll/ep11_stdll.mk b/usr/lib/ep11_stdll/ep11_stdll.mk -index bc617124..b5574d9e 100644 ---- a/usr/lib/ep11_stdll/ep11_stdll.mk -+++ b/usr/lib/ep11_stdll/ep11_stdll.mk -@@ -36,7 +36,7 @@ opencryptoki_stdll_libpkcs11_ep11_la_SOURCES = \ - usr/lib/common/utility.c usr/lib/common/trace.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/attributes.c usr/lib/common/sw_crypt.c \ -- usr/lib/common/profile_obj.c \ -+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \ - usr/lib/common/pkey_utils.c \ - usr/lib/ep11_stdll/new_host.c usr/lib/ep11_stdll/ep11_specific.c - -diff --git a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -index d8448486..8f467e11 100644 ---- a/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -+++ b/usr/lib/ica_s390_stdll/ica_s390_stdll.mk -@@ -34,7 +34,7 @@ opencryptoki_stdll_libpkcs11_ica_la_SOURCES = \ - usr/lib/common/verify_mgr.c usr/lib/common/trace.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/profile_obj.c usr/lib/common/attributes.c \ -- usr/lib/ica_s390_stdll/ica_specific.c -+ usr/lib/ica_s390_stdll/ica_specific.c usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_ica_la_SOURCES += \ -diff --git a/usr/lib/icsf_stdll/icsf_stdll.mk b/usr/lib/icsf_stdll/icsf_stdll.mk -index 788478c2..21c64f9a 100644 ---- a/usr/lib/icsf_stdll/icsf_stdll.mk -+++ b/usr/lib/icsf_stdll/icsf_stdll.mk -@@ -43,7 +43,7 @@ opencryptoki_stdll_libpkcs11_icsf_la_SOURCES = \ - usr/lib/common/mech_ssl3.c usr/lib/common/verify_mgr.c \ - usr/lib/common/mech_list.c usr/lib/common/shared_memory.c \ - usr/lib/common/attributes.c usr/lib/icsf_stdll/new_host.c \ -- usr/lib/common/profile_obj.c \ -+ usr/lib/common/profile_obj.c usr/lib/common/dlist.c \ - usr/lib/icsf_stdll/pbkdf.c usr/lib/icsf_stdll/icsf_specific.c \ - usr/lib/icsf_stdll/icsf_config_parse.y \ - usr/lib/icsf_stdll/icsf_config_lexer.l \ -diff --git a/usr/lib/soft_stdll/soft_stdll.mk b/usr/lib/soft_stdll/soft_stdll.mk -index cea802b5..ac401539 100644 ---- a/usr/lib/soft_stdll/soft_stdll.mk -+++ b/usr/lib/soft_stdll/soft_stdll.mk -@@ -32,7 +32,8 @@ opencryptoki_stdll_libpkcs11_sw_la_SOURCES = \ - usr/lib/common/utility.c usr/lib/common/verify_mgr.c \ - usr/lib/common/trace.c usr/lib/common/mech_list.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ -- usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c -+ usr/lib/soft_stdll/soft_specific.c usr/lib/common/attributes.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_sw_la_SOURCES += \ -diff --git a/usr/lib/tpm_stdll/tpm_stdll.mk b/usr/lib/tpm_stdll/tpm_stdll.mk -index f199a103..0e0eb024 100644 ---- a/usr/lib/tpm_stdll/tpm_stdll.mk -+++ b/usr/lib/tpm_stdll/tpm_stdll.mk -@@ -34,7 +34,8 @@ opencryptoki_stdll_libpkcs11_tpm_la_SOURCES = \ - usr/lib/common/verify_mgr.c usr/lib/common/mech_list.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ - usr/lib/tpm_stdll/tpm_specific.c usr/lib/common/attributes.c \ -- usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c -+ usr/lib/tpm_stdll/tpm_openssl.c usr/lib/tpm_stdll/tpm_util.c \ -+ usr/lib/common/dlist.c - - if ENABLE_LOCKS - opencryptoki_stdll_libpkcs11_tpm_la_SOURCES += \ -diff --git a/usr/sbin/pkcscca/pkcscca.mk b/usr/sbin/pkcscca/pkcscca.mk -index a223265f..cc40f819 100644 ---- a/usr/sbin/pkcscca/pkcscca.mk -+++ b/usr/sbin/pkcscca/pkcscca.mk -@@ -36,7 +36,7 @@ usr_sbin_pkcscca_pkcscca_SOURCES = \ - usr/lib/common/p11util.c usr/lib/common/sw_crypt.c \ - usr/lib/common/shared_memory.c usr/lib/common/profile_obj.c \ - usr/lib/common/attributes.c usr/lib/common/mech_rng.c \ -- usr/lib/common/pkcs_utils.c \ -+ usr/lib/common/pkcs_utils.c usr/lib/common/dlist.c \ - usr/sbin/pkcscca/pkcscca.c - - -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.mk b/usr/sbin/pkcsslotd/pkcsslotd.mk -index 4f0e3c56..2d36b4a9 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.mk -+++ b/usr/sbin/pkcsslotd/pkcsslotd.mk -@@ -21,5 +21,6 @@ usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \ - usr/sbin/pkcsslotd/socket_server.c - - nodist_usr_sbin_pkcsslotd_pkcsslotd_SOURCES = \ -- usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c -+ usr/lib/common/parser.h usr/lib/common/parser.c usr/lib/common/lexer.c \ -+ usr/lib/common/dlist.c - usr/sbin/pkcsslotd/slotmgr.$(OBJEXT): usr/lib/common/parser.h diff --git a/SOURCES/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch b/SOURCES/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch deleted file mode 100644 index a3bf6ea..0000000 --- a/SOURCES/opencryptoki-3.16.0-e88a9de3128df1c4b89bd4c7312c15bb3eb34593.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit e88a9de3128df1c4b89bd4c7312c15bb3eb34593 -Author: Ingo Franzki -Date: Thu Jul 8 15:18:30 2021 +0200 - - pkcstok_migrate: Don't remove 'tokversion = x.y' during migration - - When migrating a slot the opencryptoki.conf file is modified. If it - contains slots that already contain the 'tokversion = x.y' keyword, - this is accidentally removed when migrating another slot. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 3df1596e..05081aff 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2119,7 +2119,7 @@ static int parseupdate_key_vers(void *private, int tok, unsigned int vers) - { - struct parseupdate *u = (struct parseupdate *)private; - -- if (tok != KW_TOKVERSION) -+ if (tok == KW_TOKVERSION && !u->activeslot) - fprintf(u->f, " %s = %d.%d", keyword_token_to_str(tok), - vers >> 16, vers & 0xffu); - return 0; diff --git a/SOURCES/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch b/SOURCES/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch deleted file mode 100644 index 8e81324..0000000 --- a/SOURCES/opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch +++ /dev/null @@ -1,310 +0,0 @@ -commit e9548127edae313da7840bcb87fd0afd04549c2e -Author: Ingo Franzki -Date: Mon Feb 8 15:26:23 2021 +0100 - - pkcsslotd: Refactoring in preparation for event support - - No functional change so far, just making things a bit bore clearer. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h -index 3950a9a3..4d038435 100644 ---- a/usr/include/slotmgr.h -+++ b/usr/include/slotmgr.h -@@ -30,7 +30,7 @@ - #define TOK_PATH SBIN_PATH "/pkcsslotd" - #define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock" - --#define SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" -+#define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" - - #define PID_FILE_PATH "/var/run/pkcsslotd.pid" - #define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf" -diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c -index b74b763f..2873a20a 100644 ---- a/usr/lib/api/api_interface.c -+++ b/usr/lib/api/api_interface.c -@@ -2831,7 +2831,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid) - TRACE_DEBUG("Shared memory %p \n", Anchor->SharedMemP); - - /* Connect to slot daemon and retrieve slot infos */ -- Anchor->socketfd = connect_socket(SOCKET_FILE_PATH); -+ Anchor->socketfd = connect_socket(PROC_SOCKET_FILE_PATH); - if (Anchor->socketfd < 0) { - OCK_SYSLOG(LOG_ERR, "C_Initialize: Module failed to create a " - "socket. Verify that the slot management daemon is " -diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h -index 813db9f4..69eb59f3 100644 ---- a/usr/sbin/pkcsslotd/pkcsslotd.h -+++ b/usr/sbin/pkcsslotd/pkcsslotd.h -@@ -61,7 +61,6 @@ extern key_t tok; - extern Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED]; - extern unsigned int NumberSlotsInDB; - --extern int socketfd; - extern Slot_Mgr_Socket_t socketData; - - -@@ -89,9 +88,9 @@ int XProcLock(void); - int XProcUnLock(void); - int CreateXProcLock(void); - --int CreateListenerSocket(void); --int InitSocketData(Slot_Mgr_Socket_t *sp); --int SocketConnectionHandler(int socketfd, int timeout_secs); --void DetachSocketListener(int socketfd); -+int init_socket_server(); -+int term_socket_server(); -+int init_socket_data(Slot_Mgr_Socket_t *sp); -+int socket_connection_handler(int timeout_secs); - - #endif /* _SLOTMGR_H */ -diff --git a/usr/sbin/pkcsslotd/signal.c b/usr/sbin/pkcsslotd/signal.c -index cf7b9087..49482a2f 100644 ---- a/usr/sbin/pkcsslotd/signal.c -+++ b/usr/sbin/pkcsslotd/signal.c -@@ -101,7 +101,7 @@ void slotdGenericSignalHandler(int Signal) - - InfoLog("Exiting on %s (%d; %#x)", SignalConst(Signal), Signal, Signal); - -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c -index ea5c86f5..94288f13 100644 ---- a/usr/sbin/pkcsslotd/slotmgr.c -+++ b/usr/sbin/pkcsslotd/slotmgr.c -@@ -37,7 +37,6 @@ unsigned int NumberSlotsInDB = 0; - - Slot_Info_t_64 *psinfo; - --int socketfd; - Slot_Mgr_Socket_t socketData; - - struct dircheckinfo_s { -@@ -569,15 +568,15 @@ int main(int argc, char *argv[], char *envp[]) - if (!XProcUnLock()) - return 4; - -- if ((socketfd = CreateListenerSocket()) < 0) { -+ if (!init_socket_server()) { - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); - return 5; - } - -- if (!InitSocketData(&socketData)) { -- DetachSocketListener(socketfd); -+ if (!init_socket_data(&socketData)) { -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -598,7 +597,7 @@ int main(int argc, char *argv[], char *envp[]) - if (Daemon) { - pid_t pid; - if ((pid = fork()) < 0) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -643,7 +642,7 @@ int main(int argc, char *argv[], char *envp[]) - * the daemonization process redefines our handler for (at least) SIGTERM - */ - if (!SetupSignalHandlers()) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -664,7 +663,7 @@ int main(int argc, char *argv[], char *envp[]) - printf("Start garbage \n"); - /* start garbage collection thread */ - if (!StartGCThread(shmp)) { -- DetachSocketListener(socketfd); -+ term_socket_server(); - DestroyMutexes(); - DetachFromSharedMemory(); - DestroySharedMemory(); -@@ -684,7 +683,7 @@ int main(int argc, char *argv[], char *envp[]) - #if !(THREADED) && !(NOGARBAGE) - CheckForGarbage(shmp); - #endif -- SocketConnectionHandler(socketfd, 10); -+ socket_connection_handler(10); - } - - /************************************************************* -diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c -index ae0eff92..1fae0b95 100644 ---- a/usr/sbin/pkcsslotd/socket_server.c -+++ b/usr/sbin/pkcsslotd/socket_server.c -@@ -25,10 +25,14 @@ - #include "pkcsslotd.h" - #include "apictl.h" - -+int proc_listener_socket = -1; -+ -+static void close_listener_socket(int socketfd, const char *file_path); -+ - // Creates the daemon's listener socket, to which clients will connect and - // retrieve slot information through. Returns the file descriptor of the - // created socket. --int CreateListenerSocket(void) -+static int create_listener_socket(const char *file_path) - { - struct sockaddr_un address; - struct group *grp; -@@ -39,53 +43,60 @@ int CreateListenerSocket(void) - ErrLog("Failed to create listener socket, errno 0x%X.", errno); - return -1; - } -- if (unlink(SOCKET_FILE_PATH) && errno != ENOENT) { -+ if (unlink(file_path) && errno != ENOENT) { - ErrLog("Failed to unlink socket file, errno 0x%X.", errno); -- close(socketfd); -- return -1; -+ goto error; - } - - memset(&address, 0, sizeof(struct sockaddr_un)); - address.sun_family = AF_UNIX; -- strcpy(address.sun_path, SOCKET_FILE_PATH); -+ strcpy(address.sun_path, file_path); - - if (bind(socketfd, - (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { - ErrLog("Failed to bind to socket, errno 0x%X.", errno); -- close(socketfd); -- return -1; -+ goto error; - } - // make socket file part of the pkcs11 group, and write accessable - // for that group - grp = getgrnam("pkcs11"); - if (!grp) { - ErrLog("Group PKCS#11 does not exist"); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } -- if (chown(SOCKET_FILE_PATH, 0, grp->gr_gid)) { -+ if (chown(file_path, 0, grp->gr_gid)) { - ErrLog("Could not change file group on socket, errno 0x%X.", errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } -- if (chmod(SOCKET_FILE_PATH, -+ if (chmod(file_path, - S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP | S_IXUSR | S_IXGRP)) { - ErrLog("Could not change file permissions on socket, errno 0x%X.", - errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } - - if (listen(socketfd, 20) != 0) { - ErrLog("Failed to listen to socket, errno 0x%X.", errno); -- DetachSocketListener(socketfd); -- return -1; -+ goto error; - } - - return socketfd; -+ -+error: -+ if (socketfd >= 0) -+ close_listener_socket(socketfd, file_path); -+ -+ return -1; -+} -+ -+ -+static void close_listener_socket(int socketfd, const char *file_path) -+{ -+ close(socketfd); -+ unlink(file_path); - } - --int InitSocketData(Slot_Mgr_Socket_t *socketData) -+int init_socket_data(Slot_Mgr_Socket_t *socketData) - { - unsigned int processed = 0; - -@@ -102,19 +113,19 @@ int InitSocketData(Slot_Mgr_Socket_t *socketData) - return TRUE; - } - --int SocketConnectionHandler(int socketfd, int timeout_secs) -+int socket_connection_handler(int timeout_secs) - { - int returnVal; - fd_set set; - struct timeval timeout; - - FD_ZERO(&set); -- FD_SET(socketfd, &set); -+ FD_SET(proc_listener_socket, &set); - - timeout.tv_sec = timeout_secs; - timeout.tv_usec = 0; - -- returnVal = select(socketfd + 1, &set, NULL, NULL, &timeout); -+ returnVal = select(proc_listener_socket + 1, &set, NULL, NULL, &timeout); - if (returnVal == -1) { - ErrLog("select failed on socket connection, errno 0x%X.", errno); - return FALSE; -@@ -125,7 +136,7 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - struct sockaddr_un address; - socklen_t address_length = sizeof(address); - -- int connectionfd = accept(socketfd, -+ int connectionfd = accept(proc_listener_socket, - (struct sockaddr *) &address, - &address_length); - if (connectionfd < 0) { -@@ -138,6 +149,10 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - } - return FALSE; - } -+ -+ DbgLog(DL0, "Accepted connection from process: socket: %d", -+ connectionfd); -+ - if (write(connectionfd, &socketData, sizeof(socketData)) != - sizeof(socketData)) { - ErrLog("Failed to write socket data, errno 0x%X.", errno); -@@ -149,8 +164,23 @@ int SocketConnectionHandler(int socketfd, int timeout_secs) - } - } - --void DetachSocketListener(int socketfd) -+int init_socket_server() - { -- close(socketfd); -- unlink(SOCKET_FILE_PATH); -+ proc_listener_socket = create_listener_socket(PROC_SOCKET_FILE_PATH); -+ if (proc_listener_socket < 0) -+ return FALSE; -+ -+ DbgLog(DL0, "Socket server started"); -+ -+ return TRUE; -+} -+ -+int term_socket_server() -+{ -+ if (proc_listener_socket >= 0) -+ close_listener_socket(proc_listener_socket, PROC_SOCKET_FILE_PATH); -+ -+ DbgLog(DL0, "Socket server stopped"); -+ -+ return TRUE; - } diff --git a/SOURCES/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch b/SOURCES/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch deleted file mode 100644 index 30a506a..0000000 --- a/SOURCES/opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch +++ /dev/null @@ -1,287 +0,0 @@ -commit fa94a16116d8382a987ddf9e8cdd88027dd1f647 -Author: Ingo Franzki -Date: Tue Feb 16 17:13:34 2021 +0100 - - Event support: Add event client - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/common/common.mk b/usr/lib/common/common.mk -index 2178ad45..882c84f4 100644 ---- a/usr/lib/common/common.mk -+++ b/usr/lib/common/common.mk -@@ -4,7 +4,7 @@ noinst_HEADERS += \ - usr/lib/common/shared_memory.h usr/lib/common/tok_spec_struct.h \ - usr/lib/common/trace.h usr/lib/common/h_extern.h \ - usr/lib/common/sw_crypt.h usr/lib/common/defs.h \ -- usr/lib/common/p11util.h \ -+ usr/lib/common/p11util.h usr/lib/common/event_client.h \ - usr/lib/common/list.h usr/lib/common/tok_specific.h - - usr/lib/common/lexer.c: usr/lib/common/parser.h -diff --git a/usr/lib/common/event_client.c b/usr/lib/common/event_client.c -new file mode 100644 -index 00000000..86117b84 ---- /dev/null -+++ b/usr/lib/common/event_client.c -@@ -0,0 +1,215 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "slotmgr.h" -+#include "event_client.h" -+ -+static int connect_socket(const char *file_path) -+{ -+ int socketfd; -+ struct sockaddr_un daemon_address; -+ struct stat file_info; -+ struct group *grp; -+ int rc; -+ -+ if (stat(file_path, &file_info)) -+ return -errno; -+ -+ grp = getgrnam("pkcs11"); -+ if (!grp) -+ return -errno; -+ -+ if (file_info.st_uid != 0 || file_info.st_gid != grp->gr_gid) -+ return -EPERM; -+ -+ if ((socketfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) -+ return -errno; -+ -+ memset(&daemon_address, 0, sizeof(struct sockaddr_un)); -+ daemon_address.sun_family = AF_UNIX; -+ strcpy(daemon_address.sun_path, file_path); -+ -+ if (connect(socketfd, (struct sockaddr *) &daemon_address, -+ sizeof(struct sockaddr_un)) != 0) { -+ rc = -errno; -+ goto error; -+ } -+ -+ return socketfd; -+ -+error: -+ close(socketfd); -+ return rc; -+} -+ -+static ssize_t read_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_received = 0; -+ ssize_t n; -+ -+ while (bytes_received < size) { -+ n = read(socketfd, buffer + bytes_received, size - bytes_received); -+ if (n < 0) { -+ // read error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; -+ -+ bytes_received += n; -+ } -+ -+ return bytes_received; -+} -+ -+static ssize_t send_all(int socketfd, char *buffer, size_t size) -+{ -+ size_t bytes_sent = 0; -+ ssize_t n; -+ -+ while (bytes_sent < size) { -+ n = send(socketfd, buffer + bytes_sent, size - bytes_sent, 0); -+ if (n < 0) { -+ // send error -+ if (errno == EINTR) -+ continue; -+ return -errno; -+ } -+ if (n == 0) -+ break; -+ -+ bytes_sent += n; -+ } -+ -+ return bytes_sent; -+} -+ -+/* -+ * Initialize an admin connection to the pkcsslotd. -+ * Returns a file descriptor representing the connection, or a negative errno -+ * in case of an error. -+ */ -+int init_event_client() -+{ -+ int fd; -+ -+ fd = connect_socket(ADMIN_SOCKET_FILE_PATH); -+ -+ return fd; -+} -+ -+/* -+ * Send an event though the admin connection to the pkcsslotd, and thus to -+ * all active token instances. -+ * If parameter fd is < 0, then a connection to pkcsslotd is established -+ * inside the function and closed before return. This is for a one shot event. -+ * Otherwise, pass a file descriptor received from init_event_client(). This -+ * is to send multiple events. -+ * Event type is mandatory, flags can be zero. -+ * The event payload is optional, if payload_len is non-zero, then payload must -+ * point to a buffer containing the payload to send with the event. -+ * The event destination can be used to selectively send the event to certain -+ * token instances only. If destination is NULL, it is sent to all token -+ * instances. -+ * If flag EVENT_FLAGS_REPLY_REQ is on in the flags parameter, then it is waited -+ * until all active token instances have replied. The combined result of the -+ * replies from the token instances is returned in the reply structure. -+ * Parameter reply must be non-NULL if flag EVENT_FLAGS_REPLY_REQ is set. -+ * Returns zero for success, or a negative errno in case of an error. In most -+ * error cases the connection to the pkcsslotd is out of sequence and can no -+ * longer be used to send further events. -+ */ -+int send_event(int fd, unsigned int type, unsigned int flags, -+ unsigned int payload_len, const char *payload, -+ const struct event_destination *destination, -+ struct event_reply *reply) -+{ -+ event_msg_t event_msg; -+ event_reply_t event_reply; -+ int rc, term = 0; -+ -+ if (payload_len > 0 && payload == NULL) -+ return -EINVAL; -+ if ((flags & EVENT_FLAGS_REPLY_REQ) && reply == NULL) -+ return -EINVAL; -+ if (payload_len > EVENT_MAX_PAYLOAD_LENGTH) -+ return -EMSGSIZE; -+ -+ if (fd < 0) { -+ fd = init_event_client(); -+ if (fd < 0) -+ return fd; -+ term = 1; -+ } -+ -+ memset(&event_msg, 0, sizeof(event_msg)); -+ event_msg.version = EVENT_VERSION_1; -+ event_msg.type = type; -+ event_msg.flags = flags; -+ if (destination != NULL) { -+ event_msg.token_type = destination->token_type; -+ memcpy(event_msg.token_label, destination->token_label, -+ sizeof(event_msg.token_label)); -+ event_msg.process_id = destination->process_id; -+ } else { -+ memset(event_msg.token_label, ' ', sizeof(event_msg.token_label)); -+ } -+ event_msg.payload_len = payload_len; -+ -+ rc = send_all(fd, (char *)&event_msg, sizeof(event_msg)); -+ if (rc < 0) -+ goto out; -+ -+ if (payload_len > 0) { -+ rc = send_all(fd, (char *)payload, payload_len); -+ if (rc < 0) -+ goto out; -+ } -+ -+ if (flags & EVENT_FLAGS_REPLY_REQ) { -+ rc = read_all(fd, (char *)&event_reply, sizeof(event_reply)); -+ if (rc < 0) -+ goto out; -+ -+ reply->positive_replies = event_reply.positive_replies; -+ reply->negative_replies = event_reply.negative_replies; -+ reply->nothandled_replies = event_reply.nothandled_replies; -+ } -+ -+ rc = 0; -+ -+out: -+ if (term) -+ term_event_client(fd); -+ -+ return rc; -+} -+ -+/* -+ * Terminate the admin connection to the pkcsslotd. -+ */ -+void term_event_client(int fd) -+{ -+ if (fd >= 0) -+ close(fd); -+} -+ -diff --git a/usr/lib/common/event_client.h b/usr/lib/common/event_client.h -new file mode 100644 -index 00000000..2e4917b0 ---- /dev/null -+++ b/usr/lib/common/event_client.h -@@ -0,0 +1,39 @@ -+/* -+ * COPYRIGHT (c) International Business Machines Corp. 2021 -+ * -+ * This program is provided under the terms of the Common Public License, -+ * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this -+ * software constitutes recipient's acceptance of CPL-1.0 terms which can be -+ * found in the file LICENSE file or at -+ * https://opensource.org/licenses/cpl1.0.php -+ */ -+ -+ -+#ifndef _EVENT_CLIENT_H_ -+#define _EVENT_CLIENT_H_ -+ -+#include "events.h" -+ -+struct event_destination { -+ unsigned int token_type; /* Destination token type: EVENT_TOK_TYPE_xxx */ -+ char token_label[member_size(event_msg_t, token_label)]; -+ /* Label of destination token (or blanks) */ -+ pid_t process_id; /* Process ID of destination process (or 0) */ -+}; -+ -+struct event_reply { -+ unsigned long positive_replies; -+ unsigned long negative_replies; -+ unsigned long nothandled_replies; -+}; -+ -+int init_event_client(); -+ -+int send_event(int fd, unsigned int type, unsigned int flags, -+ unsigned int payload_len, const char *payload, -+ const struct event_destination *destination, -+ struct event_reply *reply); -+ -+void term_event_client(int fd); -+ -+#endif diff --git a/SOURCES/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch b/SOURCES/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch deleted file mode 100644 index 128ea06..0000000 --- a/SOURCES/opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch +++ /dev/null @@ -1,106 +0,0 @@ -commit 5951869263b556280da53498270cf4826f779c5b -Author: Ingo Franzki -Date: Tue Jul 13 09:05:22 2021 +0200 - - pkcstok_migrate: Fix detection if pkcsslotd is still running - - Change the code to use the pid file that pkcsslotd creates, and check - if the process with the pid contained in the pid file still exists and - runs pkcsslotd. - - Signed-off-by: Ingo Franzki - -diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -index 05081aff..a29dc8f7 100644 ---- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c -@@ -2474,54 +2474,53 @@ static CK_RV backup_repository(const char *data_store) - */ - static CK_BBOOL pkcsslotd_running(void) - { -- DIR *dir; - FILE *fp; -- struct dirent* ent; - char* endptr; -- char buf[PATH_MAX]; -+ long lpid; - char fname[PATH_MAX]; -+ char buf[PATH_MAX]; -+ char* first; - - TRACE_INFO("Checking if pkcsslotd is running ...\n"); -- if (!(dir = opendir("/proc"))) { -- TRACE_WARN("Cannot open /proc, i.e. cannot check if pkcsslotd is running.\n"); -- return CK_TRUE; -+ -+ fp = fopen(PID_FILE_PATH, "r"); -+ if (fp == NULL) { -+ TRACE_INFO("Pid file '%s' not existent, pkcsslotd is not running\n", -+ PID_FILE_PATH); -+ return CK_FALSE; - } - -- while ((ent = readdir(dir)) != NULL) { -- /* if endptr is not a null character, the directory is not -- * entirely numeric, so ignore it */ -- long lpid = strtol(ent->d_name, &endptr, 10); -- if (*endptr != '\0') { -- continue; -- } -+ if (fgets(buf, sizeof(buf), fp) == NULL) { -+ TRACE_WARN("Cannot read pid file '%s': %s\n", PID_FILE_PATH, -+ strerror(errno)); -+ fclose(fp); -+ return CK_FALSE; -+ } -+ fclose(fp); - -- /* try to open the cmdline file */ -- snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid); -- fp = fopen(fname, "r"); -- if (!fp) { -- warnx("fopen(%s) failed, errno=%s", fname, strerror(errno)); -- return CK_TRUE; -- } -+ lpid = strtol(buf, &endptr, 10); -+ if (*endptr != '\0' && *endptr != '\n') { -+ TRACE_WARN("Failed to parse pid file '%s': %s\n", PID_FILE_PATH, -+ buf); -+ return CK_FALSE; -+ } - -- /* check the first token in the file: the program pathname */ -- if (fgets(buf, sizeof(buf), fp) != NULL) { -- char* first = strtok(buf, " "); -- if (!first) { -- TRACE_WARN("Cannot read program name from %s, i.e. cannot check if pkcsslotd is running.\n", -- fname); -- return CK_TRUE; -- } -- if (strstr(first, "pkcsslotd") != NULL) { -- fclose(fp); -- closedir(dir); -- return CK_TRUE; -- } -- } -+ snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid); -+ fp = fopen(fname, "r"); -+ if (fp == NULL) { -+ TRACE_INFO("Stale pid file, pkcsslotd is not running\n"); -+ return CK_FALSE; -+ } -+ -+ if (fgets(buf, sizeof(buf), fp) == NULL) { -+ TRACE_INFO("Failed to read '%s'\n", fname); - fclose(fp); -+ return CK_FALSE; - } -+ fclose(fp); - -- closedir(dir); -- return CK_FALSE; -+ first = strtok(buf, " "); -+ return (first != NULL && strstr(first, "pkcsslotd") != NULL); - } - - /** diff --git a/SOURCES/opencryptoki-3.17.0-p11sak.patch b/SOURCES/opencryptoki-3.17.0-p11sak.patch new file mode 100644 index 0000000..62ccf2a --- /dev/null +++ b/SOURCES/opencryptoki-3.17.0-p11sak.patch @@ -0,0 +1,12 @@ +diff -up opencryptoki-3.17.0/Makefile.am.me opencryptoki-3.17.0/Makefile.am +--- opencryptoki-3.17.0/Makefile.am.me 2021-11-09 09:45:49.032661898 +0100 ++++ opencryptoki-3.17.0/Makefile.am 2021-11-09 09:46:41.353400986 +0100 +@@ -76,7 +76,7 @@ if ENABLE_EP11TOK + endif + if ENABLE_P11SAK + test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true +- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -g pkcs11 -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true ++ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -m 0644 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true + endif + if ENABLE_ICATOK + cd $(DESTDIR)$(libdir)/opencryptoki/stdll && \ diff --git a/SOURCES/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch b/SOURCES/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch deleted file mode 100644 index 3448bff..0000000 --- a/SOURCES/opencryptoki-openssl3-11196c4d7e221d29f0d385bd48ae4d6023a6e874.patch +++ /dev/null @@ -1,24 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch b/SOURCES/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch deleted file mode 100644 index 996eb6a..0000000 --- a/SOURCES/opencryptoki-openssl3-11a53055b22d590bd3c197908b0ff63f6fd3c520.patch +++ /dev/null @@ -1,123 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch b/SOURCES/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch deleted file mode 100644 index 9f87102..0000000 --- a/SOURCES/opencryptoki-openssl3-145a696d478a1694ef314659a3d374f03f75c1b1.patch +++ /dev/null @@ -1,30 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch b/SOURCES/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch deleted file mode 100644 index 171c080..0000000 --- a/SOURCES/opencryptoki-openssl3-2c116d49359a5eb91ad7f1483c64650c7874a513.patch +++ /dev/null @@ -1,38 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-376e664f082b66de970b62a81588b034fd560d27.patch b/SOURCES/opencryptoki-openssl3-376e664f082b66de970b62a81588b034fd560d27.patch deleted file mode 100644 index 8c81fe6..0000000 --- a/SOURCES/opencryptoki-openssl3-376e664f082b66de970b62a81588b034fd560d27.patch +++ /dev/null @@ -1,41 +0,0 @@ -commit 376e664f082b66de970b62a81588b034fd560d27 -Author: Ingo Franzki -Date: Fri Aug 13 10:54:44 2021 +0200 - - TESTCASES: Remove RSA public exponent restriction for Soft token - - Since commit "Allow small RSA exponents in the default provider" - https://github.com/openssl/openssl/commit/254957f768a61c91c14d89566224173d0831c2ce - in OpenSSL 3.0, we do no longer need to restrict the tests for the Soft - token to RSA public exponents of 3 and 65537 only. - - Signed-off-by: Ingo Franzki - -diff --git a/testcases/common/common.c b/testcases/common/common.c -index 0a64ecf2..abbe354f 100644 ---- a/testcases/common/common.c -+++ b/testcases/common/common.c -@@ -16,6 +16,8 @@ - #include "pkcs11types.h" - #include "regress.h" - -+#define UNUSED(var) ((void)(var)) -+ - CK_FUNCTION_LIST *funcs; - CK_FUNCTION_LIST_3_0 *funcs3; - CK_INTERFACE *ifs; -@@ -879,11 +881,10 @@ int is_valid_cca_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len) - /** 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 -+ UNUSED(pubexp); -+ UNUSED(pubexp_len); - -- return (pubexp_len == 1 && (!memcmp(pubexp, exp3, 1))) -- || (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3))); -+ return TRUE; - } - - /** Returns true if slot_id is an ICSF token diff --git a/SOURCES/opencryptoki-openssl3-4dd8a952fc00dd54cce090e4c053de408ba3884b.patch b/SOURCES/opencryptoki-openssl3-4dd8a952fc00dd54cce090e4c053de408ba3884b.patch deleted file mode 100644 index 66e0bba..0000000 --- a/SOURCES/opencryptoki-openssl3-4dd8a952fc00dd54cce090e4c053de408ba3884b.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit 4dd8a952fc00dd54cce090e4c053de408ba3884b -Author: Ingo Franzki -Date: Tue Aug 24 10:14:39 2021 +0200 - - SOFT: Detect unsupported EC curves with OpenSSL 3.0 - - OpenSSL 3.0 behaves different in reporting an error when an unsupported - EC curve is used to generate an EC key. OpenSSL 1.1.1 returns an error - at EVP_PKEY_CTX_set_ec_paramgen_curve_nid() already, but OpenSSL 3.0 returns - an error only at EVP_PKEY_keygen(). - - Signed-off-by: Ingo Franzki - -diff --git a/usr/lib/soft_stdll/soft_specific.c b/usr/lib/soft_stdll/soft_specific.c -index 43fd17c3..03767ec8 100644 ---- a/usr/lib/soft_stdll/soft_specific.c -+++ b/usr/lib/soft_stdll/soft_specific.c -@@ -51,6 +51,7 @@ - #include - #include - #include -+#include - #if OPENSSL_VERSION_PREREQ(3, 0) - #include - #include -@@ -4548,7 +4549,10 @@ CK_RV token_specific_ec_generate_keypair(STDLL_TokData_t *tokdata, - - if (EVP_PKEY_keygen(ctx, &ec_pkey) <= 0) { - TRACE_ERROR("EVP_PKEY_keygen failed\n"); -- rc = CKR_FUNCTION_FAILED; -+ if (ERR_GET_REASON(ERR_peek_last_error()) == EC_R_INVALID_CURVE) -+ rc = CKR_CURVE_NOT_SUPPORTED; -+ else -+ rc = CKR_FUNCTION_FAILED; - goto out; - } - diff --git a/SOURCES/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch b/SOURCES/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch deleted file mode 100644 index 3070552..0000000 --- a/SOURCES/opencryptoki-openssl3-50408fc3ae0f25b256dda2033d538f88c9b4f903.patch +++ /dev/null @@ -1,322 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch b/SOURCES/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch deleted file mode 100644 index 08998cc..0000000 --- a/SOURCES/opencryptoki-openssl3-50e3f06823696c74eea90a77e16b28da1f79cd47.patch +++ /dev/null @@ -1,3420 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch b/SOURCES/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch deleted file mode 100644 index af4395d..0000000 --- a/SOURCES/opencryptoki-openssl3-533cdea6897d1bc0af13490f1c89248c52e7a73b.patch +++ /dev/null @@ -1,147 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch b/SOURCES/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch deleted file mode 100644 index 165a69b..0000000 --- a/SOURCES/opencryptoki-openssl3-5377d25a6cbe3d07afcd08276ad7e90f62cad0c9.patch +++ /dev/null @@ -1,174 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch b/SOURCES/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch deleted file mode 100644 index 0cfe159..0000000 --- a/SOURCES/opencryptoki-openssl3-5cceead028ec8e0c244b01d38c9096c96d98f96b.patch +++ /dev/null @@ -1,84 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch b/SOURCES/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch deleted file mode 100644 index 5721c2f..0000000 --- a/SOURCES/opencryptoki-openssl3-62fc2bcd98672c5d0ff8a2c926f3103110e91ed7.patch +++ /dev/null @@ -1,226 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch b/SOURCES/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch deleted file mode 100644 index 516b513..0000000 --- a/SOURCES/opencryptoki-openssl3-6fee37f08391415cdf8d8610c501516c3d3ed29c.patch +++ /dev/null @@ -1,193 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch b/SOURCES/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch deleted file mode 100644 index b3c2339..0000000 --- a/SOURCES/opencryptoki-openssl3-7a23c12214688b287b9591133445e593da633caa.patch +++ /dev/null @@ -1,1085 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch b/SOURCES/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch deleted file mode 100644 index 104a5f4..0000000 --- a/SOURCES/opencryptoki-openssl3-7b4177e8557887d196ce77a129d457e817f8cc59.patch +++ /dev/null @@ -1,870 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch b/SOURCES/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch deleted file mode 100644 index a9d436e..0000000 --- a/SOURCES/opencryptoki-openssl3-93588f53d918fe6c7452da076b95081fb6aa9aef.patch +++ /dev/null @@ -1,1847 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch b/SOURCES/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch deleted file mode 100644 index 091bc8e..0000000 --- a/SOURCES/opencryptoki-openssl3-ab3fceae6194e8213e9d3ffb7447ccd04d469b9d.patch +++ /dev/null @@ -1,115 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch b/SOURCES/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch deleted file mode 100644 index 8a88c26..0000000 --- a/SOURCES/opencryptoki-openssl3-c4683eb904238d20cb34a4c7661ffac04901283c.patch +++ /dev/null @@ -1,37 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch b/SOURCES/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch deleted file mode 100644 index dccf2e8..0000000 --- a/SOURCES/opencryptoki-openssl3-dd9cfe2ef89dad185397df46227f9392a6317d35.patch +++ /dev/null @@ -1,49 +0,0 @@ -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/SOURCES/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch b/SOURCES/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch deleted file mode 100644 index 722c1d6..0000000 --- a/SOURCES/opencryptoki-openssl3-ecf71404e84ae35931cd6c7398c825378ee052b6.patch +++ /dev/null @@ -1,853 +0,0 @@ -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/SOURCES/opencryptoki-pkcsslotd-pidfile.patch b/SOURCES/opencryptoki-pkcsslotd-pidfile.patch index 8af4d96..92f7e3c 100644 --- a/SOURCES/opencryptoki-pkcsslotd-pidfile.patch +++ b/SOURCES/opencryptoki-pkcsslotd-pidfile.patch @@ -10,3 +10,20 @@ diff -up opencryptoki-3.16.0/misc/pkcsslotd.service.in.me opencryptoki-3.16.0/mi ExecStart=@sbindir@/pkcsslotd [Install] +diff -up opencryptoki-3.16.0/usr/include/slotmgr.h.me opencryptoki-3.16.0/usr/include/slotmgr.h +--- opencryptoki-3.16.0/usr/include/slotmgr.h.me 2021-06-30 17:28:18.000594834 +0200 ++++ opencryptoki-3.16.0/usr/include/slotmgr.h 2021-06-30 17:28:38.920890278 +0200 +@@ -30,10 +30,10 @@ + #define TOK_PATH SBIN_PATH "/pkcsslotd" + #define OCK_API_LOCK_FILE LOCKDIR_PATH "/LCK..APIlock" + +-#define PROC_SOCKET_FILE_PATH "/var/run/pkcsslotd.socket" +-#define ADMIN_SOCKET_FILE_PATH "/var/run/pkcsslotd.admin.socket" ++#define PROC_SOCKET_FILE_PATH "/run/pkcsslotd.socket" ++#define ADMIN_SOCKET_FILE_PATH "/run/pkcsslotd.admin.socket" + +-#define PID_FILE_PATH "/var/run/pkcsslotd.pid" ++#define PID_FILE_PATH "/run/pkcsslotd.pid" + #define OCK_CONFIG OCK_CONFDIR "/opencryptoki.conf" + + #ifndef CK_BOOL diff --git a/SOURCES/opencryptoki.module b/SOURCES/opencryptoki.module deleted file mode 100644 index 4720c04..0000000 --- a/SOURCES/opencryptoki.module +++ /dev/null @@ -1,8 +0,0 @@ -# This file describes how to load the opensc module -# See: http://p11-glue.freedesktop.org/doc/p11-kit/config.html - -# This is a relative path, which means it will be loaded from -# the p11-kit default path which is usually $(libdir)/pkcs11. -# Doing it this way allows for packagers to package opensc for -# 32-bit and 64-bit and make them parallel installable -module: libopencryptoki.so diff --git a/SPECS/opencryptoki.spec b/SPECS/opencryptoki.spec index 6235217..0c064ad 100644 --- a/SPECS/opencryptoki.spec +++ b/SPECS/opencryptoki.spec @@ -1,66 +1,25 @@ Name: opencryptoki -Summary: Implementation of the PKCS#11 (Cryptoki) specification v2.11 -Version: 3.16.0 -Release: 12%{?dist} +Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0 +Version: 3.17.0 +Release: 3%{?dist} License: CPL URL: https://github.com/opencryptoki/opencryptoki Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz -Source1: opencryptoki.module # https://bugzilla.redhat.com/show_bug.cgi?id=732756 Patch0: opencryptoki-3.11.0-group.patch - # bz#1373833, change tmpfiles snippets from /var/lock/* to /run/lock/* Patch1: opencryptoki-3.11.0-lockdir.patch -# PIDfile below legacy directory /var/run/ -Patch2: opencryptoki-pkcsslotd-pidfile.patch -# Use --no-undefined to debug missing symbols -#Patch100: %%{name}-3.2-no-undefined.patch - +# add missing p11sak_defined_attrs.conf +Patch2: opencryptoki-3.17.0-p11sak.patch # upstream patches -Patch200: opencryptoki-3.16.0-4e3b43c3d8844402c04a66b55c6c940f965109f0.patch -Patch201: opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch -Patch202: opencryptoki-3.16.0-69244a5e0d9dfec3ef534b19b89a541576bb17dc.patch -Patch203: opencryptoki-3.16.0-b07505993dd8b2f367cf3b630f6da186e4e8550d.patch -Patch204: opencryptoki-3.16.0-b048be548508dd1958bb7271568f388d0f6cbcf8.patch -Patch205: opencryptoki-3.16.0-e9548127edae313da7840bcb87fd0afd04549c2e.patch -Patch206: opencryptoki-3.16.0-d929fe8470e99f4dcbbd889e7aa87e147d0d5b48.patch -Patch207: opencryptoki-3.16.0-19f56d12b302b87e1dacf613cc61a063ad209d15.patch -Patch208: opencryptoki-3.16.0-342dfbeb8275f5ea6ed52dd3f30126614ec1d037.patch -Patch209: opencryptoki-3.16.0-fa94a16116d8382a987ddf9e8cdd88027dd1f647.patch -Patch210: opencryptoki-3.16.0-d7de5092247a0efc2c397f12977a7c9925420143.patch -Patch211: opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch -Patch212: opencryptoki-3.16.0-bf812c652c49d7e248b115d121a4f7f6568941a2.patch -Patch213: opencryptoki-3.16.0-7b7d83c571ceb3050969359817d4145600f14ae8.patch -Patch214: opencryptoki-3.16.0-pkcstok_migrate-detection_if_pkcsslotd_is_still_running.patch -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 -Patch237: opencryptoki-openssl3-4dd8a952fc00dd54cce090e4c053de408ba3884b.patch -Patch238: opencryptoki-openssl3-376e664f082b66de970b62a81588b034fd560d27.patch +# PIDfile below legacy directory /var/run/ +Patch300: opencryptoki-pkcsslotd-pidfile.patch Requires(pre): coreutils Requires: (selinux-policy >= 34.1.8-1 if selinux-policy-targeted) BuildRequires: gcc BuildRequires: gcc-c++ -BuildRequires: openssl-devel +BuildRequires: openssl-devel >= 1.1.1 %if 0%{?tmptok} BuildRequires: trousers-devel %endif @@ -72,7 +31,7 @@ BuildRequires: libitm-devel BuildRequires: expect BuildRequires: make %ifarch s390 s390x -BuildRequires: libica-devel >= 2.3 +BuildRequires: libica-devel >= 3.3 %endif Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} Requires: %{name}-libs%{?_isa} = %{version}-%{release} @@ -83,7 +42,7 @@ Requires(postun): systemd %description -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -96,7 +55,7 @@ Summary: The run-time libraries for opencryptoki package Requires(pre): shadow-utils %description libs -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -122,7 +81,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description swtok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -138,7 +97,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description tpmtok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -154,7 +113,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description icsftok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -171,7 +130,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description icatok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -188,7 +147,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description ccatok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -205,7 +164,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release} Provides: %{name}(token) %description ep11tok -Opencryptoki implements the PKCS#11 specification v2.11 for a set of +Opencryptoki implements the PKCS#11 specification v2.20 for a set of cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the Trusted Platform Module (TPM) chip. Opencryptoki also brings a software token implementation that can be used without any cryptographic @@ -266,6 +225,7 @@ fi %doc doc/README.token_data %dir %{_sysconfdir}/%{name} %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf +%attr(0640, root, pkcs11) %config(noreplace) %{_sysconfdir}/%{name}/p11sak_defined_attrs.conf %{_tmpfilesdir}/%{name}.conf %{_unitdir}/pkcsslotd.service %{_sbindir}/p11sak @@ -276,6 +236,7 @@ fi %{_mandir}/man1/pkcstok_migrate.1* %{_mandir}/man1/pkcsconf.1* %{_mandir}/man5/%{name}.conf.5* +%{_mandir}/man5/p11sak_defined_attrs.conf.5* %{_mandir}/man7/%{name}.7* %{_mandir}/man8/pkcsslotd.8* %{_libdir}/opencryptoki/methods @@ -357,6 +318,16 @@ fi %changelog +* Sat Dec 04 2021 Than Ngo - 3.17.0-3 +- Related: #2015888, added missing patch pkcsslotd-pidfile + +* Wed Nov 24 2021 Than Ngo - 3.17.0-2 +- Related: #2015888, add missing p11sak_defined_attrs.conf + +* Wed Nov 03 2021 Than Ngo - 3.17.0-1 +- Resolves: #2015888, rebase to 3.17.0 +- Resolves: #2017720, openCryptoki key management tool + * Thu Aug 26 2021 Than Ngo - 3.16.0-12 - Related: #1989138, Support for OpenSSL 3.0