Blame SOURCES/opencryptoki-3.16.0-1fdd0e4497b0078e73e0004e3492db647c7c458b.patch

8520e9
commit 1fdd0e4497b0078e73e0004e3492db647c7c458b
8520e9
Author: Ingo Franzki <ifranzki@linux.ibm.com>
8520e9
Date:   Wed Feb 24 15:47:05 2021 +0100
8520e9
8520e9
    EP11: Handle APQN events to update APQN version, CP infos and target
8520e9
    
8520e9
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
8520e9
8520e9
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
8520e9
index 52f95d7a..728fedd5 100644
8520e9
--- a/usr/lib/ep11_stdll/ep11_specific.c
8520e9
+++ b/usr/lib/ep11_stdll/ep11_specific.c
8520e9
@@ -38,6 +38,7 @@
8520e9
 #include "ock_syslog.h"
8520e9
 #include "ec_defs.h"
8520e9
 #include "p11util.h"
8520e9
+#include "events.h"
8520e9
 
8520e9
 #include <sys/types.h>
8520e9
 #include <sys/stat.h>
8520e9
@@ -197,19 +198,27 @@ typedef struct {
8520e9
 
8520e9
 #define MAX_RETRY_COUNT 100
8520e9
 
8520e9
-#define RETRY_START             do {                                     \
8520e9
+#define RETRY_START(rc, tokdata)                                         \
8520e9
+                                do {                                     \
8520e9
                                     int retry_count;                     \
8520e9
+                                    ep11_target_info_t* target_info =    \
8520e9
+                                             get_target_info((tokdata)); \
8520e9
+                                    if (target_info == NULL)             \
8520e9
+                                        (rc) = CKR_FUNCTION_FAILED;      \
8520e9
                                     for(retry_count = 0;                 \
8520e9
+                                        target_info != NULL &&           \
8520e9
                                         retry_count < MAX_RETRY_COUNT;   \
8520e9
                                         retry_count ++) {
8520e9
 
8520e9
 #define RETRY_END(rc, tokdata, session)  if ((rc) != CKR_SESSION_CLOSED) \
8520e9
                                              break;                      \
8520e9
                                          (rc) = ep11tok_relogin_session( \
8520e9
-                                                      tokdata, session); \
8520e9
+                                                  (tokdata), (session)); \
8520e9
                                          if ((rc) != CKR_OK)             \
8520e9
                                              break;                      \
8520e9
                                     }                                    \
8520e9
+                                    put_target_info((tokdata),           \
8520e9
+                                                    target_info);        \
8520e9
                                 } while (0);
8520e9
 
8520e9
 #define CKF_EP11_HELPER_SESSION      0x80000000
8520e9
@@ -248,7 +257,6 @@ typedef struct ep11_card_version {
8520e9
 } ep11_card_version_t;
8520e9
 
8520e9
 static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version);
8520e9
-static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata);
8520e9
 static void free_card_versions(ep11_card_version_t *card_version);
8520e9
 static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type,
8520e9
                               const CK_VERSION *ep11_lib_version,
8520e9
@@ -476,16 +484,23 @@ static CK_RV handle_all_ep11_cards(ep11_target_t * ep11_targets,
8520e9
 #define PKEY_MODE_ENABLE4NONEXTR    2
8520e9
 
8520e9
 typedef struct {
8520e9
+    volatile unsigned long ref_count;
8520e9
     target_t target;
8520e9
+    ep11_card_version_t *card_versions;
8520e9
+    CK_ULONG used_firmware_API_version;
8520e9
+    unsigned char control_points[XCP_CP_BYTES];
8520e9
+    size_t control_points_len;
8520e9
+    size_t max_control_point_index;
8520e9
+    CK_CHAR serialNumber[16];
8520e9
+} ep11_target_info_t;
8520e9
+
8520e9
+typedef struct {
8520e9
     ep11_target_t target_list;
8520e9
     CK_BYTE raw2key_wrap_blob[MAX_BLOBSIZE];
8520e9
     size_t raw2key_wrap_blob_l;
8520e9
     int cka_sensitive_default_true;
8520e9
     char cp_filter_config_filename[PATH_MAX];
8520e9
     cp_config_t *cp_config;
8520e9
-    unsigned char control_points[XCP_CP_BYTES];
8520e9
-    size_t control_points_len;
8520e9
-    size_t max_control_point_index;
8520e9
     int strict_mode;
8520e9
     int vhsm_mode;
8520e9
     int optimize_single_ops;
8520e9
@@ -497,12 +512,14 @@ typedef struct {
8520e9
     char digest_libica_path[PATH_MAX];
8520e9
     libica_t libica;
8520e9
     CK_VERSION ep11_lib_version;
8520e9
-    ep11_card_version_t *card_versions;
8520e9
-    CK_ULONG used_firmware_API_version;
8520e9
-    CK_CHAR serialNumber[16];
8520e9
+    volatile ep11_target_info_t *target_info;
8520e9
+    pthread_rwlock_t target_rwlock;
8520e9
 } ep11_private_data_t;
8520e9
 
8520e9
-static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata);
8520e9
+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata);
8520e9
+static void put_target_info(STDLL_TokData_t *tokdata,
8520e9
+                            ep11_target_info_t *target_info);
8520e9
+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata);
8520e9
 
8520e9
 static CK_RV get_ep11_target_for_apqn(uint_32 adapter, uint_32 domain,
8520e9
                                       target_t *target, uint64_t flags);
8520e9
@@ -704,8 +721,13 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata)
8520e9
     CK_BYTE blob[MAX_BLOBSIZE];
8520e9
     size_t blobsize = sizeof(blob);
8520e9
     CK_ATTRIBUTE *pkey_attr = NULL, *blob_attr=NULL;
8520e9
+    ep11_target_info_t* target_info;
8520e9
     CK_RV ret;
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     /* Check if CPACF_WRAP mech supported */
8520e9
     if (ep11tok_is_mechanism_supported(tokdata, CKM_IBM_CPACF_WRAP) != CKR_OK) {
8520e9
         TRACE_INFO("CKM_IBM_CPACF_WRAP not supported on this system.\n");
8520e9
@@ -717,7 +739,7 @@ static CK_RV ep11tok_pkey_get_firmware_mk_vp(STDLL_TokData_t *tokdata)
8520e9
 
8520e9
     /* Create an AES testkey with CKA_IBM_PROTKEY_EXTRACTABLE */
8520e9
     ret = dll_m_GenerateKey(&mech, tmpl, tmpl_len, NULL, 0,
8520e9
-                            blob, &blobsize, csum, &csum_l, ep11_data->target);
8520e9
+                            blob, &blobsize, csum, &csum_l, target_info->target);
8520e9
     if (ret != CKR_OK) {
8520e9
         TRACE_ERROR("dll_m_GenerateKey failed with rc=0x%lx\n",ret);
8520e9
         goto done;
8520e9
@@ -749,6 +771,8 @@ done:
8520e9
     if (blob_attr)
8520e9
         free(blob_attr);
8520e9
 
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+
8520e9
     return ret;
8520e9
 }
8520e9
 
8520e9
@@ -1337,7 +1361,7 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata,
8520e9
                                        OBJECT *obj,
8520e9
                                        CK_KEY_TYPE keytype)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    ep11_target_info_t* target_info;
8520e9
     CK_RV rc;
8520e9
     CK_BBOOL trusted, encrypt, decrypt, wrap, unwrap, sign, sign_recover,
8520e9
              verify, verify_recover, derive, extractable, local,
8520e9
@@ -1367,9 +1391,16 @@ static CK_RV ab_unwrap_update_template(STDLL_TokData_t * tokdata,
8520e9
     CK_ATTRIBUTE *attr;
8520e9
     CK_BBOOL cktrue = TRUE;
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     rc = dll_m_GetAttributeValue(blob, blob_len, attrs,
8520e9
                                  sizeof(attrs) / sizeof(CK_ATTRIBUTE),
8520e9
-                                 ep11_data->target);
8520e9
+                                 target_info->target);
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+
8520e9
     if (rc != CKR_OK) {
8520e9
         TRACE_ERROR("Retrieving attributes from AB unwrapped key failed, rc=0x%lx\n",
8520e9
                     rc);
8520e9
@@ -2117,10 +2148,10 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
      * calls the ep11 lib (which in turns sends the request to the card),
8520e9
      * all m_ function are ep11 functions
8520e9
      */
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, &mech, key,
8520e9
-                                 ksize, cipher, &clen, ep11_data->target);
8520e9
+                                 ksize, cipher, &clen, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -2146,12 +2177,12 @@ static CK_RV rawkey_2_blob(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
     /* the encrypted key is decrypted and a blob is build,
8520e9
      * card accepts only blobs as keys
8520e9
      */
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_UnwrapKey(cipher, clen, ep11_data->raw2key_wrap_blob,
8520e9
                              ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                              ep11_pin_blob, ep11_pin_blob_len, &mech,
8520e9
                              new_p_attrs, new_attrs_len, blob, blen, csum,
8520e9
-                             &cslen, ep11_data->target);
8520e9
+                             &cslen, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -2194,14 +2225,20 @@ rawkey_2_blob_end:
8520e9
 CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output,
8520e9
                          CK_ULONG bytes)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
-    CK_RV rc = dll_m_GenerateRandom(output, bytes, ep11_data->target);
8520e9
+    CK_RV rc = dll_m_GenerateRandom(output, bytes, target_info->target);
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
         TRACE_ERROR("%s output=%p bytes=%lu rc=0x%lx\n",
8520e9
                     __func__, (void *)output, bytes, rc);
8520e9
     }
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -2215,6 +2252,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in,
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_MECHANISM mech = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
8520e9
+    ep11_target_info_t* target_info;
8520e9
     CK_BYTE csum[MAX_CSUMSIZE];
8520e9
     size_t csum_l = sizeof(csum);
8520e9
     CK_RV rc;
8520e9
@@ -2225,11 +2263,15 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in,
8520e9
         return CKR_OK;
8520e9
     }
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     ep11_data->raw2key_wrap_blob_l = sizeof(ep11_data->raw2key_wrap_blob);
8520e9
     rc = dll_m_GenerateKey(&mech, tmpl_in, tmpl_len, NULL, 0,
8520e9
                            ep11_data->raw2key_wrap_blob,
8520e9
                            &ep11_data->raw2key_wrap_blob_l, csum, &csum_l,
8520e9
-                           ep11_data->target);
8520e9
+                           target_info->target);
8520e9
 
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -2240,6 +2282,7 @@ static CK_RV make_wrapblob(STDLL_TokData_t * tokdata, CK_ATTRIBUTE * tmpl_in,
8520e9
                    __func__, ep11_data->raw2key_wrap_blob_l, rc);
