Skip to content

Commit 1d3fc78

Browse files
Merge branch 'prerelease' into kdfiter
Conflicts: src/crypto_impl.c
2 parents a2bb641 + 15c09c0 commit 1d3fc78

3 files changed

Lines changed: 103 additions & 36 deletions

File tree

README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ an iPhone data vault and password manager (http://getstrip.com).
1818
- Good security practices (CBC mode, key derivation)
1919
- Zero-configuration and application level cryptography
2020
- Algorithms provided by the peer reviewed OpenSSL crypto library.
21+
- Configurable crypto providers
2122

2223
[Compiling]
2324

src/crypto_impl.c

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ typedef struct {
6767
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
6868
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
6969
static int default_kdf_iter = PBKDF2_ITER;
70-
70+
static unsigned int sqlcipher_activate_count = 0;
71+
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
7172
static sqlcipher_provider *default_provider = NULL;
7273

7374
struct codec_ctx {
@@ -82,13 +83,15 @@ struct codec_ctx {
8283
};
8384

8485
int sqlcipher_register_provider(sqlcipher_provider *p) {
86+
sqlite3_mutex_enter(sqlcipher_provider_mutex);
8587
if(default_provider != NULL && default_provider != p) {
8688
/* only free the current registerd provider if it has been initialized
8789
and it isn't a pointer to the same provider passed to the function
8890
(i.e. protect against a caller calling register twice for the same provider) */
8991
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
9092
}
9193
default_provider = p;
94+
sqlite3_mutex_leave(sqlcipher_provider_mutex);
9295
return SQLITE_OK;
9396
}
9497

@@ -100,35 +103,57 @@ sqlcipher_provider* sqlcipher_get_provider() {
100103
}
101104

102105
void sqlcipher_activate() {
103-
sqlcipher_provider *p;
104-
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
105-
p = sqlcipher_malloc(sizeof(sqlcipher_provider));
106-
{
106+
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
107+
108+
if(sqlcipher_provider_mutex == NULL) {
109+
/* allocate a new mutex to guard access to the provider */
110+
sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
111+
}
112+
113+
/* check to see if there is a provider registered at this point
114+
if there no provider registered at this point, register the
115+
default provider */
116+
if(sqlcipher_get_provider() == NULL) {
117+
sqlcipher_provider *p = sqlcipher_malloc(sizeof(sqlcipher_provider));
107118
#if defined (SQLCIPHER_CRYPTO_CC)
108-
extern int sqlcipher_cc_setup(sqlcipher_provider *p);
109-
sqlcipher_cc_setup(p);
119+
extern int sqlcipher_cc_setup(sqlcipher_provider *p);
120+
sqlcipher_cc_setup(p);
110121
#elif defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT)
111-
extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
112-
sqlcipher_ltc_setup(p);
122+
extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
123+
sqlcipher_ltc_setup(p);
113124
#elif defined (SQLCIPHER_CRYPTO_OPENSSL)
114-
extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
115-
sqlcipher_openssl_setup(p);
125+
extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
126+
sqlcipher_openssl_setup(p);
116127
#else
117128
#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
118129
#endif
130+
sqlcipher_register_provider(p);
119131
}
120-
sqlcipher_register_provider(p);
121132

122-
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
133+
sqlcipher_activate_count++; /* increment activation count */
134+
135+
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
123136
}
124137

125138
void sqlcipher_deactivate() {
126-
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
127-
if(default_provider != NULL) {
128-
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
129-
default_provider = NULL;
139+
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
140+
sqlcipher_activate_count--;
141+
/* if no connections are using sqlcipher, cleanup globals */
142+
if(sqlcipher_activate_count < 1) {
143+
sqlite3_mutex_enter(sqlcipher_provider_mutex);
144+
if(default_provider != NULL) {
145+
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
146+
default_provider = NULL;
147+
}
148+
sqlite3_mutex_leave(sqlcipher_provider_mutex);
149+
150+
/* last connection closed, free provider mutex*/
151+
sqlite3_mutex_free(sqlcipher_provider_mutex);
152+
sqlcipher_provider_mutex = NULL;
153+
154+
sqlcipher_activate_count = 0; /* reset activation count */
130155
}
131-
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
156+
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
132157
}
133158

134159
/* constant time memset using volitile to avoid having the memset
@@ -236,7 +261,11 @@ static int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
236261

237262
ctx->provider = (sqlcipher_provider *) sqlcipher_malloc(sizeof(sqlcipher_provider));
238263
if(ctx->provider == NULL) return SQLITE_NOMEM;
264+
265+
/* make a copy of the provider to be used for the duration of the context */
266+
sqlite3_mutex_enter(sqlcipher_provider_mutex);
239267
memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
268+
sqlite3_mutex_leave(sqlcipher_provider_mutex);
240269

241270
if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;
242271
ctx->key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);

src/crypto_openssl.c

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@ typedef struct {
4545

4646
static unsigned int openssl_external_init = 0;
4747
static unsigned int openssl_init_count = 0;
48-
48+
static sqlite3_mutex* openssl_rand_mutex = NULL;
4949

5050
static 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
*/
6167
static 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 */
81100
static 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 */
104127
static 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

108145
static 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

Comments
 (0)