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
