aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index d4e0f6fa9..a159cd5fa 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -17,6 +17,8 @@
#include <openssl/evp.h>
#include <openssl/engine.h>
+#include <openssl/crypto.h>
+#include <pthread.h>
#include "openssl_plugin.h"
@@ -41,9 +43,120 @@ 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
*/
static void destroy(private_openssl_plugin_t *this)
@@ -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 */