added locking mechanism for multithreaded use of OpenSSL
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "openssl_plugin.h"
|
||||
|
||||
@@ -41,8 +43,119 @@ struct private_openssl_plugin_t {
|
||||
* public functions
|
||||
*/
|
||||
openssl_plugin_t public;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Array of static mutexs, with CRYPTO_num_locks() mutex
|
||||
*/
|
||||
static pthread_mutex_t *mutex;
|
||||
|
||||
/**
|
||||
* Locking callback for static locks
|
||||
*/
|
||||
static void locking_function(int mode, int type, const char *file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
{
|
||||
pthread_mutex_lock(&mutex[type]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&mutex[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of dynlock
|
||||
*/
|
||||
struct CRYPTO_dynlock_value {
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to create a dynamic lock
|
||||
*/
|
||||
static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
|
||||
{
|
||||
struct CRYPTO_dynlock_value *lock;
|
||||
|
||||
lock = malloc_thing(struct CRYPTO_dynlock_value);
|
||||
pthread_mutex_init(&lock->mutex, NULL);
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to (un-)lock a dynamic lock
|
||||
*/
|
||||
static void lock_function(int mode, struct CRYPTO_dynlock_value *lock,
|
||||
const char *file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
{
|
||||
pthread_mutex_lock(&lock->mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&lock->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to destroy a dynamic lock
|
||||
*/
|
||||
static void destroy_function(struct CRYPTO_dynlock_value *lock,
|
||||
const char *file, int line)
|
||||
{
|
||||
pthread_mutex_destroy(&lock->mutex);
|
||||
free(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread-ID callback function
|
||||
*/
|
||||
static unsigned long id_function(void)
|
||||
{
|
||||
return pthread_self();
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize OpenSSL for multi-threaded use
|
||||
*/
|
||||
static void threading_init()
|
||||
{
|
||||
int i, num_locks;
|
||||
|
||||
CRYPTO_set_id_callback(id_function);
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
|
||||
CRYPTO_set_dynlock_create_callback(create_function);
|
||||
CRYPTO_set_dynlock_lock_callback(lock_function);
|
||||
CRYPTO_set_dynlock_destroy_callback(destroy_function);
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
mutex = malloc(sizeof(pthread_mutex_t) * num_locks);
|
||||
for (i = 0; i < num_locks; i++)
|
||||
{
|
||||
pthread_mutex_init(&mutex[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cleanup OpenSSL threading locks
|
||||
*/
|
||||
static void threading_cleanup()
|
||||
{
|
||||
int i, num_locks;
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
for (i = 0; i < num_locks; i++)
|
||||
{
|
||||
pthread_mutex_destroy(&mutex[i]);
|
||||
}
|
||||
free(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of openssl_plugin_t.destroy
|
||||
*/
|
||||
@@ -68,6 +181,8 @@ static void destroy(private_openssl_plugin_t *this)
|
||||
ENGINE_cleanup();
|
||||
EVP_cleanup();
|
||||
|
||||
threading_cleanup();
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -80,6 +195,8 @@ plugin_t *plugin_create()
|
||||
|
||||
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||
|
||||
threading_init();
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
/* activate support for hardware accelerators */
|
||||
|
||||
Reference in New Issue
Block a user