8520e9
     }
8520e9
 
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -2479,6 +2522,14 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
8520e9
     if (ep11_data == NULL)
8520e9
         return CKR_HOST_MEMORY;
8520e9
 
8520e9
+    if (pthread_rwlock_init(&ep11_data->target_rwlock, NULL) != 0) {
8520e9
+        TRACE_DEVEL("Target Lock init failed.\n");
8520e9
+        OCK_SYSLOG(LOG_ERR, "%s: Failed to initialize the target lock\n",
8520e9
+                   __func__);
8520e9
+        rc = CKR_CANT_LOCK;
8520e9
+        goto error;
8520e9
+    }
8520e9
+
8520e9
     tokdata->private_data = ep11_data;
8520e9
 
8520e9
     /* read ep11 specific config file with user specified
8520e9
@@ -2513,13 +2564,28 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
8520e9
     }
8520e9
 #endif
8520e9
 
8520e9
-    rc = ep11tok_get_ep11_version(tokdata);
8520e9
-    if (rc != CKR_OK)
8520e9
+    rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s Failed to get the Ep11 library version "
8520e9
+                    "(ep11tok_get_ep11_library_version rc=0x%lx)\n", __func__,
8520e9
+                    rc);
8520e9
+        OCK_SYSLOG(LOG_ERR, "%s: Failed to get the EP11 library version "
8520e9
+                   "rc=0x%lx\n", __func__, rc);
8520e9
         goto error;
8520e9
+    }
8520e9
 
8520e9
-    rc = ep11tok_setup_target(tokdata);
8520e9
-    if (rc != CKR_OK)
8520e9
+    TRACE_INFO("%s Host library version: %d.%d\n", __func__,
8520e9
+               ep11_data->ep11_lib_version.major,
8520e9
+               ep11_data->ep11_lib_version.minor);
8520e9
+
8520e9
+    rc = refresh_target_info(tokdata);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s Failed to get the target info (refresh_target_info "
8520e9
+                    "rc=0x%lx)\n", __func__, rc);
8520e9
+        OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n",
8520e9
+                   __func__, rc);
8520e9
         goto error;
8520e9
+    }
8520e9
 
8520e9
     if (ep11_data->digest_libica) {
8520e9
         rc = ep11tok_load_libica(tokdata);
8520e9
@@ -2530,18 +2596,6 @@ CK_RV ep11tok_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
8520e9
     ep11_data->msa_level = get_msa_level();
8520e9
     TRACE_INFO("MSA level = %i\n", ep11_data->msa_level);
8520e9
 
8520e9
-    ep11_data->control_points_len = sizeof(ep11_data->control_points);
8520e9
-    rc = get_control_points(tokdata, ep11_data->control_points,
8520e9
-                            &ep11_data->control_points_len,
8520e9
-                            &ep11_data->max_control_point_index);
8520e9
-    if (rc != CKR_OK) {
8520e9
-        TRACE_ERROR("%s Failed to get the control points (get_control_points "
8520e9
-                    "rc=0x%lx)\n", __func__, rc);
8520e9
-        OCK_SYSLOG(LOG_ERR, "%s: Failed to get the control points rc=0x%lx\n",
8520e9
-                   __func__, rc);
8520e9
-        goto error;
8520e9
-    }
8520e9
-
8520e9
     /* create an AES key needed for importing keys
8520e9
      * (encrypt by wrap_key and m_UnwrapKey by wrap key)
8520e9
      */
8520e9
@@ -2600,10 +2654,14 @@ CK_RV ep11tok_final(STDLL_TokData_t * tokdata)
8520e9
     TRACE_INFO("ep11 %s running\n", __func__);
8520e9
 
8520e9
     if (ep11_data != NULL) {
8520e9
-        if (dll_m_rm_module != NULL)
8520e9
-            dll_m_rm_module(NULL, ep11_data->target);
8520e9
+        if (ep11_data->target_info != NULL) {
8520e9
+            if (dll_m_rm_module != NULL)
8520e9
+                dll_m_rm_module(NULL, ep11_data->target_info->target);
8520e9
+            free_card_versions(ep11_data->target_info->card_versions);
8520e9
+            free((void* )ep11_data->target_info);
8520e9
+        }
8520e9
+        pthread_rwlock_destroy(&ep11_data->target_rwlock);
8520e9
         free_cp_config(ep11_data->cp_config);
8520e9
-        free_card_versions(ep11_data->card_versions);
8520e9
         free(ep11_data);
8520e9
         tokdata->private_data = NULL;
8520e9
     }
8520e9
@@ -2619,7 +2677,6 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess,
8520e9
                              CK_BYTE *spki, CK_ULONG spki_len,
8520e9
                              CK_BYTE *maced_spki, CK_ULONG *maced_spki_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     unsigned char *ep11_pin_blob = NULL;
8520e9
     CK_ULONG ep11_pin_blob_len = 0;
8520e9
     ep11_session_t *ep11_session = (ep11_session_t *) sess->private_data;
8520e9
@@ -2712,11 +2769,11 @@ static CK_RV make_maced_spki(STDLL_TokData_t *tokdata, SESSION * sess,
8520e9
     ep11_get_pin_blob(ep11_session, object_is_session_object(pub_key_obj),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_UnwrapKey(spki, spki_len, NULL, 0, NULL, 0,
8520e9
                              ep11_pin_blob, ep11_pin_blob_len, &mech,
8520e9
                              p_attrs, attrs_len, maced_spki, maced_spki_len,
8520e9
-                             csum, &cslen, ep11_data->target);
8520e9
+                             csum, &cslen, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -2870,11 +2927,11 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         }
8520e9
 
8520e9
         /* encrypt */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                      ep11_data->raw2key_wrap_blob_l, &mech_w,
8520e9
                                      data, data_len, cipher, &cipher_l,
8520e9
-                                     ep11_data->target);
8520e9
+                                     target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n",
8520e9
@@ -2901,12 +2958,12 @@ static CK_RV import_RSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         /* calls the card, it decrypts the private RSA key,
8520e9
          * reads its BER format and builds a blob.
8520e9
          */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_UnwrapKey(cipher, cipher_l, ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                                  ep11_pin_blob, ep11_pin_blob_len, &mech_w,
8520e9
                                  new_p_attrs, new_attrs_len, blob, blob_size,
8520e9
-                                 csum, &cslen, ep11_data->target);
8520e9
+                                 csum, &cslen, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         if (rc != CKR_OK) {
8520e9
@@ -3101,11 +3158,11 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         }
8520e9
 
8520e9
         /* encrypt */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                      ep11_data->raw2key_wrap_blob_l,
8520e9
                                      &mech_w, data, data_len,
8520e9
-                                     cipher, &cipher_l, ep11_data->target);
8520e9
+                                     cipher, &cipher_l, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n",
8520e9
@@ -3133,14 +3190,14 @@ static CK_RV import_EC_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         /* calls the card, it decrypts the private EC key,
8520e9
          * reads its BER format and builds a blob.
8520e9
          */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_UnwrapKey(cipher, cipher_l,
8520e9
                                  ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                                  ep11_pin_blob,
8520e9
                                  ep11_pin_blob_len, &mech_w,
8520e9
                                  new_p_attrs, new_attrs_len, blob,
8520e9
-                                 blob_size, csum, &cslen, ep11_data->target);
8520e9
+                                 blob_size, csum, &cslen, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         if (rc != CKR_OK) {
8520e9
@@ -3295,11 +3352,11 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         }
8520e9
 
8520e9
         /* encrypt */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                      ep11_data->raw2key_wrap_blob_l,
8520e9
                                      &mech_w, data, data_len,
8520e9
-                                     cipher, &cipher_l, ep11_data->target);
8520e9
+                                     cipher, &cipher_l, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
 
8520e9
@@ -3327,14 +3384,14 @@ static CK_RV import_DSA_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         /* calls the card, it decrypts the private EC key,
8520e9
          * reads its BER format and builds a blob.
8520e9
          */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_UnwrapKey(cipher, cipher_l,
8520e9
                                  ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                                  ep11_pin_blob,
8520e9
                                  ep11_pin_blob_len, &mech_w,
8520e9
                                  new_p_attrs, new_attrs_len, blob,
8520e9
-                                 blob_size, csum, &cslen, ep11_data->target);
8520e9
+                                 blob_size, csum, &cslen, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         if (rc != CKR_OK) {
8520e9
@@ -3478,11 +3535,11 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         }
8520e9
 
8520e9
         /* encrypt */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                      ep11_data->raw2key_wrap_blob_l,
8520e9
                                      &mech_w, data, data_len,
8520e9
-                                     cipher, &cipher_l, ep11_data->target);
8520e9
+                                     cipher, &cipher_l, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n",
8520e9
@@ -3509,14 +3566,14 @@ static CK_RV import_DH_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         /* calls the card, it decrypts the private EC key,
8520e9
          * reads its BER format and builds a blob.
8520e9
          */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_UnwrapKey(cipher, cipher_l,
8520e9
                                  ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                                  ep11_pin_blob,
8520e9
                                  ep11_pin_blob_len, &mech_w,
8520e9
                                  new_p_attrs, new_attrs_len, blob,
8520e9
-                                 blob_size, csum, &cslen, ep11_data->target);
8520e9
+                                 blob_size, csum, &cslen, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         if (rc != CKR_OK) {
8520e9
@@ -3666,11 +3723,11 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         }
8520e9
 
