@@ -81,6 +81,9 @@ int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char
8181
8282static unsigned int default_flags = DEFAULT_CIPHER_FLAGS ;
8383
84+ static unsigned int openssl_external_init = 0 ;
85+ static unsigned int openssl_init_count = 0 ;
86+
8487struct codec_ctx {
8588 int kdf_salt_sz ;
8689 int page_sz ;
@@ -94,12 +97,40 @@ struct codec_ctx {
9497
9598void sqlcipher_activate () {
9699 sqlite3_mutex_enter (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
97- if (EVP_get_cipherbyname (CIPHER ) == NULL ) {
98- OpenSSL_add_all_algorithms ();
100+
101+ /* we'll initialize openssl and increment the internal init counter
102+ but only if it hasn't been initalized outside of SQLCipher by this program
103+ e.g. on startup */
104+ if (openssl_init_count == 0 && EVP_get_cipherbyname (CIPHER ) != NULL ) {
105+ openssl_external_init = 1 ;
106+ }
107+
108+ if (openssl_external_init == 0 ) {
109+ if (openssl_init_count == 0 ) {
110+ OpenSSL_add_all_algorithms ();
111+ }
112+ openssl_init_count ++ ;
99113 }
100114 sqlite3_mutex_leave (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
101115}
102116
117+ void sqlcipher_deactivate () {
118+ sqlite3_mutex_enter (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
119+ /* If it is initialized externally, then the init counter should never be greater than zero.
120+ This should prevent SQLCipher from "cleaning up" openssl
121+ when something else in the program might be using it. */
122+ if (openssl_external_init == 0 ) {
123+ openssl_init_count -- ;
124+ /* if the counter reaches zero after it's decremented release EVP memory
125+ Note: this code will only be reached if OpensSSL_add_all_algorithms()
126+ is called by SQLCipher internally. */
127+ if (openssl_init_count == 0 ) {
128+ EVP_cleanup ();
129+ }
130+ }
131+ sqlite3_mutex_leave (sqlite3MutexAlloc (SQLITE_MUTEX_STATIC_MASTER ));
132+ }
133+
103134/* fixed time zero memory check tests every position of a memory segement
104135 matches a single value (i.e. the memory is all zeros)*/
105136int sqlcipher_ismemset (const unsigned char * a0 , unsigned char value , int len ) {
0 commit comments