Merges crypto.h, crypto.c, and crypto_impl.c into sqlcipher.c
[sqlcipher.git] / src / crypto_openssl.c
blob032830242995feee6e8896539bed0fdbe4127f50
1 /*
2 ** SQLCipher
3 ** http://sqlcipher.net
4 **
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
7 **
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions are met:
10 ** * Redistributions of source code must retain the above copyright
11 ** notice, this list of conditions and the following disclaimer.
12 ** * Redistributions in binary form must reproduce the above copyright
13 ** notice, this list of conditions and the following disclaimer in the
14 ** documentation and/or other materials provided with the distribution.
15 ** * Neither the name of the ZETETIC LLC nor the
16 ** names of its contributors may be used to endorse or promote products
17 ** derived from this software without specific prior written permission.
19 ** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
20 ** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 ** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
23 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /* BEGIN SQLCIPHER */
32 #ifdef SQLITE_HAS_CODEC
33 #ifdef SQLCIPHER_CRYPTO_OPENSSL
34 #include "sqliteInt.h"
35 #include "sqlcipher.h"
36 #include <openssl/crypto.h> /* amalgamator: dontcache */
37 #include <openssl/rand.h> /* amalgamator: dontcache */
38 #include <openssl/evp.h> /* amalgamator: dontcache */
39 #include <openssl/objects.h> /* amalgamator: dontcache */
40 #include <openssl/hmac.h> /* amalgamator: dontcache */
41 #include <openssl/err.h> /* amalgamator: dontcache */
43 static unsigned int openssl_init_count = 0;
45 static void sqlcipher_openssl_log_errors() {
46 unsigned long err = 0;
47 while((err = ERR_get_error()) != 0) {
48 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_log_errors: ERR_get_error() returned %lx: %s", err, ERR_error_string(err, NULL));
52 #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
53 static HMAC_CTX *HMAC_CTX_new(void)
55 HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
56 if (ctx != NULL) {
57 HMAC_CTX_init(ctx);
59 return ctx;
62 /* Per 1.1.0 (https://wiki.openssl.org/index.php/1.1_API_Changes)
63 HMAC_CTX_free should call HMAC_CTX_cleanup, then EVP_MD_CTX_Cleanup.
64 HMAC_CTX_cleanup internally calls EVP_MD_CTX_cleanup so these
65 calls are not needed. */
66 static void HMAC_CTX_free(HMAC_CTX *ctx)
68 if (ctx != NULL) {
69 HMAC_CTX_cleanup(ctx);
70 OPENSSL_free(ctx);
73 #endif
75 static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
76 #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
77 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND");
78 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
79 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND");
80 #endif
81 RAND_add(buffer, length, 0);
82 #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
83 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND");
84 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
85 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND");
86 #endif
87 return SQLITE_OK;
90 #define OPENSSL_CIPHER EVP_aes_256_cbc()
92 /* activate and initialize sqlcipher. Most importantly, this will automatically
93 intialize OpenSSL's EVP system if it hasn't already be externally. Note that
94 this function may be called multiple times as new codecs are intiialized.
95 Thus it performs some basic counting to ensure that only the last and final
96 sqlcipher_openssl_deactivate() will free the EVP structures.
98 static int sqlcipher_openssl_activate(void *ctx) {
99 /* initialize openssl and increment the internal init counter
100 but only if it hasn't been initalized outside of SQLCipher by this program
101 e.g. on startup */
102 int rc = 0;
104 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
105 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
106 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
108 #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L)
109 ERR_load_crypto_strings();
110 #endif
112 #ifdef SQLCIPHER_FIPS
113 if(!FIPS_mode()){
114 if(!(rc = FIPS_mode_set(1))){
115 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_activate: FIPS_mode_set() returned %d", rc);
116 sqlcipher_openssl_log_errors();
119 #endif
121 openssl_init_count++;
122 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
123 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
124 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
125 return SQLITE_OK;
128 /* deactivate SQLCipher, most imporantly decremeting the activation count and
129 freeing the EVP structures on the final deactivation to ensure that
130 OpenSSL memory is cleaned up */
131 static int sqlcipher_openssl_deactivate(void *ctx) {
132 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
133 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
134 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
136 openssl_init_count--;
138 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
139 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
140 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE");
141 return SQLITE_OK;
144 static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
145 return "openssl";
148 static const char* sqlcipher_openssl_get_provider_version(void *ctx) {
149 #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L)
150 return OPENSSL_VERSION_TEXT;
151 #else
152 return OpenSSL_version(OPENSSL_VERSION);
153 #endif
156 /* generate a defined number of random bytes */
157 static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
158 int rc = 0;
159 /* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a
160 naive application doesn't use CRYPTO_set_locking_callback and
161 CRYPTO_THREADID_set_callback to ensure openssl thread safety.
162 This is simple workaround to prevent this common crash
163 but a more proper solution is that applications setup platform-appropriate
164 thread saftey in openssl externally */
165 #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
166 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND");
167 sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
168 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND");
169 #endif
170 rc = RAND_bytes((unsigned char *)buffer, length);
171 #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
172 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND");
173 sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
174 sqlcipher_log(SQLCIPHER_LOG_TRACE, SQLCIPHER_LOG_MUTEX, "sqlcipher_openssl_random: left SQLCIPHER_MUTEX_PROVIDER_RAND");
175 #endif
176 if(!rc) {
177 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_random: RAND_bytes() returned %d", rc);
178 sqlcipher_openssl_log_errors();
179 return SQLITE_ERROR;
181 return SQLITE_OK;
184 static int sqlcipher_openssl_hmac(void *ctx, int algorithm, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
185 int rc = 0;
187 #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x30000000L)
188 unsigned int outlen;
189 HMAC_CTX* hctx = NULL;
191 if(in == NULL) goto error;
193 hctx = HMAC_CTX_new();
194 if(hctx == NULL) {
195 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_CTX_new() failed");
196 sqlcipher_openssl_log_errors();
197 goto error;
200 switch(algorithm) {
201 case SQLCIPHER_HMAC_SHA1:
202 if(!(rc = HMAC_Init_ex(hctx, hmac_key, key_sz, EVP_sha1(), NULL))) {
203 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Init_ex() with key size %d and EVP_sha1() returned %d", key_sz, rc);
204 sqlcipher_openssl_log_errors();
205 goto error;
207 break;
208 case SQLCIPHER_HMAC_SHA256:
209 if(!(rc = HMAC_Init_ex(hctx, hmac_key, key_sz, EVP_sha256(), NULL))) {
210 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Init_ex() with key size %d and EVP_sha256() returned %d", key_sz, rc);
211 sqlcipher_openssl_log_errors();
212 goto error;
214 break;
215 case SQLCIPHER_HMAC_SHA512:
216 if(!(rc = HMAC_Init_ex(hctx, hmac_key, key_sz, EVP_sha512(), NULL))) {
217 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Init_ex() with key size %d and EVP_sha512() returned %d", key_sz, rc);
218 sqlcipher_openssl_log_errors();
219 goto error;
221 break;
222 default:
223 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: invalid algorithm %d", algorithm);
224 goto error;
227 if(!(rc = HMAC_Update(hctx, in, in_sz))) {
228 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Update() on 1st input buffer of %d bytes using algorithm %d returned %d", in_sz, algorithm, rc);
229 sqlcipher_openssl_log_errors();
230 goto error;
233 if(in2 != NULL) {
234 if(!(rc = HMAC_Update(hctx, in2, in2_sz))) {
235 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Update() on 2nd input buffer of %d bytes using algorithm %d returned %d", in2_sz, algorithm, rc);
236 sqlcipher_openssl_log_errors();
237 goto error;
241 if(!(rc = HMAC_Final(hctx, out, &outlen))) {
242 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: HMAC_Final() using algorithm %d returned %d", algorithm, rc);
243 sqlcipher_openssl_log_errors();
244 goto error;
247 rc = SQLITE_OK;
248 goto cleanup;
250 error:
251 rc = SQLITE_ERROR;
253 cleanup:
254 if(hctx) HMAC_CTX_free(hctx);
256 #else
257 size_t outlen;
258 EVP_MAC *mac = NULL;
259 EVP_MAC_CTX *hctx = NULL;
260 OSSL_PARAM sha1[] = { { "digest", OSSL_PARAM_UTF8_STRING, "sha1", 4, 0 }, OSSL_PARAM_END };
261 OSSL_PARAM sha256[] = { { "digest", OSSL_PARAM_UTF8_STRING, "sha256", 6, 0 }, OSSL_PARAM_END };
262 OSSL_PARAM sha512[] = { { "digest", OSSL_PARAM_UTF8_STRING, "sha512", 6, 0 }, OSSL_PARAM_END };
264 if(in == NULL) goto error;
266 mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
267 if(mac == NULL) {
268 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_fetch for HMAC failed");
269 sqlcipher_openssl_log_errors();
270 goto error;
273 hctx = EVP_MAC_CTX_new(mac);
274 if(hctx == NULL) {
275 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_CTX_new() failed");
276 sqlcipher_openssl_log_errors();
277 goto error;
280 switch(algorithm) {
281 case SQLCIPHER_HMAC_SHA1:
282 if(!(rc = EVP_MAC_init(hctx, hmac_key, key_sz, sha1))) {
283 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_init() with key size %d and sha1 returned %d", key_sz, rc);
284 sqlcipher_openssl_log_errors();
285 goto error;
287 break;
288 case SQLCIPHER_HMAC_SHA256:
289 if(!(rc = EVP_MAC_init(hctx, hmac_key, key_sz, sha256))) {
290 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_init() with key size %d and sha256 returned %d", key_sz, rc);
291 sqlcipher_openssl_log_errors();
292 goto error;
294 break;
295 case SQLCIPHER_HMAC_SHA512:
296 if(!(rc = EVP_MAC_init(hctx, hmac_key, key_sz, sha512))) {
297 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_init() with key size %d and sha512 returned %d", key_sz, rc);
298 sqlcipher_openssl_log_errors();
299 goto error;
301 break;
302 default:
303 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: invalid algorithm %d", algorithm);
304 goto error;
307 if(!(rc = EVP_MAC_update(hctx, in, in_sz))) {
308 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_update() on 1st input buffer of %d bytes using algorithm %d returned %d", in_sz, algorithm, rc);
309 sqlcipher_openssl_log_errors();
310 goto error;
313 if(in2 != NULL) {
314 if(!(rc = EVP_MAC_update(hctx, in2, in2_sz))) {
315 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: EVP_MAC_update() on 2nd input buffer of %d bytes using algorithm %d returned %d", in_sz, algorithm, rc);
316 sqlcipher_openssl_log_errors();
317 goto error;
321 if(!(rc = EVP_MAC_final(hctx, NULL, &outlen, 0))) {
322 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: 1st EVP_MAC_final() for output length calculation using algorithm %d returned %d", algorithm, rc);
323 sqlcipher_openssl_log_errors();
324 goto error;
327 if(!(rc = EVP_MAC_final(hctx, out, &outlen, outlen))) {
328 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_hmac: 2nd EVP_MAC_final() using algorithm %d returned %d", algorithm, rc);
329 sqlcipher_openssl_log_errors();
330 goto error;
333 rc = SQLITE_OK;
334 goto cleanup;
336 error:
337 rc = SQLITE_ERROR;
339 cleanup:
340 if(hctx) EVP_MAC_CTX_free(hctx);
341 if(mac) EVP_MAC_free(mac);
343 #endif
345 return rc;
348 static int sqlcipher_openssl_kdf(void *ctx, int algorithm, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
349 int rc = 0;
351 switch(algorithm) {
352 case SQLCIPHER_HMAC_SHA1:
353 if(!(rc = PKCS5_PBKDF2_HMAC((const char *)pass, pass_sz, salt, salt_sz, workfactor, EVP_sha1(), key_sz, key))) {
354 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_kdf: PKCS5_PBKDF2_HMAC() for EVP_sha1() workfactor %d and key size %d returned %d", workfactor, key_sz, rc);
355 sqlcipher_openssl_log_errors();
356 goto error;
358 break;
359 case SQLCIPHER_HMAC_SHA256:
360 if(!(rc = PKCS5_PBKDF2_HMAC((const char *)pass, pass_sz, salt, salt_sz, workfactor, EVP_sha256(), key_sz, key))) {
361 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_kdf: PKCS5_PBKDF2_HMAC() for EVP_sha256() workfactor %d and key size %d returned %d", workfactor, key_sz, rc);
362 sqlcipher_openssl_log_errors();
363 goto error;
365 break;
366 case SQLCIPHER_HMAC_SHA512:
367 if(!(rc = PKCS5_PBKDF2_HMAC((const char *)pass, pass_sz, salt, salt_sz, workfactor, EVP_sha512(), key_sz, key))) {
368 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_kdf: PKCS5_PBKDF2_HMAC() for EVP_sha512() workfactor %d and key size %d returned %d", workfactor, key_sz, rc);
369 sqlcipher_openssl_log_errors();
370 goto error;
372 break;
373 default:
374 return SQLITE_ERROR;
377 rc = SQLITE_OK;
378 goto cleanup;
379 error:
380 rc = SQLITE_ERROR;
381 cleanup:
382 return rc;
385 static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
386 int tmp_csz, csz, rc = 0;
387 EVP_CIPHER_CTX* ectx = EVP_CIPHER_CTX_new();
388 if(ectx == NULL) {
389 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CIPHER_CTX_new failed");
390 sqlcipher_openssl_log_errors();
391 goto error;
394 if(!(rc = EVP_CipherInit_ex(ectx, OPENSSL_CIPHER, NULL, NULL, NULL, mode))) {
395 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CipherInit_ex for mode %d returned %d", mode, rc);
396 sqlcipher_openssl_log_errors();
397 goto error;
400 if(!(rc = EVP_CIPHER_CTX_set_padding(ectx, 0))) { /* no padding */
401 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CIPHER_CTX_set_padding 0 returned %d", rc);
402 sqlcipher_openssl_log_errors();
403 goto error;
406 if(!(rc = EVP_CipherInit_ex(ectx, NULL, NULL, key, iv, mode))) {
407 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CipherInit_ex for mode %d returned %d", mode, rc);
408 sqlcipher_openssl_log_errors();
409 goto error;
412 if(!(rc = EVP_CipherUpdate(ectx, out, &tmp_csz, in, in_sz))) {
413 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CipherUpdate returned %d", rc);
414 sqlcipher_openssl_log_errors();
415 goto error;
418 csz = tmp_csz;
419 out += tmp_csz;
420 if(!(rc = EVP_CipherFinal_ex(ectx, out, &tmp_csz))) {
421 sqlcipher_log(SQLCIPHER_LOG_ERROR, SQLCIPHER_LOG_PROVIDER, "sqlcipher_openssl_cipher: EVP_CipherFinal_ex returned %d", rc);
422 sqlcipher_openssl_log_errors();
423 goto error;
426 csz += tmp_csz;
427 assert(in_sz == csz);
429 rc = SQLITE_OK;
430 goto cleanup;
431 error:
432 rc = SQLITE_ERROR;
433 cleanup:
434 if(ectx) EVP_CIPHER_CTX_free(ectx);
435 return rc;
438 static const char* sqlcipher_openssl_get_cipher(void *ctx) {
439 return OBJ_nid2sn(EVP_CIPHER_nid(OPENSSL_CIPHER));
442 static int sqlcipher_openssl_get_key_sz(void *ctx) {
443 return EVP_CIPHER_key_length(OPENSSL_CIPHER);
446 static int sqlcipher_openssl_get_iv_sz(void *ctx) {
447 return EVP_CIPHER_iv_length(OPENSSL_CIPHER);
450 static int sqlcipher_openssl_get_block_sz(void *ctx) {
451 return EVP_CIPHER_block_size(OPENSSL_CIPHER);
454 static int sqlcipher_openssl_get_hmac_sz(void *ctx, int algorithm) {
455 switch(algorithm) {
456 case SQLCIPHER_HMAC_SHA1:
457 return EVP_MD_size(EVP_sha1());
458 break;
459 case SQLCIPHER_HMAC_SHA256:
460 return EVP_MD_size(EVP_sha256());
461 break;
462 case SQLCIPHER_HMAC_SHA512:
463 return EVP_MD_size(EVP_sha512());
464 break;
465 default:
466 return 0;
470 static int sqlcipher_openssl_ctx_init(void **ctx) {
471 return sqlcipher_openssl_activate(*ctx);
474 static int sqlcipher_openssl_ctx_free(void **ctx) {
475 return sqlcipher_openssl_deactivate(NULL);
478 static int sqlcipher_openssl_fips_status(void *ctx) {
479 #ifdef SQLCIPHER_FIPS
480 return FIPS_mode();
481 #else
482 return 0;
483 #endif
486 int sqlcipher_openssl_setup(sqlcipher_provider *p) {
487 p->activate = sqlcipher_openssl_activate;
488 p->deactivate = sqlcipher_openssl_deactivate;
489 p->get_provider_name = sqlcipher_openssl_get_provider_name;
490 p->random = sqlcipher_openssl_random;
491 p->hmac = sqlcipher_openssl_hmac;
492 p->kdf = sqlcipher_openssl_kdf;
493 p->cipher = sqlcipher_openssl_cipher;
494 p->get_cipher = sqlcipher_openssl_get_cipher;
495 p->get_key_sz = sqlcipher_openssl_get_key_sz;
496 p->get_iv_sz = sqlcipher_openssl_get_iv_sz;
497 p->get_block_sz = sqlcipher_openssl_get_block_sz;
498 p->get_hmac_sz = sqlcipher_openssl_get_hmac_sz;
499 p->ctx_init = sqlcipher_openssl_ctx_init;
500 p->ctx_free = sqlcipher_openssl_ctx_free;
501 p->add_random = sqlcipher_openssl_add_random;
502 p->fips_status = sqlcipher_openssl_fips_status;
503 p->get_provider_version = sqlcipher_openssl_get_provider_version;
504 return SQLITE_OK;
507 #endif
508 #endif
509 /* END SQLCIPHER */