8520e9
         /* encrypt */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptSingle(ep11_data->raw2key_wrap_blob,
8520e9
                                      ep11_data->raw2key_wrap_blob_l,
8520e9
                                      &mech_w, data, data_len,
8520e9
-                                     cipher, &cipher_l, ep11_data->target);
8520e9
+                                     cipher, &cipher_l, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         TRACE_INFO("%s wrapping wrap key rc=0x%lx cipher_l=0x%lx\n",
8520e9
@@ -3699,14 +3756,14 @@ static CK_RV import_IBM_Dilithium_key(STDLL_TokData_t * tokdata, SESSION * sess,
8520e9
         /* calls the card, it decrypts the private Dilithium key,
8520e9
          * reads its BER format and builds a blob.
8520e9
          */
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_UnwrapKey(cipher, cipher_l,
8520e9
                                  ep11_data->raw2key_wrap_blob,
8520e9
                                  ep11_data->raw2key_wrap_blob_l, NULL, ~0,
8520e9
                                  ep11_pin_blob,
8520e9
                                  ep11_pin_blob_len, &mech_w,
8520e9
                                  new_p_attrs, new_attrs_len, blob,
8520e9
-                                 blob_size, csum, &cslen, ep11_data->target);
8520e9
+                                 blob_size, csum, &cslen, target_info->target);
8520e9
         RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
         if (rc != CKR_OK) {
8520e9
@@ -3884,7 +3941,6 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                            CK_MECHANISM_PTR mech, CK_ATTRIBUTE_PTR attrs,
8520e9
                            CK_ULONG attrs_len, CK_OBJECT_HANDLE_PTR handle)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_BYTE blob[MAX_BLOBSIZE];
8520e9
     size_t blobsize = sizeof(blob);
8520e9
     CK_BYTE csum[MAX_CSUMSIZE];
8520e9
@@ -3936,10 +3992,10 @@ CK_RV ep11tok_generate_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_GenerateKey(mech, new_attrs2, new_attrs2_len, ep11_pin_blob,
8520e9
                                ep11_pin_blob_len, blob, &blobsize,
8520e9
-                               csum, &csum_len, ep11_data->target);
8520e9
+                               csum, &csum_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4354,6 +4410,7 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
     size_t state_len = MAX(MAX_DIGEST_STATE_BYTES, sizeof(libica_sha_context_t));
8520e9
     CK_BYTE *state;
8520e9
     libica_sha_context_t *libica_ctx;
8520e9
+    ep11_target_info_t* target_info;
8520e9
 
8520e9
     state = calloc(state_len, 1); /* freed by dig_mgr.c */
8520e9
     if (!state) {
8520e9
@@ -4361,15 +4418,21 @@ CK_RV token_specific_sha_init(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
         return CKR_HOST_MEMORY;
8520e9
     }
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     if (ep11tok_libica_digest_available(ep11_data, mech->mechanism)) {
8520e9
         libica_ctx = (libica_sha_context_t *)state;
8520e9
         state_len = sizeof(libica_sha_context_t);
8520e9
         libica_ctx->first = CK_TRUE;
8520e9
         rc = get_sha_block_size(mech->mechanism, &libica_ctx->block_size);
8520e9
     } else {
8520e9
-        rc = dll_m_DigestInit(state, &state_len, mech, ep11_data->target);
8520e9
+        rc = dll_m_DigestInit(state, &state_len, mech, target_info->target);
8520e9
     }
8520e9
 
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
         TRACE_ERROR("%s rc=0x%lx\n", __func__, rc);
8520e9
@@ -4399,6 +4462,11 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) {
8520e9
         rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism,
8520e9
@@ -4408,7 +4476,7 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
                                    SHA_MSG_PART_ONLY);
8520e9
     } else {
8520e9
         rc = dll_m_Digest(c->context, c->context_len, in_data, in_data_len,
8520e9
-                          out_data, out_data_len, ep11_data->target);
8520e9
+                          out_data, out_data_len, target_info->target);
8520e9
     }
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -4417,6 +4485,8 @@ CK_RV token_specific_sha(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
     } else {
8520e9
         TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
8520e9
     }
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -4430,6 +4500,11 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
     CK_ULONG out_len = sizeof(temp_out);
8520e9
     CK_ULONG len;
8520e9
     CK_RV rc = CKR_OK;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) {
8520e9
         if (libica_ctx->offset > 0 || in_data_len < libica_ctx->block_size) {
8520e9
@@ -4479,7 +4554,7 @@ CK_RV token_specific_sha_update(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
         }
8520e9
     } else {
8520e9
         rc = dll_m_DigestUpdate(c->context, c->context_len,
8520e9
-                                in_data, in_data_len, ep11_data->target);
8520e9
+                                in_data, in_data_len, target_info->target);
8520e9
     }
8520e9
 
8520e9
 out:
8520e9
@@ -4489,6 +4564,8 @@ out:
8520e9
     } else {
8520e9
         TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
8520e9
     }
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -4499,6 +4576,11 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     libica_sha_context_t *libica_ctx = (libica_sha_context_t *)c->context;
8520e9
     CK_RV rc;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     if (ep11tok_libica_digest_available(ep11_data, c->mech.mechanism)) {
8520e9
         rc = ep11tok_libica_digest(ep11_data, c->mech.mechanism,
8520e9
@@ -4510,7 +4592,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
                                         SHA_MSG_PART_FINAL);
8520e9
     } else {
8520e9
         rc = dll_m_DigestFinal(c->context, c->context_len,
8520e9
-                               out_data, out_data_len, ep11_data->target);
8520e9
+                               out_data, out_data_len, target_info->target);
8520e9
     }
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -4520,6 +4602,7 @@ CK_RV token_specific_sha_final(STDLL_TokData_t * tokdata, DIGEST_CONTEXT * c,
8520e9
         TRACE_INFO("%s rc=0x%lx\n", __func__, rc);
8520e9
     }
8520e9
 
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -4528,7 +4611,6 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
                               CK_BYTE *out_data, CK_ULONG *out_data_len,
8520e9
                               OBJECT *key_obj)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
@@ -4544,9 +4626,9 @@ CK_RV token_specific_rsa_sign(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     mech.pParameter = NULL;
8520e9
     mech.ulParameterLen = 0;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len,
8520e9
-                          out_data, out_data_len, ep11_data->target);
8520e9
+                          out_data, out_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4563,7 +4645,6 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
                                 CK_BYTE *signature, CK_ULONG sig_len,
8520e9
                                 OBJECT *key_obj)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *spki;
8520e9
     size_t spki_len = 0;
8520e9
@@ -4579,9 +4660,9 @@ CK_RV token_specific_rsa_verify(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     mech.pParameter = NULL;
8520e9
     mech.ulParameterLen = 0;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len,
8520e9
-                            signature, sig_len, ep11_data->target);
8520e9
+                            signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4598,7 +4679,6 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
                                   CK_BYTE *in_data, CK_ULONG in_data_len,
8520e9
                                   CK_BYTE *sig, CK_ULONG *sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
@@ -4616,9 +4696,9 @@ CK_RV token_specific_rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     mech.ulParameterLen = ctx->mech.ulParameterLen;
8520e9
     mech.pParameter = ctx->mech.pParameter;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len,
8520e9
-                          sig, sig_len, ep11_data->target);
8520e9
+                          sig, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4638,7 +4718,6 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
                                     CK_BYTE *in_data, CK_ULONG in_data_len,
8520e9
                                     CK_BYTE *signature, CK_ULONG sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *spki;
8520e9
     size_t spki_len = 0;
8520e9
@@ -4656,9 +4735,9 @@ CK_RV token_specific_rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     mech.ulParameterLen = ctx->mech.ulParameterLen;
8520e9
     mech.pParameter = ctx->mech.pParameter;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len,
8520e9
-                            signature, sig_len, ep11_data->target);
8520e9
+                            signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4678,7 +4757,6 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION  *session,
8520e9
                              CK_BYTE *out_data, CK_ULONG *out_data_len,
8520e9
                              OBJECT *key_obj )
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &(session->sign_ctx);
8520e9
     CK_RV rc;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -4707,9 +4785,9 @@ CK_RV token_specific_ec_sign(STDLL_TokData_t *tokdata, SESSION  *session,
8520e9
     mech.pParameter = NULL;
8520e9
     mech.ulParameterLen = 0;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_SignSingle(keyblob, keyblobsize, &mech, in_data, in_data_len,
8520e9
-                          out_data, out_data_len, ep11_data->target);
8520e9
+                          out_data, out_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4728,7 +4806,6 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION  *session,
8520e9
                                CK_BYTE *out_data, CK_ULONG out_data_len,
8520e9
                                OBJECT *key_obj )
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &(session->verify_ctx);
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *spki;
8520e9
@@ -4757,9 +4834,9 @@ CK_RV token_specific_ec_verify(STDLL_TokData_t *tokdata, SESSION  *session,
8520e9
     mech.pParameter = NULL;
8520e9
     mech.ulParameterLen = 0;
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_VerifySingle(spki, spki_len, &mech, in_data, in_data_len,
8520e9
-                            out_data, out_data_len, ep11_data->target);
8520e9
+                            out_data, out_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4784,7 +4861,6 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata,
8520e9
                                       CK_BYTE *in_data, CK_ULONG in_data_len,
8520e9
                                       CK_BYTE *out_data, CK_ULONG *out_data_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *decr_key, *encr_key;
8520e9
     size_t decr_key_len = 0, encr_key_len = 0;
8520e9
@@ -4813,10 +4889,10 @@ CK_RV token_specific_reencrypt_single(STDLL_TokData_t *tokdata,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_ReencryptSingle(decr_key, decr_key_len, encr_key, encr_key_len,
8520e9
                                decr_mech, encr_mech, in_data, in_data_len,
8520e9
-                               out_data, out_data_len, ep11_data->target);
8520e9
+                               out_data, out_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -4892,7 +4968,6 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                          CK_OBJECT_HANDLE_PTR handle, CK_ATTRIBUTE_PTR attrs,
8520e9
                          CK_ULONG attrs_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *keyblob;
8520e9
     size_t keyblobsize;
8520e9
@@ -4920,6 +4995,8 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_ULONG privlen;
8520e9
     int curve_type;
8520e9
     CK_BBOOL allocated = FALSE;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+    CK_ULONG used_firmware_API_version;
8520e9
 
8520e9
     memset(newblob, 0, sizeof(newblob));
8520e9
 
8520e9
@@ -5009,7 +5086,15 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
          * then we can pass the mechanism parameters as-is, otherwise we still
8520e9
          * need to use the old way.
8520e9
          */
8520e9
-        if (ep11_data->used_firmware_API_version <= 2) {
8520e9
+        target_info = get_target_info(tokdata);
8520e9
+        if (target_info == NULL)
8520e9
+            return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
+        used_firmware_API_version = target_info->used_firmware_API_version;
8520e9
+
8520e9
+        put_target_info(tokdata, target_info);
8520e9
+
8520e9
+        if (used_firmware_API_version <= 2) {
8520e9
             if (ecdh1_parms->kdf != CKD_NULL) {
8520e9
                 TRACE_ERROR("%s KDF for CKM_ECDH1_DERIVE not supported: %lu\n",
8520e9
                             __func__, ecdh1_parms->kdf);
8520e9
@@ -5133,11 +5218,11 @@ CK_RV ep11tok_derive_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     ep11_get_pin_blob(ep11_session, ep11_is_session_object(attrs, attrs_len),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc =
8520e9
         dll_m_DeriveKey(mech, new_attrs2, new_attrs2_len, keyblob, keyblobsize,
8520e9
                         NULL, 0, ep11_pin_blob, ep11_pin_blob_len, newblob,
8520e9
-                        &newblobsize, csum, &cslen, ep11_data->target);
8520e9
+                        &newblobsize, csum, &cslen, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -5231,7 +5316,6 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                  CK_ULONG ulPrivateKeyAttributeCount,
8520e9
                                  CK_SESSION_HANDLE h)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE publblob[MAX_BLOBSIZE];
8520e9
     size_t publblobsize = sizeof(publblob);
8520e9
@@ -5418,13 +5502,13 @@ static CK_RV dh_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                                  ulPrivateKeyAttributeCount)),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_GenerateKeyPair(pMechanism,
8520e9
                                    new_publ_attrs, new_publ_attrs_len,
8520e9
                                    new_priv_attrs, new_priv_attrs_len,
8520e9
                                    ep11_pin_blob, ep11_pin_blob_len,
8520e9
                                    privblob, &privblobsize,
8520e9
-                                   publblob, &publblobsize, ep11_data->target);
8520e9
+                                   publblob, &publblobsize, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -5543,7 +5627,6 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                   CK_ULONG ulPrivateKeyAttributeCount,
8520e9
                                   CK_SESSION_HANDLE h)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE publblob[MAX_BLOBSIZE];
8520e9
     size_t publblobsize = sizeof(publblob);
8520e9
@@ -5752,13 +5835,13 @@ static CK_RV dsa_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                                  ulPrivateKeyAttributeCount)),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_GenerateKeyPair(pMechanism,
8520e9
                                    new_publ_attrs2, new_publ_attrs2_len,
8520e9
                                    new_priv_attrs2, new_priv_attrs2_len,
8520e9
                                    ep11_pin_blob, ep11_pin_blob_len, privblob,
8520e9
                                    &privblobsize, publblob, &publblobsize,
8520e9
-                                   ep11_data->target);
8520e9
+                                   target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -5866,7 +5949,6 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                      CK_ULONG ulPrivateKeyAttributeCount,
8520e9
                                      CK_SESSION_HANDLE h)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_ATTRIBUTE *attr = NULL;
