Skip to content

Commit 9a6807e

Browse files
committed
deactivation routine to call EVP_cleanup
1 parent 4821558 commit 9a6807e

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/crypto.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,23 @@ void sqlite3FreeCodecArg(void *pCodecArg) {
205205
codec_ctx *ctx = (codec_ctx *) pCodecArg;
206206
if(pCodecArg == NULL) return;
207207
sqlcipher_codec_ctx_free(&ctx); // wipe and free allocated memory for the context
208+
sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
208209
}
209210

210211
int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
211212
struct Db *pDb = &db->aDb[nDb];
212213

213214
CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, (char *)zKey, nKey));
214215

215-
sqlcipher_activate();
216216

217217
if(nKey && zKey && pDb->pBt) {
218218
int rc;
219219
Pager *pPager = pDb->pBt->pBt->pPager;
220220
sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
221221
codec_ctx *ctx;
222222

223+
sqlcipher_activate(); /* perform internal initialization for sqlcipher */
224+
223225
/* point the internal codec argument against the contet to be prepared */
224226
rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey);
225227

@@ -272,7 +274,6 @@ int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
272274
*/
273275
int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
274276
CODEC_TRACE(("sqlite3_rekey: entered db=%p pKey=%s, nKey=%d\n", db, (char *)pKey, nKey));
275-
sqlcipher_activate();
276277
if(db && pKey && nKey) {
277278
struct Db *pDb = &db->aDb[0];
278279
CODEC_TRACE(("sqlite3_rekey: database pDb=%p\n", pDb));

src/crypto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ void sqlcipher_free(void *, int);
146146

147147
/* activation and initialization */
148148
void sqlcipher_activate();
149+
void sqlcipher_deactivate();
149150
int sqlcipher_codec_ctx_init(codec_ctx **, Db *, Pager *, sqlite3_file *, const void *, int);
150151
void sqlcipher_codec_ctx_free(codec_ctx **);
151152
int sqlcipher_codec_key_derive(codec_ctx *);

src/crypto_impl.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char
8181

8282
static 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+
8487
struct codec_ctx {
8588
int kdf_salt_sz;
8689
int page_sz;
@@ -94,12 +97,40 @@ struct codec_ctx {
9497

9598
void 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)*/
105136
int sqlcipher_ismemset(const unsigned char *a0, unsigned char value, int len) {

0 commit comments

Comments
 (0)