added locking mechanism for multithreaded use of OpenSSL

This commit is contained in:
Martin Willi
2008-11-03 16:14:12 +00:00
parent 4d901e3584
commit 7de6da0c88
@@ -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 */