8520e9
     CK_ATTRIBUTE *n_attr = NULL;
8520e9
@@ -5967,13 +6049,13 @@ static CK_RV rsa_ec_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                                  ulPrivateKeyAttributeCount)),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_GenerateKeyPair(pMechanism,
8520e9
                                    new_publ_attrs2, new_publ_attrs2_len,
8520e9
                                    new_priv_attrs2, new_priv_attrs2_len,
8520e9
                                    ep11_pin_blob, ep11_pin_blob_len,
8520e9
                                    privkey_blob, &privkey_blob_len, spki,
8520e9
-                                   &spki_len, ep11_data->target);
8520e9
+                                   &spki_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, sess);
8520e9
@@ -6225,7 +6307,6 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                      CK_ULONG ulPrivateKeyAttributeCount,
8520e9
                                      CK_SESSION_HANDLE h)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_ATTRIBUTE *attr = NULL;
8520e9
     CK_BYTE privkey_blob[MAX_BLOBSIZE];
8520e9
@@ -6308,13 +6389,13 @@ static CK_RV ibm_dilithium_generate_keypair(STDLL_TokData_t * tokdata,
8520e9
                                                  ulPrivateKeyAttributeCount)),
8520e9
                       &ep11_pin_blob, &ep11_pin_blob_len);
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_GenerateKeyPair(pMechanism,
8520e9
                                    new_publ_attrs2, new_publ_attrs2_len,
8520e9
                                    new_priv_attrs2, new_priv_attrs2_len,
8520e9
                                    ep11_pin_blob, ep11_pin_blob_len,
8520e9
                                    privkey_blob, &privkey_blob_len, spki,
8520e9
-                                   &spki_len, ep11_data->target);
8520e9
+                                   &spki_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, sess)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, sess);
8520e9
@@ -6914,7 +6995,6 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                         CK_MECHANISM * mech, CK_BBOOL recover_mode,
8520e9
                         CK_OBJECT_HANDLE key)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
@@ -6980,9 +7060,9 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_SignInit(ep11_sign_state, &ep11_sign_state_l,
8520e9
-                            mech, keyblob, keyblobsize, ep11_data->target);
8520e9
+                            mech, keyblob, keyblobsize, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7017,7 +7097,6 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                    CK_ULONG in_data_len, CK_BYTE * signature,
8520e9
                    CK_ULONG * sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7049,9 +7128,9 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_Sign(ctx->context, ctx->context_len, in_data, in_data_len,
8520e9
-                        signature, sig_len, ep11_data->target);
8520e9
+                        signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7073,7 +7152,6 @@ done:
8520e9
 CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                           CK_BYTE * in_data, CK_ULONG in_data_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7095,9 +7173,9 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data,
8520e9
-                              in_data_len, ep11_data->target);
8520e9
+                              in_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7120,7 +7198,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                          CK_BBOOL length_only, CK_BYTE * signature,
8520e9
                          CK_ULONG * sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->sign_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7139,9 +7216,9 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len,
8520e9
-                             ep11_data->target);
8520e9
+                             target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7169,7 +7246,6 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
 
8520e9
     UNUSED(length_only);
8520e9
 
8520e9
@@ -7186,9 +7262,9 @@ CK_RV ep11tok_sign_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_SignSingle(keyblob, keyblobsize, mech, in_data, in_data_len,
8520e9
-                          signature, sig_len, ep11_data->target);
8520e9
+                          signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -7209,7 +7285,6 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                           CK_MECHANISM * mech, CK_BBOOL recover_mode,
8520e9
                           CK_OBJECT_HANDLE key)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *spki;
8520e9
     size_t spki_len = 0;
8520e9
@@ -7285,9 +7360,9 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_VerifyInit(ep11_sign_state, &ep11_sign_state_l, mech,
8520e9
-                              spki, spki_len, ep11_data->target);
8520e9
+                              spki, spki_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7320,7 +7395,6 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                      CK_BYTE * in_data, CK_ULONG in_data_len,
8520e9
                      CK_BYTE * signature, CK_ULONG sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7353,9 +7427,9 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_Verify(ctx->context, ctx->context_len, in_data, in_data_len,
8520e9
-                          signature, sig_len, ep11_data->target);
8520e9
+                          signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7377,7 +7451,6 @@ done:
8520e9
 CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                             CK_BYTE * in_data, CK_ULONG in_data_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7399,9 +7472,9 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data,
8520e9
-                                in_data_len, ep11_data->target);
8520e9
+                                in_data_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7423,7 +7496,6 @@ done:
8520e9
 CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                            CK_BYTE * signature, CK_ULONG sig_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     SIGN_VERIFY_CONTEXT *ctx = &session->verify_ctx;
8520e9
     size_t keyblobsize = 0;
8520e9
@@ -7442,9 +7514,9 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature,
8520e9
-                               sig_len, ep11_data->target);
8520e9
+                               sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7471,7 +7543,6 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     CK_BYTE *spki;
8520e9
     size_t spki_len = 0;
8520e9
     OBJECT *key_obj = NULL;
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
 
8520e9
     rc = h_opaque_2_blob(tokdata, key, &spki, &spki_len, &key_obj, READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7495,9 +7566,9 @@ CK_RV ep11tok_verify_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_VerifySingle(spki, spki_len, mech, in_data, in_data_len,
8520e9
-                            signature, sig_len, ep11_data->target);
8520e9
+                            signature, sig_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -7517,7 +7588,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                             CK_BYTE_PTR output_part,
8520e9
                             CK_ULONG_PTR p_output_part_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->decr_ctx;
8520e9
     CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7538,10 +7608,10 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_DecryptFinal(ctx->context, ctx->context_len,
8520e9
                                 output_part, p_output_part_len,
8520e9
-                                ep11_data->target);
8520e9
+                                target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7564,7 +7634,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                       CK_BYTE_PTR input_data, CK_ULONG input_data_len,
8520e9
                       CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->decr_ctx;
8520e9
     CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7586,10 +7655,10 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data,
8520e9
                            input_data_len, output_data, p_output_data_len,
8520e9
-                           ep11_data->target);
8520e9
+                           target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7613,7 +7682,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                              CK_BYTE_PTR output_part,
8520e9
                              CK_ULONG_PTR p_output_part_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->decr_ctx;
8520e9
     CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7640,10 +7708,10 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len,
8520e9
                                  input_part, input_part_len, output_part,
8520e9
-                                 p_output_part_len, ep11_data->target);
8520e9
+                                 p_output_part_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7671,7 +7739,6 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
 
8520e9
     UNUSED(length_only);
8520e9
 
8520e9
@@ -7688,10 +7755,10 @@ CK_RV ep11tok_decrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_DecryptSingle(keyblob, keyblobsize, mech, input_data,
8520e9
                              input_data_len, output_data, p_output_data_len,
8520e9
-                             ep11_data->target);
8520e9
+                             target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -7711,7 +7778,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                             CK_BYTE_PTR output_part,
8520e9
                             CK_ULONG_PTR p_output_part_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->encr_ctx;
8520e9
     CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7732,10 +7798,10 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_EncryptFinal(ctx->context, ctx->context_len,
8520e9
                                 output_part, p_output_part_len,
8520e9
-                                ep11_data->target);
8520e9
+                                target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7758,7 +7824,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                       CK_BYTE_PTR input_data, CK_ULONG input_data_len,
8520e9
                       CK_BYTE_PTR output_data, CK_ULONG_PTR p_output_data_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->encr_ctx;
8520e9
     CK_BBOOL length_only = (output_data == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7780,10 +7845,10 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data,
8520e9
                            input_data_len, output_data, p_output_data_len,
8520e9
-                           ep11_data->target);
8520e9
+                           target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7807,7 +7872,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                              CK_BYTE_PTR output_part,
8520e9
                              CK_ULONG_PTR p_output_part_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     ENCR_DECR_CONTEXT *ctx = &session->encr_ctx;
8520e9
     CK_BBOOL length_only = (output_part == NULL ? CK_TRUE : CK_FALSE);
8520e9
@@ -7834,10 +7898,10 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len,
8520e9
                                  input_part, input_part_len, output_part,
8520e9
-                                 p_output_part_len, ep11_data->target);
8520e9
+                                 p_output_part_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7865,7 +7929,6 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
     size_t keyblobsize = 0;
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
 
8520e9
     UNUSED(length_only);
8520e9
 
8520e9
@@ -7893,10 +7956,10 @@ CK_RV ep11tok_encrypt_single(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
     rc = dll_m_EncryptSingle(keyblob, keyblobsize, mech, input_data,
8520e9
                              input_data_len, output_data, p_output_data_len,
8520e9
-                             ep11_data->target);
8520e9
+                             target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -7916,7 +7979,6 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                                   CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key,
8520e9
                                   int op)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = CKR_OK;
8520e9
     CK_BYTE *blob;
8520e9
     size_t blob_len = 0;
8520e9
@@ -7979,9 +8041,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
 
