@@ -45,10 +45,16 @@ typedef struct {
4545
4646static unsigned int openssl_external_init = 0 ;
4747static unsigned int openssl_init_count = 0 ;
48-
48+ static sqlite3_mutex * openssl_rand_mutex = NULL ;
4949
5050static int sqlcipher_openssl_add_random (void * ctx , void * buffer , int length ) {
51+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
52+ sqlite3_mutex_enter (openssl_rand_mutex );
53+ #endif
5154 RAND_add (buffer , length , 0 );
55+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
56+ sqlite3_mutex_leave (openssl_rand_mutex );
57+ #endif
5258 return SQLITE_OK ;
5359}
5460
@@ -59,40 +65,57 @@ static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
5965 sqlcipher_openssl_deactivate() will free the EVP structures.
6066*/
6167static int sqlcipher_openssl_activate (void * ctx ) {
62- /* we'll initialize openssl and increment the internal init counter
68+ /* initialize openssl and increment the internal init counter
6369 but only if it hasn't been initalized outside of SQLCipher by this program
6470 e.g. on startup */
71+ sqlite3_mutex_enter (sqlite3_mutex_alloc (SQLITE_MUTEX_STATIC_MASTER ));
72+
6573 if (openssl_init_count == 0 && EVP_get_cipherbyname (CIPHER ) != NULL ) {
74+ /* if openssl has not yet been initialized by this library, but
75+ a call to get_cipherbyname works, then the openssl library
76+ has been initialized externally already. */
6677 openssl_external_init = 1 ;
6778 }
6879
69- if (openssl_external_init == 0 ) {
70- if (openssl_init_count == 0 ) {
71- OpenSSL_add_all_algorithms ();
72- }
73- openssl_init_count ++ ;
80+ if (openssl_init_count == 0 && openssl_external_init == 0 ) {
81+ /* if the library was not externally initialized, then should be now */
82+ OpenSSL_add_all_algorithms ();
7483 }
84+
85+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
86+ if (openssl_rand_mutex == NULL ) {
87+ /* allocate a mutex to guard against concurrent calls to RAND_bytes() */
88+ openssl_rand_mutex = sqlite3_mutex_alloc (SQLITE_MUTEX_FAST );
89+ }
90+ #endif
91+
92+ openssl_init_count ++ ;
93+ sqlite3_mutex_leave (sqlite3_mutex_alloc (SQLITE_MUTEX_STATIC_MASTER ));
7594 return SQLITE_OK ;
7695}
7796
7897/* deactivate SQLCipher, most imporantly decremeting the activation count and
7998 freeing the EVP structures on the final deactivation to ensure that
8099 OpenSSL memory is cleaned up */
81100static int sqlcipher_openssl_deactivate (void * ctx ) {
82- sqlite3_mutex_enter (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
83- /* If it is initialized externally, then the init counter should never be greater than zero.
84- This should prevent SQLCipher from "cleaning up" openssl
85- when something else in the program might be using it. */
86- if (openssl_external_init == 0 ) {
87- openssl_init_count -- ;
88- /* if the counter reaches zero after it's decremented release EVP memory
101+ sqlite3_mutex_enter (sqlite3_mutex_alloc (SQLITE_MUTEX_STATIC_MASTER ));
102+ openssl_init_count -- ;
103+
104+ if ( openssl_init_count == 0 ) {
105+ if (openssl_external_init == 0 ) {
106+ /* if OpenSSL hasn't be initialized externally, and the counter reaches zero
107+ after it's decremented, release EVP memory
89108 Note: this code will only be reached if OpensSSL_add_all_algorithms()
90- is called by SQLCipher internally. */
91- if ( openssl_init_count == 0 ) {
109+ is called by SQLCipher internally. This should prevent SQLCipher from
110+ "cleaning up" openssl when it was initialized externally by the program */
92111 EVP_cleanup ();
93112 }
113+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
114+ sqlite3_mutex_free (openssl_rand_mutex );
115+ openssl_rand_mutex = NULL ;
116+ #endif
94117 }
95- sqlite3_mutex_leave (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
118+ sqlite3_mutex_leave (sqlite3_mutex_alloc (SQLITE_MUTEX_STATIC_MASTER ));
96119 return SQLITE_OK ;
97120}
98121
@@ -102,7 +125,21 @@ static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
102125
103126/* generate a defined number of random bytes */
104127static int sqlcipher_openssl_random (void * ctx , void * buffer , int length ) {
105- return (RAND_bytes ((unsigned char * )buffer , length ) == 1 ) ? SQLITE_OK : SQLITE_ERROR ;
128+ int rc = 0 ;
129+ /* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a
130+ naive application doesn't use CRYPTO_set_locking_callback and
131+ CRYPTO_THREADID_set_callback to ensure openssl thread safety.
132+ This is simple workaround to prevent this common crash
133+ but a more proper solution is that applications setup platform-appropriate
134+ thread saftey in openssl externally */
135+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
136+ sqlite3_mutex_enter (openssl_rand_mutex );
137+ #endif
138+ rc = RAND_bytes ((unsigned char * )buffer , length );
139+ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
140+ sqlite3_mutex_leave (openssl_rand_mutex );
141+ #endif
142+ return (rc == 1 ) ? SQLITE_OK : SQLITE_ERROR ;
106143}
107144
108145static int sqlcipher_openssl_hmac (void * ctx , unsigned char * hmac_key , int key_sz , unsigned char * in , int in_sz , unsigned char * in2 , int in2_sz , unsigned char * out ) {
0 commit comments