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