8520e9
     if (op == DECRYPT) {
8520e9
         ENCR_DECR_CONTEXT *ctx = &session->decr_ctx;
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_DecryptInit(ep11_state, &ep11_state_l, mech, blob,
8520e9
-                                   blob_len, ep11_data->target);
8520e9
+                                   blob_len, target_info->target);
8520e9
         RETRY_END(rc, tokdata, session)
8520e9
         ctx->key = key;
8520e9
         ctx->active = TRUE;
8520e9
@@ -8012,9 +8074,9 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
             goto error;
8520e9
         }
8520e9
 
8520e9
-        RETRY_START
8520e9
+        RETRY_START(rc, tokdata)
8520e9
             rc = dll_m_EncryptInit(ep11_state, &ep11_state_l, mech, blob,
8520e9
-                                   blob_len, ep11_data->target);
8520e9
+                                   blob_len, target_info->target);
8520e9
         RETRY_END(rc, tokdata, session)
8520e9
         ctx->key = key;
8520e9
         ctx->active = TRUE;
8520e9
@@ -8092,7 +8154,6 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                        CK_OBJECT_HANDLE key, CK_BYTE_PTR wrapped_key,
8520e9
                        CK_ULONG_PTR p_wrapped_key_len)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *wrapping_blob;
8520e9
     size_t wrapping_blob_len;
8520e9
@@ -8192,11 +8253,11 @@ CK_RV ep11tok_wrap_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
      * (wrapping blob). The wrapped key can be processed by any PKCS11
8520e9
      * implementation.
8520e9
      */
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc =
8520e9
         dll_m_WrapKey(wrap_target_blob, wrap_target_blob_len, wrapping_blob,
8520e9
                       wrapping_blob_len, sign_blob, sign_blob_len, mech,
8520e9
-                      wrapped_key, p_wrapped_key_len, ep11_data->target);
8520e9
+                      wrapped_key, p_wrapped_key_len, target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -8228,7 +8289,6 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
                          CK_OBJECT_HANDLE wrapping_key,
8520e9
                          CK_OBJECT_HANDLE_PTR p_key)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     CK_BYTE *wrapping_blob, *temp;
8520e9
     size_t wrapping_blob_len;
8520e9
@@ -8388,13 +8448,13 @@ CK_RV ep11tok_unwrap_key(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     /* we need a blob for the new key created by unwrapping,
8520e9
      * the wrapped key comes in BER
8520e9
      */
8520e9
-    RETRY_START
8520e9
+    RETRY_START(rc, tokdata)
8520e9
         rc = dll_m_UnwrapKey(wrapped_key, wrapped_key_len, wrapping_blob,
8520e9
                              wrapping_blob_len, verifyblob, verifyblobsize,
8520e9
                              ep11_pin_blob,
8520e9
                              ep11_pin_blob_len, mech, new_attrs2, new_attrs2_len,
8520e9
                              keyblob, &keyblobsize, csum, &cslen,
8520e9
-                             ep11_data->target);
8520e9
+                             target_info->target);
8520e9
     RETRY_END(rc, tokdata, session)
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -8657,21 +8717,25 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
8520e9
                                  CK_MECHANISM_TYPE_PTR pMechanismList,
8520e9
                                  CK_ULONG_PTR pulCount)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc = 0;
8520e9
     CK_ULONG counter = 0, size = 0;
8520e9
     CK_MECHANISM_TYPE_PTR mlist = NULL;
8520e9
     CK_ULONG i;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     /* size querry */
8520e9
     if (pMechanismList == NULL) {
8520e9
         rc = dll_m_GetMechanismList(0, pMechanismList, pulCount,
8520e9
-                                    ep11_data->target);
8520e9
+                                    target_info->target);
8520e9
         if (rc != CKR_OK) {
8520e9
             rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
             TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #1\n",
8520e9
                         __func__, rc);
8520e9
-            return rc;
8520e9
+            goto out;
8520e9
         }
8520e9
 
8520e9
         /* adjust the size according to the ban list,
8520e9
@@ -8693,16 +8757,16 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
8520e9
                                     sizeof(CK_MECHANISM_TYPE) * counter);
8520e9
             if (!mlist) {
8520e9
                 TRACE_ERROR("%s Memory allocation failed\n", __func__);
8520e9
-                return CKR_HOST_MEMORY;
8520e9
+                rc = CKR_HOST_MEMORY;
8520e9
+                goto out;
8520e9
             }
8520e9
-            rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target);
8520e9
+            rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target);
8520e9
             if (rc != CKR_OK) {
8520e9
                 rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
                 TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #2\n",
8520e9
                             __func__, rc);
8520e9
-                free(mlist);
8520e9
                 if (rc != CKR_BUFFER_TOO_SMALL)
8520e9
-                    return rc;
8520e9
+                    goto out;
8520e9
             }
8520e9
         } while (rc == CKR_BUFFER_TOO_SMALL);
8520e9
 
8520e9
@@ -8722,12 +8786,12 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
8520e9
          * that comes as parameter, this is a 'reduced size',
8520e9
          * ep11 would complain about insufficient list size
8520e9
          */
8520e9
-        rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target);
8520e9
+        rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target);
8520e9
         if (rc != CKR_OK) {
8520e9
             rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
             TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #3\n",
8520e9
                         __func__, rc);
8520e9
-            return rc;
8520e9
+            goto out;
8520e9
         }
8520e9
 
8520e9
         /*
8520e9
@@ -8744,17 +8808,17 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
8520e9
                                     sizeof(CK_MECHANISM_TYPE) * counter);
8520e9
             if (!mlist) {
8520e9
                 TRACE_ERROR("%s Memory allocation failed\n", __func__);
8520e9
-                return CKR_HOST_MEMORY;
8520e9
+                rc = CKR_HOST_MEMORY;
8520e9
+                goto out;
8520e9
             }
8520e9
             /* all the card has */
8520e9
-            rc = dll_m_GetMechanismList(0, mlist, &counter, ep11_data->target);
8520e9
+            rc = dll_m_GetMechanismList(0, mlist, &counter, target_info->target);
8520e9
             if (rc != CKR_OK) {
8520e9
                 rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
                 TRACE_ERROR("%s bad rc=0x%lx from m_GetMechanismList() #4\n",
8520e9
                             __func__, rc);
8520e9
-                free(mlist);
8520e9
                 if (rc != CKR_BUFFER_TOO_SMALL)
8520e9
-                    return rc;
8520e9
+                    goto out;
8520e9
             }
8520e9
         } while (rc == CKR_BUFFER_TOO_SMALL);
8520e9
 
8520e9
@@ -8775,8 +8839,10 @@ CK_RV ep11tok_get_mechanism_list(STDLL_TokData_t * tokdata,
8520e9
             rc = CKR_BUFFER_TOO_SMALL;
8520e9
     }
8520e9
 
8520e9
+out:
8520e9
     if (mlist)
8520e9
         free(mlist);
8520e9
+    put_target_info(tokdata, target_info);
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
@@ -8790,6 +8856,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
     CK_BBOOL found = FALSE;
8520e9
     CK_ULONG i;
8520e9
     int status;
8520e9
+    CK_RV rc = CKR_OK;
8520e9
+    ep11_target_info_t* target_info;
8520e9
 
8520e9
     for (i = 0; i < supported_mech_list_len; i++) {
8520e9
         if (type == ep11_supported_mech_list[i]) {
8520e9
@@ -8804,13 +8872,18 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         return CKR_MECHANISM_INVALID;
8520e9
     }
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     if (check_cps_for_mechanism(ep11_data->cp_config,
8520e9
-                                type, ep11_data->control_points,
8520e9
-                                ep11_data->control_points_len,
8520e9
-                                ep11_data->max_control_point_index) != CKR_OK) {
8520e9
+                                type, target_info->control_points,
8520e9
+                                target_info->control_points_len,
8520e9
+                                target_info->max_control_point_index) != CKR_OK) {
8520e9
         TRACE_INFO("%s Mech '%s' banned due to control point\n",
8520e9
                                    __func__, ep11_get_ckm(type));
8520e9
-        return CKR_MECHANISM_INVALID;
8520e9
+        rc = CKR_MECHANISM_INVALID;
8520e9
+        goto out;
8520e9
     }
8520e9
 
