OpenSSL 1.1.0 uses new threading API. It is no longer necessary to set
locking callbacks to use OpenSSL in a multi-threaded environment. The
old threading API should no longer be used. Separate old locking code
into separate functions that are guarded by OPENSSL_VERSION_NUMBER
check.

Signed-off-by: Dmitry Eremin-Solenikov <[email protected]>
---
 .../linux-generic/include/odp_crypto_internal.h    |  1 +
 platform/linux-generic/odp_crypto.c                | 78 ++++++++++++++++------
 2 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/platform/linux-generic/include/odp_crypto_internal.h 
b/platform/linux-generic/include/odp_crypto_internal.h
index c7b893aa..f85b76ea 100644
--- a/platform/linux-generic/include/odp_crypto_internal.h
+++ b/platform/linux-generic/include/odp_crypto_internal.h
@@ -13,6 +13,7 @@ extern "C" {
 
 #include <openssl/des.h>
 #include <openssl/aes.h>
+#include <openssl/evp.h>
 
 #define MAX_IV_LEN      64
 #define OP_RESULT_MAGIC 0x91919191
diff --git a/platform/linux-generic/odp_crypto.c 
b/platform/linux-generic/odp_crypto.c
index b53b0fc1..2145c36e 100644
--- a/platform/linux-generic/odp_crypto.c
+++ b/platform/linux-generic/odp_crypto.c
@@ -26,6 +26,7 @@
 #include <openssl/rand.h>
 #include <openssl/hmac.h>
 #include <openssl/evp.h>
+#include <openssl/opensslv.h>
 
 #define MAX_SESSIONS 32
 
@@ -64,7 +65,6 @@ typedef struct odp_crypto_global_s odp_crypto_global_t;
 
 struct odp_crypto_global_s {
        odp_spinlock_t                lock;
-       odp_ticketlock_t **openssl_lock;
        odp_crypto_generic_session_t *free;
        odp_crypto_generic_session_t  sessions[0];
 };
@@ -949,35 +949,80 @@ odp_crypto_operation(odp_crypto_op_param_t *param,
        return 0;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 static unsigned long openssl_thread_id(void)
 {
        return (unsigned long)odp_thread_id();
 }
 
+odp_ticketlock_t *openssl_locks;
+
 static void openssl_lock(int mode, int n,
                         const char *file ODP_UNUSED,
                         int line ODP_UNUSED)
 {
        if (mode & CRYPTO_LOCK)
-               odp_ticketlock_lock((odp_ticketlock_t *)
-                                   &global->openssl_lock[n]);
+               odp_ticketlock_lock(&openssl_locks[n]);
        else
-               odp_ticketlock_unlock((odp_ticketlock_t *)
-                                     &global->openssl_lock[n]);
+               odp_ticketlock_unlock(&openssl_locks[n]);
+}
+
+static void odp_crypto_init_openssl_locks(void)
+{
+       int nlocks = CRYPTO_num_locks();
+       size_t mem_size;
+       odp_shm_t shm;
+       int idx;
+
+       if (nlocks <= 0)
+               return;
+
+       mem_size = nlocks * sizeof(odp_ticketlock_t);
+
+       /* Allocate our globally shared memory */
+       shm = odp_shm_reserve("crypto_openssl_locks", mem_size,
+                             ODP_CACHE_LINE_SIZE, 0);
+
+       openssl_locks = odp_shm_addr(shm);
+
+       /* Clear it out */
+       memset(openssl_locks, 0, mem_size);
+
+       for (idx = 0; idx < nlocks; idx++)
+               odp_ticketlock_init(&openssl_locks[idx]);
+
+       CRYPTO_set_id_callback(openssl_thread_id);
+       CRYPTO_set_locking_callback(openssl_lock);
 }
 
+static int odp_crypto_term_openssl_locks(void)
+{
+       CRYPTO_set_locking_callback(NULL);
+       CRYPTO_set_id_callback(NULL);
+
+       return odp_shm_free(odp_shm_lookup("crypto_openssl_locks"));
+}
+#else
+static void odp_crypto_init_openssl_locks(void)
+{
+}
+
+static int odp_crypto_term_openssl_locks(void)
+{
+       return 0;
+}
+#endif
+
 int
 odp_crypto_init_global(void)
 {
        size_t mem_size;
        odp_shm_t shm;
        int idx;
-       int nlocks = CRYPTO_num_locks();
 
        /* Calculate the memory size we need */
        mem_size  = sizeof(*global);
        mem_size += (MAX_SESSIONS * sizeof(odp_crypto_generic_session_t));
-       mem_size += nlocks * sizeof(odp_ticketlock_t);
 
        /* Allocate our globally shared memory */
        shm = odp_shm_reserve("crypto_pool", mem_size,
@@ -995,17 +1040,7 @@ odp_crypto_init_global(void)
        }
        odp_spinlock_init(&global->lock);
 
-       if (nlocks > 0) {
-               global->openssl_lock =
-                       (odp_ticketlock_t **)&global->sessions[MAX_SESSIONS];
-
-               for (idx = 0; idx < nlocks; idx++)
-                       odp_ticketlock_init((odp_ticketlock_t *)
-                                           &global->openssl_lock[idx]);
-
-               CRYPTO_set_id_callback(openssl_thread_id);
-               CRYPTO_set_locking_callback(openssl_lock);
-       }
+       odp_crypto_init_openssl_locks();
 
        return 0;
 }
@@ -1024,8 +1059,11 @@ int odp_crypto_term_global(void)
                rc = -1;
        }
 
-       CRYPTO_set_locking_callback(NULL);
-       CRYPTO_set_id_callback(NULL);
+       ret = odp_crypto_term_openssl_locks();
+       if (ret < 0) {
+               ODP_ERR("shm free failed for crypto_openssl_locks\n");
+               rc = -1;
+       }
 
        ret = odp_shm_free(odp_shm_lookup("crypto_pool"));
        if (ret < 0) {
-- 
2.11.0

Reply via email to