Blame SOURCES/opencryptoki-3.16.0-c79e899d77a5724635a9d4451a34a240e2c7e891.patch

8520e9
commit c79e899d77a5724635a9d4451a34a240e2c7e891
8520e9
Author: Ingo Franzki <ifranzki@linux.ibm.com>
8520e9
Date:   Fri Apr 16 13:41:41 2021 +0200
8520e9
8520e9
    Fix potential deadlock situation with double read-locks
8520e9
    
8520e9
    Do not get and read-lock an object twice within the same thread via
8520e9
    function object_mgr_find_in_map1(), as this would read-lock the object
8520e9
    twice.
8520e9
    
8520e9
    This could cause a deadlock situation, when in-between the first
8520e9
    and the second call to object_mgr_find_in_map1() the token object is
8520e9
    modified by another process. The second object_mgr_find_in_map1() would
8520e9
    detect that the object has been modified (object_mgr_check_shm()), and
8520e9
    would try to re-load the object from the disk. For re-loading, the
8520e9
    object is unlocked once, and a write-lock is acquired instead.
8520e9
    However, if the current thread has read-locked the object twice, but
8520e9
    releases only one read-lock, then it will never get the write lock,
8520e9
    because it still owns the read lock itself.
8520e9
    
8520e9
    To avoid this situation, release the read-lock before calling another
8520e9
    function that also acquires the read lock of the object. That way, only
8520e9
    one read-lock is held by the current thread, and re-loading the object
8520e9
    will not cause a deadlock.
8520e9
    
8520e9
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
8520e9
8520e9
diff --git a/usr/lib/common/decr_mgr.c b/usr/lib/common/decr_mgr.c
8520e9
index 317ef995..9842302b 100644
8520e9
--- a/usr/lib/common/decr_mgr.c
8520e9
+++ b/usr/lib/common/decr_mgr.c
8520e9
@@ -540,6 +540,10 @@ CK_RV decr_mgr_init(STDLL_TokData_t *tokdata,
8520e9
         }
8520e9
         memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT));
8520e9
 
8520e9
+        /* Release obj lock, token specific aes-gcm may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 0);
8520e9
         if (rc) {
8520e9
             TRACE_ERROR("Could not initialize AES_GCM parms.\n");
8520e9
diff --git a/usr/lib/common/encr_mgr.c b/usr/lib/common/encr_mgr.c
8520e9
index d3ecdeee..3e85ceab 100644
8520e9
--- a/usr/lib/common/encr_mgr.c
8520e9
+++ b/usr/lib/common/encr_mgr.c
8520e9
@@ -537,6 +537,10 @@ CK_RV encr_mgr_init(STDLL_TokData_t *tokdata,
8520e9
         }
8520e9
         memset(ctx->context, 0x0, sizeof(AES_GCM_CONTEXT));
8520e9
 
8520e9
+        /* Release obj lock, token specific aes-gcm may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         rc = aes_gcm_init(tokdata, sess, ctx, mech, key_handle, 1);
8520e9
         if (rc != CKR_OK) {
8520e9
             TRACE_ERROR("Could not initialize AES_GCM parms.\n");
8520e9
diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c
8520e9
index 1652f90a..e35b383c 100644
8520e9
--- a/usr/lib/common/mech_rsa.c
8520e9
+++ b/usr/lib/common/mech_rsa.c
8520e9
@@ -602,6 +602,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess,
8520e9
             goto done;
8520e9
         }
8520e9
 
8520e9
+        /* Release obj lock, token specific rsa-oaep may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         rc = token_specific.t_rsa_oaep_encrypt(tokdata, ctx, in_data,
8520e9
                                                in_data_len, out_data,
8520e9
                                                out_data_len, hash, hlen);
8520e9
@@ -625,6 +629,10 @@ CK_RV rsa_oaep_crypt(STDLL_TokData_t *tokdata, SESSION *sess,
8520e9
             goto done;
8520e9
         }
8520e9
 
8520e9
+        /* Release obj lock, token specific rsa-oaep may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         rc = token_specific.t_rsa_oaep_decrypt(tokdata, ctx, in_data,
8520e9
                                                in_data_len, out_data,
8520e9
                                                out_data_len, hash, hlen);
8520e9
@@ -1331,6 +1339,10 @@ CK_RV rsa_pss_sign(STDLL_TokData_t *tokdata, SESSION *sess,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
+    /* Release obj lock, token specific rsa_pss may re-acquire the lock */
8520e9
+    object_put(tokdata, key_obj, TRUE);
8520e9
+    key_obj = NULL;
8520e9
+
8520e9
     rc = token_specific.t_rsa_pss_sign(tokdata, sess, ctx, in_data, in_data_len,
8520e9
                                        out_data, out_data_len);