8520e9
     switch(type) {
8520e9
@@ -8840,14 +8913,17 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (status == -1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                         __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
 
8520e9
     case CKM_RSA_PKCS_OAEP:
8520e9
         /* CKM_RSA_PKCS_OAEP is not supported with EP11 host library <= 1.3 */
8520e9
-        if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0)
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+        if (compare_ck_version(&ep11_data->ep11_lib_version, &ver1_3) <= 0) {
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
+        }
8520e9
         break;
8520e9
 
8520e9
     case CKM_IBM_SHA3_224:
8520e9
@@ -8863,7 +8939,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (status != 1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
 
8520e9
@@ -8876,7 +8953,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (status != 1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
 
8520e9
@@ -8887,7 +8965,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) < 0) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to host library version\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
 
8520e9
         status = check_required_versions(tokdata, edwards_req_versions,
8520e9
@@ -8895,7 +8974,8 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (status != 1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
 
8520e9
@@ -8903,14 +8983,16 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
         if (compare_ck_version(&ep11_data->ep11_lib_version, &ver3) <= 0) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to host library version\n",
8520e9
                                      __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         status = check_required_versions(tokdata, ibm_dilithium_req_versions,
8520e9
                                          NUM_DILITHIUM_REQ);
8520e9
         if (status != 1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
 
8520e9
@@ -8919,19 +9001,23 @@ CK_RV ep11tok_is_mechanism_supported(STDLL_TokData_t *tokdata,
8520e9
             TRACE_INFO("%s Mech '%s' banned due to host library version\n",
8520e9
                                      __func__, ep11_get_ckm(type));
8520e9
 
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         status = check_required_versions(tokdata, ibm_cpacf_wrap_req_versions,
8520e9
                                          NUM_CPACF_WRAP_REQ);
8520e9
         if (status != 1) {
8520e9
             TRACE_INFO("%s Mech '%s' banned due to mixed firmware versions\n",
8520e9
                                     __func__, ep11_get_ckm(type));
8520e9
-            return CKR_MECHANISM_INVALID;
8520e9
+            rc = CKR_MECHANISM_INVALID;
8520e9
+            goto out;
8520e9
         }
8520e9
         break;
8520e9
     }
8520e9
 
8520e9
-    return CKR_OK;
8520e9
+out:
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+    return rc;
8520e9
 }
8520e9
 
8520e9
 CK_RV ep11tok_is_mechanism_supported_ex(STDLL_TokData_t *tokdata,
8520e9
@@ -8976,9 +9062,9 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata,
8520e9
                                  CK_MECHANISM_TYPE type,
8520e9
                                  CK_MECHANISM_INFO_PTR pInfo)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_RV rc;
8520e9
     int status;
8520e9
+    ep11_target_info_t* target_info;
8520e9
 
8520e9
     rc = ep11tok_is_mechanism_supported(tokdata, type);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -8987,7 +9073,14 @@ CK_RV ep11tok_get_mechanism_info(STDLL_TokData_t * tokdata,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    rc = dll_m_GetMechanismInfo(0, type, pInfo, ep11_data->target);
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
+    rc = dll_m_GetMechanismInfo(0, type, pInfo, target_info->target);
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
         TRACE_ERROR("%s m_GetMechanismInfo(0x%lx) failed with rc=0x%lx\n",
8520e9
@@ -10265,6 +10358,11 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata,
8520e9
     CK_MECHANISM mech;
8520e9
     CK_ULONG len;
8520e9
     libica_sha_context_t ctx;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     session_id_data.handle = session->handle;
8520e9
     gettimeofday(&session_id_data.timeofday, NULL);
8520e9
@@ -10286,7 +10384,9 @@ static CK_RV generate_ep11_session_id(STDLL_TokData_t * tokdata,
8520e9
         rc = dll_m_DigestSingle(&mech, (CK_BYTE_PTR)&session_id_data,
8520e9
                                 sizeof(session_id_data),
8520e9
                                 ep11_session->session_id, &len,
8520e9
-                                ep11_data->target);
8520e9
+                                target_info->target);
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
 
8520e9
     if (rc != CKR_OK) {
8520e9
         rc = ep11_error_to_pkcs11_error(rc, session);
8520e9
@@ -10964,7 +11064,7 @@ static CK_RV get_card_type(uint_32 adapter, CK_ULONG *type)
8520e9
 
8520e9
 typedef struct query_version
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data;
8520e9
+    ep11_target_info_t *target_info;
8520e9
     CK_CHAR serialNumber[16];
8520e9
     CK_BBOOL first;
8520e9
     CK_BBOOL error;
8520e9
@@ -11005,7 +11105,7 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain,
8520e9
     }
8520e9
 
8520e9
     /* Try to find existing version info for this card type */
8520e9
-    card_version = qv->ep11_data->card_versions;
8520e9
+    card_version = qv->target_info->card_versions;
8520e9
     while (card_version != NULL) {
8520e9
         if (card_version->card_type == card_type)
8520e9
            break;
8520e9
@@ -11050,8 +11150,8 @@ static CK_RV version_query_handler(uint_32 adapter, uint_32 domain,
8520e9
         card_version->firmware_version = xcp_info.firmwareVersion;
8520e9
 #endif
8520e9
 
8520e9
-        card_version->next = qv->ep11_data->card_versions;
8520e9
-        qv->ep11_data->card_versions = card_version;
8520e9
+        card_version->next = qv->target_info->card_versions;
8520e9
+        qv->target_info->card_versions = card_version;
8520e9
     } else {
8520e9
         /*
8520e9
          * Version info for this card type is already available, so check this
8520e9
@@ -11134,23 +11234,16 @@ static CK_RV ep11tok_get_ep11_library_version(CK_VERSION *lib_version)
8520e9
     return CKR_OK;
8520e9
 }
8520e9
 
8520e9
-static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata)
8520e9
+static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata,
8520e9
+                                      ep11_target_info_t *target_info)
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     ep11_card_version_t *card_version;
8520e9
     query_version_t qv;
8520e9
     CK_RV rc;
8520e9
 
8520e9
-    rc = ep11tok_get_ep11_library_version(&ep11_data->ep11_lib_version);
8520e9
-    if (rc != CKR_OK)
8520e9
-        return rc;
8520e9
-
8520e9
-    TRACE_INFO("%s Host library version: %d.%d\n", __func__,
8520e9
-               ep11_data->ep11_lib_version.major,
8520e9
-               ep11_data->ep11_lib_version.minor);
8520e9
-
8520e9
     memset(&qv, 0, sizeof(qv));
8520e9
-    qv.ep11_data = ep11_data;
8520e9
+    qv.target_info = target_info;
8520e9
     qv.first = TRUE;
8520e9
 
8520e9
     rc = handle_all_ep11_cards(&ep11_data->target_list, version_query_handler,
8520e9
@@ -11169,18 +11262,18 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata)
8520e9
         return CKR_DEVICE_ERROR;
8520e9
     }
8520e9
 
8520e9
-    memcpy(ep11_data->serialNumber, qv.serialNumber,
8520e9
-           sizeof(ep11_data->serialNumber));
8520e9
+    memcpy(target_info->serialNumber, qv.serialNumber,
8520e9
+           sizeof(target_info->serialNumber));
8520e9
 
8520e9
-    TRACE_INFO("%s Serial number: %.16s\n", __func__, ep11_data->serialNumber);
8520e9
+    TRACE_INFO("%s Serial number: %.16s\n", __func__, target_info->serialNumber);
8520e9
 
8520e9
     /* EP11 host lib version <= 2 only support API version 2 */
8520e9
     if (ep11_data->ep11_lib_version.major <= 2)
8520e9
-        ep11_data->used_firmware_API_version = 2;
8520e9
+        target_info->used_firmware_API_version = 2;
8520e9
     else
8520e9
-        ep11_data->used_firmware_API_version = 0;
8520e9
+        target_info->used_firmware_API_version = 0;
8520e9
 
8520e9
-    card_version = ep11_data->card_versions;
8520e9
+    card_version = target_info->card_versions;
8520e9
     while (card_version != NULL) {
8520e9
         TRACE_INFO("%s Card type: CEX%luP\n", __func__,
8520e9
                    card_version->card_type);
8520e9
@@ -11190,19 +11283,19 @@ static CK_RV ep11tok_get_ep11_version(STDLL_TokData_t *tokdata)
8520e9
                 card_version->firmware_version.major,
8520e9
                 card_version->firmware_version.minor);
8520e9
 
8520e9
-        if (ep11_data->used_firmware_API_version == 0)
8520e9
-            ep11_data->used_firmware_API_version =
8520e9
+        if (target_info->used_firmware_API_version == 0)
8520e9
+            target_info->used_firmware_API_version =
8520e9
                                 card_version->firmware_API_version;
8520e9
         else
8520e9
-            ep11_data->used_firmware_API_version =
8520e9
-                                MIN(ep11_data->used_firmware_API_version,
8520e9
+            target_info->used_firmware_API_version =
8520e9
+                                MIN(target_info->used_firmware_API_version,
8520e9
                                     card_version->firmware_API_version);
8520e9
 
8520e9
         card_version = card_version->next;
8520e9
     }
8520e9
 
8520e9
     TRACE_INFO("%s Used Firmware API: %lu\n", __func__,
8520e9
-               ep11_data->used_firmware_API_version);
8520e9
+               target_info->used_firmware_API_version);
8520e9
 
8520e9
     return CKR_OK;
8520e9
 }
8520e9
@@ -11220,20 +11313,29 @@ static void free_card_versions(ep11_card_version_t *card_version)
8520e9
     }
8520e9
 }
8520e9
 
8520e9
-void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata,
8520e9
+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata,
8520e9
                                  CK_TOKEN_INFO_PTR pInfo)
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
 
8520e9
     /*
8520e9
      * report the EP11 firmware version as hardware version, and
8520e9
      * the EP11 host library version as firmware version
8520e9
      */
8520e9
-    if (ep11_data->card_versions != NULL)
8520e9
-        pInfo->hardwareVersion = ep11_data->card_versions->firmware_version;
8520e9
+    if (target_info->card_versions != NULL)
8520e9
+        pInfo->hardwareVersion = target_info->card_versions->firmware_version;
8520e9
     pInfo->firmwareVersion = ep11_data->ep11_lib_version;
8520e9
-    memcpy(pInfo->serialNumber, ep11_data->serialNumber,
8520e9
+    memcpy(pInfo->serialNumber, target_info->serialNumber,
8520e9
            sizeof(pInfo->serialNumber));
8520e9
+
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+
8520e9
+    return CKR_OK;
8520e9
 }
8520e9
 
8520e9
 /**
8520e9
@@ -11247,13 +11349,17 @@ static int check_required_versions(STDLL_TokData_t *tokdata,
8520e9
                                    const version_req_t req[],
8520e9
                                    CK_ULONG num_req)
8520e9
 {
8520e9
-    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     CK_ULONG i, max_card_type = 0, min_card_type = 0xFFFFFFFF;
8520e9
     CK_BBOOL req_not_fullfilled = CK_FALSE;
8520e9
     CK_BBOOL req_fullfilled = CK_FALSE;
8520e9
     ep11_card_version_t *card_version;
8520e9
+    ep11_target_info_t* target_info;
8520e9
     int status;
8520e9
 
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return CKR_FUNCTION_FAILED;
8520e9
+
8520e9
     for (i = 0; i < num_req; i++) {
8520e9
         status = check_card_version(tokdata, req[i].card_type,
8520e9
                                            req[i].min_lib_version,
8520e9
@@ -11268,7 +11374,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata,
8520e9
     }
8520e9
 
8520e9
     /* Are card types < min_card_type present? */
8520e9
-    card_version = ep11_data->card_versions;
8520e9
+    card_version = target_info->card_versions;
8520e9
     while (card_version != NULL) {
8520e9
          if (card_version->card_type < min_card_type)
8520e9
              req_not_fullfilled = CK_TRUE;
8520e9
@@ -11276,7 +11382,7 @@ static int check_required_versions(STDLL_TokData_t *tokdata,
8520e9
      }
8520e9
 
8520e9
     /* Are card types > max_card_type present? */
8520e9
-    card_version = ep11_data->card_versions;
8520e9
+    card_version = target_info->card_versions;
8520e9
     while (card_version != NULL) {
8520e9
         if (card_version->card_type > max_card_type) {
8520e9
             /*
8520e9
@@ -11285,9 +11391,10 @@ static int check_required_versions(STDLL_TokData_t *tokdata,
8520e9
               * So all others must also meet the version requirements or be
8520e9
               * not present.
8520e9
               */
8520e9
+            status = 1;
8520e9
              if (req_not_fullfilled == CK_TRUE)
8520e9
-                 return -1;
8520e9
-             return 1;
8520e9
+                 status = -1;
8520e9
+             goto out;
8520e9
         }
8520e9
         card_version = card_version->next;
8520e9
     }
8520e9
@@ -11298,13 +11405,19 @@ static int check_required_versions(STDLL_TokData_t *tokdata,
8520e9
          * At least one don't meet the requirements, so all other must not
8520e9
          * fulfill the requirements, too, or are not present.
8520e9
          */
8520e9
+        status = 0;
8520e9
         if (req_fullfilled == CK_TRUE)
8520e9
-                return -1;
8520e9
-        return 0;
8520e9
+            status = -1;
8520e9
+        goto out;
8520e9
     } else {
8520e9
         /* All of the cards that are present fulfill the requirements */
8520e9
-        return 1;
8520e9
+        status = 1;
8520e9
+        goto out;
8520e9
     }
8520e9
+
8520e9
+out:
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+    return status;
8520e9
 }
8520e9
 
8520e9
 /**
8520e9
@@ -11320,6 +11433,8 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type,
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     ep11_card_version_t *card_version;
8520e9
+    ep11_target_info_t* target_info;
8520e9
+    int status = 1;
8520e9
 
8520e9
     TRACE_DEBUG("%s checking versions for CEX%luP cards.\n", __func__, card_type);
8520e9
 
8520e9
@@ -11331,21 +11446,28 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type,
8520e9
         }
8520e9
     }
8520e9
 
8520e9
-    card_version = ep11_data->card_versions;
8520e9
+    target_info = get_target_info(tokdata);
8520e9
+    if (target_info == NULL)
8520e9
+        return -1;
8520e9
+
8520e9
+    card_version = target_info->card_versions;
8520e9
     while (card_version != NULL) {
8520e9
         if (card_version->card_type == card_type)
8520e9
             break;
8520e9
         card_version = card_version->next;
8520e9
     }
8520e9
 
8520e9
-    if (card_version == NULL)
8520e9
-        return -1;
8520e9
+    if (card_version == NULL) {
8520e9
+        status = -1;
8520e9
+        goto out;
8520e9
+    }
8520e9
 
8520e9
     if (firmware_version != NULL) {
8520e9
         if (compare_ck_version(&card_version->firmware_version,
8520e9
                                firmware_version) < 0) {
8520e9
             TRACE_DEBUG("%s firmware_version is less than required\n", __func__);
8520e9
-            return 0;
8520e9
+            status = 0;
8520e9
+            goto out;
8520e9
         }
8520e9
     }
8520e9
 
8520e9
@@ -11353,53 +11475,57 @@ static int check_card_version(STDLL_TokData_t *tokdata, CK_ULONG card_type,
8520e9
         if (card_version->firmware_API_version < *firmware_API_version) {
8520e9
             TRACE_DEBUG("%s firmware_API_version is less than required\n",
8520e9
                        __func__);
8520e9
-            return 0;
8520e9
+            status = 0;
8520e9
+            goto out;
8520e9
         }
8520e9
     }
8520e9
 
8520e9
-    return 1;
8520e9
+ out:
8520e9
+    put_target_info(tokdata, target_info);
8520e9
+    return status;
8520e9
 }
8520e9
 
8520e9
-static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata)
8520e9
+static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata,
8520e9
+                                  ep11_target_info_t *target_info)
8520e9
 {
8520e9
     ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
     struct XCP_Module module;
8520e9
-    CK_RV rc;
8520e9
+    CK_RV rc = CKR_OK;
8520e9
     short i;
8520e9
 
8520e9
     if (dll_m_add_module == NULL) {
8520e9
         TRACE_WARNING("%s Function dll_m_add_module is not available, falling "
8520e9
                       "back to old target handling\n", __func__);
8520e9
 
8520e9
-        if (ep11_data->used_firmware_API_version > 2) {
8520e9
+        if (target_info->used_firmware_API_version > 2) {
8520e9
             TRACE_ERROR("%s selecting an API version is not possible with old "
8520e9
                         "target handling\n", __func__);
8520e9
             return CKR_FUNCTION_FAILED;
8520e9
         }
8520e9
 
8520e9
-        ep11_data->target = (target_t)&ep11_data->target_list;
8520e9
+        target_info->target = (target_t)&ep11_data->target_list;
8520e9
         return CKR_OK;
8520e9
     }
8520e9
 
8520e9
-    if (ep11_data->used_firmware_API_version > 2 &&
8520e9
+    if (target_info->used_firmware_API_version > 2 &&
8520e9
         ep11_data->ep11_lib_version.major < 3) {
8520e9
         TRACE_ERROR("%s selecting an API version is not possible with an EP11"
8520e9
                     " host library version < 3.0\n", __func__);
8520e9
         return CKR_FUNCTION_FAILED;
8520e9
     }
8520e9
 
8520e9
-    ep11_data->target = XCP_TGT_INIT;
8520e9
+    target_info->target = XCP_TGT_INIT;
8520e9
     memset(&module, 0, sizeof(module));
8520e9
     module.version = ep11_data->ep11_lib_version.major >= 3 ? XCP_MOD_VERSION_2
8520e9
                                                             : XCP_MOD_VERSION_1;
8520e9
     module.flags = XCP_MFL_VIRTUAL | XCP_MFL_MODULE;
8520e9
-    module.api = ep11_data->used_firmware_API_version;
8520e9
+    module.api = target_info->used_firmware_API_version;
8520e9
 
8520e9
     TRACE_DEVEL("%s XCP_MOD_VERSION: %u\n", __func__, module.version);
8520e9
 
8520e9
     if (ep11_data->target_list.length == 0) {
8520e9
         /* APQN_ANY: Create an empty module group */
8520e9
-        rc = dll_m_add_module(&module, &ep11_data->target);
8520e9
+        rc = dll_m_add_module(&module, &target_info->target);
8520e9
         if (rc != CKR_OK) {
8520e9
             TRACE_ERROR("%s dll_m_add_module (ANY) failed: rc=%ld\n",
8520e9
                         __func__, rc);
8520e9
@@ -11414,11 +11540,12 @@ static CK_RV ep11tok_setup_target(STDLL_TokData_t *tokdata)
8520e9
         XCPTGTMASK_SET_DOM(module.domainmask,
8520e9
                            ep11_data->target_list.apqns[2 * i + 1]);
8520e9
 
8520e9
-        rc = dll_m_add_module(&module, &ep11_data->target);
8520e9
+        rc = dll_m_add_module(&module, &target_info->target);
8520e9
         if (rc != CKR_OK) {
8520e9
             TRACE_ERROR("%s dll_m_add_module (%02x.%04x) failed: rc=%ld\n",
8520e9
                     __func__, ep11_data->target_list.apqns[2 * i],
8520e9
                     ep11_data->target_list.apqns[2 * i + 1], rc);
8520e9
+            dll_m_rm_module(NULL, target_info->target);
8520e9
             return CKR_FUNCTION_FAILED;
8520e9
         }
8520e9
     }
8520e9
@@ -11494,6 +11621,7 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj,
8520e9
     CK_ULONG num_attributes = 0;
8520e9
     CK_ATTRIBUTE *attr;
8520e9
     CK_RV rc;
8520e9
+    ep11_target_info_t* target_info;
8520e9
 
8520e9
     rc = template_attribute_get_ulong(obj->template, CKA_CLASS, &class);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -11575,9 +11703,18 @@ CK_RV token_specific_set_attribute_values(STDLL_TokData_t *tokdata, OBJECT *obj,
8520e9
             goto out;
8520e9
         }
8520e9
 
8520e9
+        target_info = get_target_info(tokdata);
8520e9
+        if (target_info == NULL) {
8520e9
+            rc = CKR_FUNCTION_FAILED;
8520e9
+            goto out;
8520e9
+        }
8520e9
+
8520e9
         rc = dll_m_SetAttributeValue(ibm_opaque_attr->pValue,
8520e9
                                      ibm_opaque_attr->ulValueLen, attributes,
8520e9
-                                     num_attributes, ep11_data->target);
8520e9
+                                     num_attributes, target_info->target);
8520e9
+
8520e9
+        put_target_info(tokdata, target_info);
8520e9
+
8520e9
         if (rc != CKR_OK) {
8520e9
             rc = ep11_error_to_pkcs11_error(rc, NULL);
8520e9
             TRACE_ERROR("%s m_SetAttributeValue failed rc=0x%lx\n",
8520e9
@@ -11601,3 +11738,233 @@ out:
8520e9
     return rc;
8520e9
 }
8520e9
 
8520e9
+/*
8520e9
+ * ATTENTION: This function is called in a separate thread. All actions
8520e9
+ * performed by this function must be thread save and use locks to lock
8520e9
+ * against concurrent access by other threads.
8520e9
+ */
8520e9
+static CK_RV ep11tok_handle_apqn_event(STDLL_TokData_t *tokdata,
8520e9
+                                       unsigned int event_type,
8520e9
+                                       event_udev_apqn_data_t *apqn_data)
8520e9
+{
8520e9
+    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    CK_BBOOL found = FALSE;
8520e9
+    CK_RV rc = CKR_OK;
8520e9
+    char name[20];
8520e9
+    int i;
8520e9
+
8520e9
+    /* Is it one of the configured APQNs ?*/
8520e9
+    if (ep11_data->target_list.length > 0) {
8520e9
+        /* APQN_WHITELIST is specified */
8520e9
+        for (i = 0; i < ep11_data->target_list.length; i++) {
8520e9
+            if (ep11_data->target_list.apqns[2 * i] == apqn_data->card &&
8520e9
+                ep11_data->target_list.apqns[2 * i + 1] == apqn_data->domain) {
8520e9
+                found = TRUE;
8520e9
+                break;
8520e9
+            }
8520e9
+        }
8520e9
+    } else {
8520e9
+        /* APQN_ANY is specified */
8520e9
+        found = TRUE;
8520e9
+        if (event_type == EVENT_TYPE_APQN_ADD) {
8520e9
+            snprintf(name, sizeof(name), "card%02x", apqn_data->card);
8520e9
+            if (is_card_ep11_and_online(name) != CKR_OK)
8520e9
+                found = FALSE; /* Not an EP11 APQN */
8520e9
+        }
8520e9
+    }
8520e9
+    if (!found)
8520e9
+        return CKR_OK;
8520e9
+
8520e9
+    TRACE_DEVEL("%s Refreshing target infos due to event for APQN %02x.%04x\n",
8520e9
+                __func__, apqn_data->card, apqn_data->domain);
8520e9
+
8520e9
+    rc = refresh_target_info(tokdata);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s Failed to get the target infos (refresh_target_info "
8520e9
+                    "rc=0x%lx)\n", __func__, rc);
8520e9
+        OCK_SYSLOG(LOG_ERR, "%s: Failed to get the target info rc=0x%lx\n",
8520e9
+                   __func__, rc);
8520e9
+        return rc;
8520e9
+    }
8520e9
+
8520e9
+    return CKR_OK;
8520e9
+}
8520e9
+
8520e9
+/*
8520e9
+ * Called by the event thread, on receipt of an event.
8520e9
+ *
8520e9
+ * ATTENTION: This function is called in a separate thread. All actions
8520e9
+ * performed by this function must be thread save and use locks to lock
8520e9
+ * against concurrent access by other threads.
8520e9
+ */
8520e9
+CK_RV token_specific_handle_event(STDLL_TokData_t *tokdata,
8520e9
+                                  unsigned int event_type,
8520e9
+                                  unsigned int event_flags,
8520e9
+                                  const char *payload,
8520e9
+                                  unsigned int payload_len)
8520e9
+{
8520e9
+    UNUSED(event_flags);
8520e9
+
8520e9
+    switch (event_type) {
8520e9
+    case EVENT_TYPE_APQN_ADD:
8520e9
+    case EVENT_TYPE_APQN_REMOVE:
8520e9
+        if (payload_len != sizeof(event_udev_apqn_data_t))
8520e9
+            return CKR_FUNCTION_FAILED;
8520e9
+        return ep11tok_handle_apqn_event(tokdata, event_type,
8520e9
+                                         (event_udev_apqn_data_t *)payload);
8520e9
+
8520e9
+    default:
8520e9
+        return CKR_FUNCTION_NOT_SUPPORTED;
8520e9
+    }
8520e9
+
8520e9
+    return CKR_OK;
8520e9
+}
8520e9
+
8520e9
+/*
8520e9
+ * Refreshes the target info using the currently configured and available
8520e9
+ * APQNs. Registers the newly allocated target info as the current one in a
8520e9
+ * thread save way and gives back the previous one so that it is release when
8520e9
+ * no longer used (i.e. by a concurrently running thread).
8520e9
+ */
8520e9
+static CK_RV refresh_target_info(STDLL_TokData_t *tokdata)
8520e9
+{
8520e9
+    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    volatile ep11_target_info_t *prev_info;
8520e9
+    ep11_target_info_t *target_info;
8520e9
+    CK_RV rc;
8520e9
+
8520e9
+    target_info = calloc(1, sizeof(ep11_target_info_t));
8520e9
+    if (target_info == NULL) {
8520e9
+        TRACE_ERROR("%s Memory allocation failed\n", __func__);
8520e9
+        return CKR_HOST_MEMORY;
8520e9
+    }
8520e9
+
8520e9
+    target_info->ref_count = 1;
8520e9
+
8520e9
+    /* Get the version info freshly with the current set of APQNs */
8520e9
+    rc = ep11tok_get_ep11_version(tokdata, target_info);
8520e9
+    if (rc != 0)
8520e9
+        goto error;
8520e9
+
8520e9
+    /* Get the control points freshly with the current set of APQNs */
8520e9
+    target_info->control_points_len = sizeof(target_info->control_points);
8520e9
+    rc = get_control_points(tokdata, target_info->control_points,
8520e9
+                            &target_info->control_points_len,
8520e9
+                            &target_info->max_control_point_index);
8520e9
+    if (rc != 0)
8520e9
+        goto error;
8520e9
+
8520e9
+    /* Setup the group target freshly with the current set of APQNs */
8520e9
+    rc = ep11tok_setup_target(tokdata, target_info);
8520e9
+    if (rc != CKR_OK)
8520e9
+        goto error;
8520e9
+
8520e9
+    /* Set the new one as the current one (locked against concurrent get's) */
8520e9
+    if (pthread_rwlock_wrlock(&ep11_data->target_rwlock) != 0) {
8520e9
+        TRACE_DEVEL("Target Write-Lock failed.\n");
8520e9
+        rc = CKR_CANT_LOCK;
8520e9
+        goto error;
8520e9
+    }
8520e9
+
8520e9
+    prev_info = ep11_data->target_info;
8520e9
+    ep11_data->target_info = target_info;
8520e9
+
8520e9
+    if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) {
8520e9
+        TRACE_DEVEL("Target Unlock failed.\n");
8520e9
+        return CKR_CANT_LOCK;
8520e9
+    }
8520e9
+
8520e9
+    /* Release the previous one */
8520e9
+    if (prev_info != NULL)
8520e9
+        put_target_info(tokdata, (ep11_target_info_t *)prev_info);
8520e9
+
8520e9
+    return CKR_OK;
8520e9
+
8520e9
+error:
8520e9
+    free_card_versions(target_info->card_versions);
8520e9
+    free((void *)target_info);
8520e9
+    return rc;
8520e9
+}
8520e9
+
8520e9
+/*
8520e9
+ * Get the current EP11 target info.
8520e9
+ * Do NOT use the ep11_data->target_info directly, always get a copy using
8520e9
+ * this function. This will increment the reference count of the target info,
8520e9
+ * and return the current target info in a thread save way.
8520e9
+ * When no longer needed, put it back using put_target_info().
8520e9
+ */
8520e9
+static ep11_target_info_t *get_target_info(STDLL_TokData_t *tokdata)
8520e9
+{
8520e9
+    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    volatile ep11_target_info_t *target_info;
8520e9
+#ifdef DEBUG
8520e9
+    unsigned long ref_count;
8520e9
+#endif
8520e9
+
8520e9
+    /*
8520e9
+     * Lock until we have obtained the current target info and have
8520e9
+     * increased the reference counter
8520e9
+     */
8520e9
+    if (pthread_rwlock_rdlock(&ep11_data->target_rwlock) != 0) {
8520e9
+        TRACE_DEVEL("Target Read-Lock failed.\n");
8520e9
+        return NULL;
8520e9
+    }
8520e9
+
8520e9
+    target_info = *((void * volatile *)&ep11_data->target_info);
8520e9
+    if (target_info == NULL) {
8520e9
+        TRACE_ERROR("%s: target_info is NULL\n", __func__);
8520e9
+        return NULL;
8520e9
+    }
8520e9
+
8520e9
+#ifdef DEBUG
8520e9
+    ref_count = __sync_add_and_fetch(&target_info->ref_count, 1);
8520e9
+
8520e9
+    TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__,
8520e9
+                (void *)target_info, ref_count);
8520e9
+#else
8520e9
+    __sync_add_and_fetch(&target_info->ref_count, 1);
8520e9
+#endif
8520e9
+
8520e9
+    if (pthread_rwlock_unlock(&ep11_data->target_rwlock) != 0) {
8520e9
+        TRACE_DEVEL("Target Unlock failed.\n");
8520e9
+        return NULL;
8520e9
+    }
8520e9
+
8520e9
+    return (ep11_target_info_t *)target_info;
8520e9
+}
8520e9
+
8520e9
+/*
8520e9
+ * Give back an EP11 target info. This will decrement the reference count,
8520e9
+ * and will free it if the reference count reaches zero.
8520e9
+ */
8520e9
+static void put_target_info(STDLL_TokData_t *tokdata,
8520e9
+                            ep11_target_info_t *target_info)
8520e9
+{
8520e9
+    ep11_private_data_t *ep11_data = tokdata->private_data;
8520e9
+    unsigned long ref_count;
8520e9
+
8520e9
+    if (target_info == NULL)
8520e9
+        return;
8520e9
+
8520e9
+    if (target_info->ref_count > 0) {
8520e9
+        ref_count = __sync_sub_and_fetch(&target_info->ref_count, 1);
8520e9
+
8520e9
+        TRACE_DEBUG("%s: target_info: %p ref_count: %lu\n", __func__,
8520e9
+                    (void *)target_info, ref_count);
8520e9
+    } else {
8520e9
+        TRACE_WARNING("%s: target_info: %p ref_count already 0.\n", __func__,
8520e9
+                      (void *)target_info);
8520e9
+        ref_count = 0;
8520e9
+    }
8520e9
+
8520e9
+    if (ref_count == 0 && target_info != ep11_data->target_info) {
8520e9
+        TRACE_DEBUG("%s: target_info: %p is freed\n", __func__,
8520e9
+                    (void *)target_info);
8520e9
+
8520e9
+        if (dll_m_rm_module != NULL)
8520e9
+            dll_m_rm_module(NULL, target_info->target);
8520e9
+        free_card_versions(target_info->card_versions);
8520e9
+        free(target_info);
8520e9
+    }
8520e9
+}
8520e9
+
8520e9
diff --git a/usr/lib/ep11_stdll/ep11_specific.h b/usr/lib/ep11_stdll/ep11_specific.h
8520e9
index 55fc023c..343f4b3d 100644
8520e9
--- a/usr/lib/ep11_stdll/ep11_specific.h
8520e9
+++ b/usr/lib/ep11_stdll/ep11_specific.h
8520e9
@@ -161,7 +161,7 @@ CK_BBOOL ep11tok_libica_mech_available(STDLL_TokData_t *tokdata,
8520e9
                                        CK_MECHANISM_TYPE mech,
8520e9
                                        CK_OBJECT_HANDLE hKey);
