From 872fb0078fbb132c1c4abb53cc17b18f7ceb0482 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Wed, 6 Nov 2019 13:56:00 -0500 Subject: [PATCH] major rework of mutex allocation and management --- src/crypto_impl.c | 73 ++++++++++++++++-------------- src/crypto_libtomcrypt.c | 96 +++++++++++++++++++++------------------- src/crypto_nss.c | 43 ++++++------------ src/crypto_openssl.c | 83 +++++++++++----------------------- src/sqlcipher.h | 10 +++++ 5 files changed, 142 insertions(+), 163 deletions(-) diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 48899fb..a2c8c75 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -56,9 +56,15 @@ static volatile int mem_security_initialized = 0; static volatile int mem_security_activated = 0; static volatile unsigned int sqlcipher_activate_count = 0; static volatile sqlite3_mem_methods default_mem_methods; -static sqlite3_mutex* sqlcipher_provider_mutex = NULL; static sqlcipher_provider *default_provider = NULL; +static sqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT]; + +sqlite3_mutex* sqlcipher_mutex(int mutex) { + if(mutex < 0 || mutex >= SQLCIPHER_MUTEX_COUNT) return NULL; + return sqlcipher_static_mutex[mutex]; +} + static int sqlcipher_mem_init(void *pAppData) { return default_mem_methods.xInit(pAppData); } @@ -116,9 +122,9 @@ void sqlcipher_init_memmethods() { } int sqlcipher_register_provider(sqlcipher_provider *p) { - CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_enter(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered SQLCIPHER_MUTEX_PROVIDER"\n); if(default_provider != NULL && default_provider != p) { /* only free the current registerd provider if it has been initialized @@ -127,9 +133,9 @@ int sqlcipher_register_provider(sqlcipher_provider *p) { sqlcipher_free(default_provider, sizeof(sqlcipher_provider)); } default_provider = p; - CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_leave(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_register_provider: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_register_provider: left SQLCIPHER_MUTEX_PROVIDER\n"); return SQLITE_OK; } @@ -146,11 +152,12 @@ void sqlcipher_activate() { sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n"); - if(sqlcipher_provider_mutex == NULL) { - /* allocate a new mutex to guard access to the provider */ - CODEC_TRACE_MUTEX("sqlcipher_activate: allocating sqlcipher provider mutex\n"); - sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - CODEC_TRACE_MUTEX("sqlcipher_activate: allocated sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + /* allocate new mutexes */ + if(sqlcipher_activate_count == 0) { + int i; + for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) { + sqlcipher_static_mutex[i] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + } } /* check to see if there is a provider registered at this point @@ -196,30 +203,32 @@ void sqlcipher_deactivate() { sqlcipher_activate_count--; /* if no connections are using sqlcipher, cleanup globals */ if(sqlcipher_activate_count < 1) { - CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_enter(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + + CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered SQLCIPHER_MUTEX_PROVIDER\n"); if(default_provider != NULL) { sqlcipher_free(default_provider, sizeof(sqlcipher_provider)); default_provider = NULL; } - CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_leave(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_deactivate: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - - /* last connection closed, free provider mutex*/ - CODEC_TRACE_MUTEX("sqlcipher_deactivate: freeing sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_free(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_deactivate: freed sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_deactivate: left SQLCIPHER_MUTEX_PROVIDER\n"); - sqlcipher_provider_mutex = NULL; - - sqlcipher_activate_count = 0; /* reset activation count */ #ifdef SQLCIPHER_EXT sqlcipher_ext_provider_destroy(); #endif + + /* last connection closed, free mutexes */ + if(sqlcipher_activate_count == 0) { + int i; + for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) { + sqlite3_mutex_free(sqlcipher_static_mutex[i]); + } + } + sqlcipher_activate_count = 0; /* reset activation count */ } CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n"); @@ -845,15 +854,15 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, const voi if(ctx->provider == NULL) return SQLITE_NOMEM; /* make a copy of the provider to be used for the duration of the context */ - CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_enter(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered SQLCIPHER_MUTEX_PROVIDER\n"); memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider)); - CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); - sqlite3_mutex_leave(sqlcipher_provider_mutex); - CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); + CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving SQLCIPHER_MUTEX_PROVIDER\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left SQLCIPHER_MUTEX_PROVIDER\n"); CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n"); if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc; diff --git a/src/crypto_libtomcrypt.c b/src/crypto_libtomcrypt.c index 9b5e581..f49339c 100644 --- a/src/crypto_libtomcrypt.c +++ b/src/crypto_libtomcrypt.c @@ -39,7 +39,6 @@ static prng_state prng; static volatile unsigned int ltc_init = 0; static volatile unsigned int ltc_ref_count = 0; -static sqlite3_mutex* ltc_rand_mutex = NULL; #define LTC_CIPHER "rijndael" @@ -48,34 +47,37 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) { int data_to_read = length; int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ; const unsigned char * data = (const unsigned char *)buffer; -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_enter(ltc_rand_mutex); -#endif - while(data_to_read > 0){ - rc = fortuna_add_entropy(data, block_sz, &prng); - rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK; - if(rc != SQLITE_OK){ - break; - } - data_to_read -= block_sz; - data += block_sz; - block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ; + + CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + + while(data_to_read > 0){ + rc = fortuna_add_entropy(data, block_sz, &prng); + rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK; + if(rc != SQLITE_OK){ + break; } - fortuna_ready(&prng); -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_leave(ltc_rand_mutex); -#endif + data_to_read -= block_sz; + data += block_sz; + block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ; + } + fortuna_ready(&prng); + + CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + return rc; } static int sqlcipher_ltc_activate(void *ctx) { unsigned char random_buffer[FORTUNA_MAX_SZ]; -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - if(ltc_rand_mutex == NULL){ - ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - } - sqlite3_mutex_enter(ltc_rand_mutex); -#endif + + CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); if(ltc_init == 0) { if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR; @@ -86,41 +88,42 @@ static int sqlcipher_ltc_activate(void *ctx) { if(fortuna_start(&prng) != CRYPT_OK) { return SQLITE_ERROR; } + ltc_init = 1; } ltc_ref_count++; + #ifndef SQLCIPHER_TEST sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer); #endif -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_leave(ltc_rand_mutex); -#endif + if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) { return SQLITE_ERROR; } sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); + + CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + return SQLITE_OK; } static int sqlcipher_ltc_deactivate(void *ctx) { -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_enter(ltc_rand_mutex); -#endif + CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + ltc_ref_count--; if(ltc_ref_count == 0){ fortuna_done(&prng); sqlcipher_memset((void *)&prng, 0, sizeof(prng)); -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_leave(ltc_rand_mutex); - sqlite3_mutex_free(ltc_rand_mutex); - ltc_rand_mutex = NULL; -#endif } -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - else { - sqlite3_mutex_leave(ltc_rand_mutex); - } -#endif + + CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + return SQLITE_OK; } @@ -133,13 +136,16 @@ static const char* sqlcipher_ltc_get_provider_version(void *ctx) { } static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) { -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_enter(ltc_rand_mutex); -#endif + CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + fortuna_read(buffer, length, &prng); -#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND - sqlite3_mutex_leave(ltc_rand_mutex); -#endif + + CODEC_TRACE_MUTEX("sqlcipher_ltc_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_ltc_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + return SQLITE_OK; } diff --git a/src/crypto_nss.c b/src/crypto_nss.c index 5d81fca..54d2370 100644 --- a/src/crypto_nss.c +++ b/src/crypto_nss.c @@ -39,55 +39,40 @@ static NSSInitContext* nss_init_context = NULL; static unsigned int nss_init_count = 0; -static sqlite3_mutex* nss_mutex = NULL; int sqlcipher_nss_setup(sqlcipher_provider *p); static int sqlcipher_nss_activate(void *ctx) { - if(nss_mutex == NULL){ - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocating nss_mutex"); - nss_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocated nss_mutex %p", nss_mutex); - } - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex); - sqlite3_mutex_enter(nss_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); if (nss_init_context == NULL) { nss_init_context = NSS_InitContext("", "", "", "", NULL, NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT); } nss_init_count++; - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); - sqlite3_mutex_leave(nss_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } static int sqlcipher_nss_deactivate(void *ctx) { - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex); - sqlite3_mutex_enter(nss_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); nss_init_count--; if (nss_init_count == 0 && nss_init_context != NULL) { - sqlite3_mutex *temp_mutex; NSS_ShutdownContext(nss_init_context); nss_init_context = NULL; - temp_mutex = nss_mutex; - nss_mutex = NULL; - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); - sqlite3_mutex_leave(temp_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freeing nss_mutex %p", nss_mutex); - sqlite3_mutex_free(temp_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freed nss_mutex %p", nss_mutex); - } else { - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); - sqlite3_mutex_leave(nss_mutex); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); - } + } + + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } diff --git a/src/crypto_openssl.c b/src/crypto_openssl.c index ff62228..298255f 100644 --- a/src/crypto_openssl.c +++ b/src/crypto_openssl.c @@ -46,8 +46,6 @@ typedef struct { static unsigned int openssl_external_init = 0; static unsigned int openssl_init_count = 0; -static sqlite3_mutex* openssl_rand_mutex = NULL; -static sqlite3_mutex* openssl_activate_mutex = NULL; #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) static HMAC_CTX *HMAC_CTX_new(void) @@ -74,15 +72,15 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) { #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering openssl_rand_mutex %p\n", openssl_rand_mutex); - sqlite3_mutex_enter(openssl_rand_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered openssl_rand_mutex %p\n", openssl_rand_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif RAND_add(buffer, length, 0); #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving openssl_rand_mutex %p\n", openssl_rand_mutex); - sqlite3_mutex_leave(openssl_rand_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left openssl_rand_mutex %p\n", openssl_rand_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif return SQLITE_OK; } @@ -101,15 +99,9 @@ static int sqlcipher_openssl_activate(void *ctx) { but only if it hasn't been initalized outside of SQLCipher by this program e.g. on startup */ - if(openssl_activate_mutex == NULL){ - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_activate_mutex"); - openssl_activate_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocated openssl_activate_mutex %p", openssl_activate_mutex); - } - - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex); - sqlite3_mutex_enter(openssl_activate_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); if(openssl_init_count == 0 && EVP_get_cipherbyname(OPENSSL_CIPHER) != NULL) { /* if openssl has not yet been initialized by this library, but @@ -134,19 +126,10 @@ static int sqlcipher_openssl_activate(void *ctx) { #endif } -#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - if(openssl_rand_mutex == NULL) { - /* allocate a mutex to guard against concurrent calls to RAND_bytes() */ - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_rand_mutex"); - openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocated openssl_rand_mutex %p", openssl_rand_mutex); - } -#endif - openssl_init_count++; - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); - sqlite3_mutex_leave(openssl_activate_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } @@ -154,9 +137,9 @@ static int sqlcipher_openssl_activate(void *ctx) { freeing the EVP structures on the final deactivation to ensure that OpenSSL memory is cleaned up */ static int sqlcipher_openssl_deactivate(void *ctx) { - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex); - sqlite3_mutex_enter(openssl_activate_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); openssl_init_count--; if(openssl_init_count == 0) { @@ -173,25 +156,11 @@ static int sqlcipher_openssl_deactivate(void *ctx) { } else { openssl_external_init = 0; } -#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freeing openssl_rand_mutex %p", openssl_rand_mutex); - sqlite3_mutex_free(openssl_rand_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_rand_mutex %p", openssl_rand_mutex); - openssl_rand_mutex = NULL; -#endif - temp_mutex = openssl_activate_mutex; - openssl_activate_mutex = NULL; - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); - sqlite3_mutex_leave(temp_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freeing openssl_activate_mutex %p", openssl_activate_mutex); - sqlite3_mutex_free(temp_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_activate_mutex %p", openssl_activate_mutex); - } else { - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); - sqlite3_mutex_leave(openssl_activate_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); - } + } + + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } @@ -213,15 +182,15 @@ static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) { but a more proper solution is that applications setup platform-appropriate thread saftey in openssl externally */ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering openssl_rand_mutex %p", openssl_rand_mutex); - sqlite3_mutex_enter(openssl_rand_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered openssl_rand_mutex %p", openssl_rand_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif rc = RAND_bytes((unsigned char *)buffer, length); #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND - CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving openssl_rand_mutex %p", openssl_rand_mutex); - sqlite3_mutex_leave(openssl_rand_mutex); - CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left openssl_rand_mutex %p", openssl_rand_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif return (rc == 1) ? SQLITE_OK : SQLITE_ERROR; } diff --git a/src/sqlcipher.h b/src/sqlcipher.h index bf680e8..f1f868d 100644 --- a/src/sqlcipher.h +++ b/src/sqlcipher.h @@ -87,6 +87,16 @@ void sqlcipher_free(void *, int); int sqlcipher_register_provider(sqlcipher_provider *); sqlcipher_provider* sqlcipher_get_provider(void); +#define SQLCIPHER_MUTEX_PROVIDER 0 +#define SQLCIPHER_MUTEX_PROVIDER_ACTIVATE 1 +#define SQLCIPHER_MUTEX_PROVIDER_RAND 2 +#define SQLCIPHER_MUTEX_RESERVED1 3 +#define SQLCIPHER_MUTEX_RESERVED2 4 +#define SQLCIPHER_MUTEX_RESERVED3 5 +#define SQLCIPHER_MUTEX_COUNT 6 + +sqlite3_mutex* sqlcipher_mutex(int); + #endif #endif /* END SQLCIPHER */