8520e9
     if (rc != CKR_OK)
8520e9
@@ -1389,6 +1401,10 @@ CK_RV rsa_pss_verify(STDLL_TokData_t *tokdata, SESSION *sess,
8520e9
         goto done;
8520e9
     }
8520e9
 
8520e9
+    /* Release obj lock, token specific rsa_pss may re-acquire the lock */
8520e9
+    object_put(tokdata, key_obj, TRUE);
8520e9
+    key_obj = NULL;
8520e9
+
8520e9
     rc = token_specific.t_rsa_pss_verify(tokdata, sess, ctx, in_data,
8520e9
                                          in_data_len, signature, sig_len);
8520e9
     if (rc != CKR_OK)
8520e9
diff --git a/usr/lib/common/sign_mgr.c b/usr/lib/common/sign_mgr.c
8520e9
index 937a371a..c7268e01 100644
8520e9
--- a/usr/lib/common/sign_mgr.c
8520e9
+++ b/usr/lib/common/sign_mgr.c
8520e9
@@ -424,6 +424,10 @@ CK_RV sign_mgr_init(STDLL_TokData_t *tokdata,
8520e9
         ctx->context_len = 0;
8520e9
         ctx->context = NULL;
8520e9
 
8520e9
+        /* Release obj lock, token specific hmac-sign may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         rc = hmac_sign_init(tokdata, sess, mech, key);
8520e9
         if (rc != CKR_OK) {
8520e9
             TRACE_ERROR("Failed to initialize hmac.\n");
8520e9
diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
8520e9
index 3ac3768a..52f95d7a 100644
8520e9
--- a/usr/lib/ep11_stdll/ep11_specific.c
8520e9
+++ b/usr/lib/ep11_stdll/ep11_specific.c
8520e9
@@ -6948,6 +6948,13 @@ CK_RV ep11tok_sign_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
8520e9
     switch (rc) {
8520e9
     case CKR_OK:
8520e9
+        /*
8520e9
+         * Release obj lock, sign_mgr_init or ep11tok_sign_verify_init_ibm_ed
8520e9
+         * may re-acquire the lock
8520e9
+         */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         /* Note that Edwards curves in general are not yet supported in
8520e9
          * opencryptoki. These two special IBM specific ED mechs are only
8520e9
          * supported by the ep11token, so let's keep them local here. */
8520e9
@@ -7029,11 +7036,16 @@ CK_RV ep11tok_sign(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
          * opencryptoki. These two special IBM specific ED mechs are only
8520e9
          * supported by the ep11token, so let's keep them local here. */
8520e9
         if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 ||
8520e9
-            ctx->mech.mechanism == CKM_IBM_ED448_SHA3)
8520e9
+            ctx->mech.mechanism == CKM_IBM_ED448_SHA3) {
8520e9
             rc = pkey_ibm_ed_sign(key_obj, in_data, in_data_len, signature, sig_len);
8520e9
-        else
8520e9
+        } else {
8520e9
+            /* Release obj lock, sign_mgr_sign may re-acquire the lock */
8520e9
+            object_put(tokdata, key_obj, TRUE);
8520e9
+            key_obj = NULL;
8520e9
+
8520e9
             rc = sign_mgr_sign(tokdata, session, length_only, ctx, in_data,
8520e9
                                in_data_len, signature, sig_len);
8520e9
+        }
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
@@ -7071,6 +7083,11 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     if (!in_data || !in_data_len)
8520e9
         return CKR_OK;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                           READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7078,11 +7095,6 @@ CK_RV ep11tok_sign_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = sign_mgr_sign_update(tokdata, session, ctx, in_data, in_data_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_SignUpdate(ctx->context, ctx->context_len, in_data,
8520e9
                               in_data_len, ep11_data->target);
8520e9
@@ -7115,6 +7127,11 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                           READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7122,11 +7139,6 @@ CK_RV ep11tok_sign_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = sign_mgr_sign_final(tokdata, session, length_only, ctx, signature, sig_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_SignFinal(ctx->context, ctx->context_len, signature, sig_len,
8520e9
                              ep11_data->target);
8520e9
@@ -7241,6 +7253,13 @@ CK_RV ep11tok_verify_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
8520e9
     switch (rc) {
8520e9
     case CKR_OK:
8520e9
+        /*
8520e9
+         * Release obj lock, verify_mgr_init or ep11tok_sign_verify_init_ibm_ed
8520e9
+         * may re-acquire the lock
8520e9
+         */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         /* Note that Edwards curves in general are not yet supported in
8520e9
          * opencryptoki. These two special IBM specific ED mechs are only
8520e9
          * supported by the ep11token, so let's keep them local here. */
8520e9
@@ -7320,12 +7339,17 @@ CK_RV ep11tok_verify(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
          * opencryptoki. These two special IBM specific ED mechs are only
8520e9
          * supported by the ep11token, so let's keep them local here. */
8520e9
         if (ctx->mech.mechanism == CKM_IBM_ED25519_SHA512 ||
8520e9
-            ctx->mech.mechanism == CKM_IBM_ED448_SHA3)
8520e9
+            ctx->mech.mechanism == CKM_IBM_ED448_SHA3) {
8520e9
             rc = pkey_ibm_ed_verify(key_obj, in_data, in_data_len,
8520e9
                                     signature, sig_len);
8520e9
-        else
8520e9
+        } else {
8520e9
+            /* Release obj lock, verify_mgr_verify may re-acquire the lock */
8520e9
+            object_put(tokdata, key_obj, TRUE);
8520e9
+            key_obj = NULL;
8520e9
+
8520e9
             rc = verify_mgr_verify(tokdata, session, ctx, in_data,
8520e9
                                    in_data_len, signature, sig_len);
8520e9
+        }
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
@@ -7363,6 +7387,11 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     if (!in_data || !in_data_len)
8520e9
         return CKR_OK;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                          READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7370,11 +7399,6 @@ CK_RV ep11tok_verify_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = verify_mgr_verify_update(tokdata, session, ctx, in_data, in_data_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_VerifyUpdate(ctx->context, ctx->context_len, in_data,
8520e9
                                 in_data_len, ep11_data->target);
8520e9
@@ -7406,6 +7430,11 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                          READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7413,11 +7442,6 @@ CK_RV ep11tok_verify_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = verify_mgr_verify_final(tokdata, session, ctx, signature, sig_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_VerifyFinal(ctx->context, ctx->context_len, signature,
8520e9
                                sig_len, ep11_data->target);
8520e9
@@ -7501,6 +7525,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = decr_mgr_decrypt_final(tokdata, session, length_only,
8520e9
+                                    ctx, output_part, p_output_part_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                          READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7508,12 +7538,6 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = decr_mgr_decrypt_final(tokdata, session, length_only,
8520e9
-                                    ctx, output_part, p_output_part_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_DecryptFinal(ctx->context, ctx->context_len,
8520e9
                                 output_part, p_output_part_len,
8520e9
@@ -7548,13 +7572,6 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
-    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
-                         READ_LOCK);
8520e9
-    if (rc != CKR_OK) {
8520e9
-        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
-        return rc;
8520e9
-    }
8520e9
-
8520e9
     if (ctx->pkey_active) {
8520e9
         rc = decr_mgr_decrypt(tokdata, session, length_only, ctx,
8520e9
                               input_data, input_data_len, output_data,
8520e9
@@ -7562,6 +7579,13 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
+    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
+                         READ_LOCK);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
+        return rc;
8520e9
+    }
8520e9
+
8520e9
     RETRY_START
8520e9
         rc = dll_m_Decrypt(ctx->context, ctx->context_len, input_data,
8520e9
                            input_data_len, output_data, p_output_data_len,
8520e9
@@ -7602,13 +7626,6 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return CKR_OK;          /* nothing to update, keep context */
8520e9
     }
8520e9
 
8520e9
-    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
-                         READ_LOCK);
8520e9
-    if (rc != CKR_OK) {
8520e9
-        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
-        return rc;
8520e9
-    }
8520e9
-
8520e9
     if (ctx->pkey_active) {
8520e9
         rc = decr_mgr_decrypt_update(tokdata, session, length_only,
8520e9
                                      ctx, input_part, input_part_len,
8520e9
@@ -7616,6 +7633,13 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
+    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
+                         READ_LOCK);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
+        return rc;
8520e9
+    }
8520e9
+
8520e9
     RETRY_START
8520e9
         rc = dll_m_DecryptUpdate(ctx->context, ctx->context_len,
8520e9
                                  input_part, input_part_len, output_part,
8520e9
@@ -7695,6 +7719,12 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
+    if (ctx->pkey_active) {
8520e9
+        rc = encr_mgr_encrypt_final(tokdata, session, length_only,
8520e9
+                                    ctx, output_part, p_output_part_len);
8520e9
+        goto done; /* no ep11 fallback possible */
8520e9
+    }
8520e9
+
8520e9
     rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
                          READ_LOCK);
8520e9
     if (rc != CKR_OK) {
8520e9
@@ -7702,12 +7732,6 @@ CK_RV ep11tok_encrypt_final(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return rc;
8520e9
     }
8520e9
 
8520e9
-    if (ctx->pkey_active) {
8520e9
-        rc = encr_mgr_encrypt_final(tokdata, session, length_only,
8520e9
-                                    ctx, output_part, p_output_part_len);
8520e9
-        goto done; /* no ep11 fallback possible */
8520e9
-    }
8520e9
-
8520e9
     RETRY_START
8520e9
         rc = dll_m_EncryptFinal(ctx->context, ctx->context_len,
8520e9
                                 output_part, p_output_part_len,
8520e9
@@ -7742,13 +7766,6 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     CK_BYTE *keyblob;
8520e9
     OBJECT *key_obj = NULL;
8520e9
 
8520e9
-    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
-                         READ_LOCK);
8520e9
-    if (rc != CKR_OK) {
8520e9
-        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
-        return rc;
8520e9
-    }
8520e9
-
8520e9
     if (ctx->pkey_active) {
8520e9
         rc = encr_mgr_encrypt(tokdata, session, length_only, ctx,
8520e9
                               input_data, input_data_len, output_data,
8520e9
@@ -7756,6 +7773,13 @@ CK_RV ep11tok_encrypt(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
+    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
+                         READ_LOCK);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
+        return rc;
8520e9
+    }
8520e9
+
8520e9
     RETRY_START
8520e9
         rc = dll_m_Encrypt(ctx->context, ctx->context_len, input_data,
8520e9
                            input_data_len, output_data, p_output_data_len,
8520e9
@@ -7796,13 +7820,6 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         return CKR_OK;          /* nothing to update, keep context */
8520e9
     }
8520e9
 
8520e9
-    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
-                         READ_LOCK);
8520e9
-    if (rc != CKR_OK) {
8520e9
-        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
-        return rc;
8520e9
-    }
8520e9
-
8520e9
     if (ctx->pkey_active) {
8520e9
         rc = encr_mgr_encrypt_update(tokdata, session, length_only, ctx,
8520e9
                                      input_part, input_part_len, output_part,
8520e9
@@ -7810,6 +7827,13 @@ CK_RV ep11tok_encrypt_update(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
         goto done; /* no ep11 fallback possible */
8520e9
     }
8520e9
 
8520e9
+    rc = h_opaque_2_blob(tokdata, ctx->key, &keyblob, &keyblobsize, &key_obj,
8520e9
+                         READ_LOCK);
8520e9
+    if (rc != CKR_OK) {
8520e9
+        TRACE_ERROR("%s h_opaque_2_blob, rc=0x%lx\n", __func__, rc);
8520e9
+        return rc;
8520e9
+    }
8520e9
+
8520e9
     RETRY_START
8520e9
         rc = dll_m_EncryptUpdate(ctx->context, ctx->context_len,
8520e9
                                  input_part, input_part_len, output_part,
8520e9
@@ -7921,6 +7945,10 @@ static CK_RV ep11_ende_crypt_init(STDLL_TokData_t * tokdata, SESSION * session,
8520e9
     rc = ep11tok_pkey_check(tokdata, session, key_obj, mech);
8520e9
     switch (rc) {
8520e9
     case CKR_OK:
8520e9
+        /* Release obj lock, encr/decr_mgr_init may re-acquire the lock */
8520e9
+        object_put(tokdata, key_obj, TRUE);
8520e9
+        key_obj = NULL;
8520e9
+
8520e9
         if (op == DECRYPT) {
8520e9
             rc = decr_mgr_init(tokdata, session, &session->decr_ctx,
8520e9
                                OP_DECRYPT_INIT, mech, key);