8520e9
 
8520e9
-void ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata,
8520e9
+CK_RV ep11tok_copy_firmware_info(STDLL_TokData_t *tokdata,
8520e9
                                  CK_TOKEN_INFO_PTR pInfo);
8520e9
 
8520e9
 CK_BBOOL ep11tok_pkey_usage_ok(STDLL_TokData_t *tokdata, SESSION *session,
8520e9
diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c
8520e9
index 4e592363..cd12604e 100644
8520e9
--- a/usr/lib/ep11_stdll/new_host.c
8520e9
+++ b/usr/lib/ep11_stdll/new_host.c
8520e9
@@ -298,7 +298,7 @@ CK_RV SC_GetTokenInfo(STDLL_TokData_t *tokdata, CK_SLOT_ID sid,
8520e9
         goto done;
8520e9
     }
8520e9
     copy_token_contents_sensibly(pInfo, tokdata->nv_token_data);
8520e9
-    ep11tok_copy_firmware_info(tokdata, pInfo);
8520e9
+    rc = ep11tok_copy_firmware_info(tokdata, pInfo);
8520e9
 
8520e9
     /* Set the time */
8520e9
     now = time((time_t *) NULL);
8520e9
diff --git a/usr/lib/ep11_stdll/tok_struct.h b/usr/lib/ep11_stdll/tok_struct.h
8520e9
index 2c0af9cf..01268c67 100644
8520e9
--- a/usr/lib/ep11_stdll/tok_struct.h
8520e9
+++ b/usr/lib/ep11_stdll/tok_struct.h
8520e9
@@ -137,7 +137,7 @@ token_spec_t token_specific = {
8520e9
     &token_specific_reencrypt_single,
8520e9
     &token_specific_set_attribute_values,
8520e9
     &token_specific_set_attrs_for_new_object,
8520e9
-    NULL,                       // handle_event
8520e9
+    &token_specific_handle_event,
8520e9
 };
8520e9
 
8520e9
 #endif