diff --git a/src/crypto.c b/src/crypto.c index 9b46a9b1..8a17b385 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -87,7 +87,6 @@ static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, } int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) { - char *pragma_cipher_deprecated_msg = "PRAGMA cipher command is deprecated, please remove from usage."; struct Db *pDb = &db->aDb[iDb]; codec_ctx *ctx = NULL; int rc; @@ -152,10 +151,9 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef if( sqlite3StrICmp(zLeft, "cipher")==0 ){ if(ctx) { if( zRight ) { - rc = sqlcipher_codec_ctx_set_cipher(ctx, zRight); // change cipher for both - codec_vdbe_return_static_string(pParse, "cipher", pragma_cipher_deprecated_msg); - sqlite3_log(SQLITE_WARNING, pragma_cipher_deprecated_msg); - return rc; + const char* message = "PRAGMA cipher is no longer supported."; + codec_vdbe_return_static_string(pParse, "cipher", message); + sqlite3_log(SQLITE_WARNING, message); }else { codec_vdbe_return_static_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx)); diff --git a/src/crypto.h b/src/crypto.h index 90b121c1..d8ab9cf5 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -54,10 +54,6 @@ #endif #endif -#ifndef CIPHER -#define CIPHER "aes-256-cbc" -#endif - #define CIPHER_DECRYPT 0 #define CIPHER_ENCRYPT 1 @@ -244,7 +240,6 @@ void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx); int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int); int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *); -int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *); const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx); void* sqlcipher_codec_ctx_get_data(codec_ctx *); diff --git a/src/crypto_cc.c b/src/crypto_cc.c index 90793e6a..d7a05191 100644 --- a/src/crypto_cc.c +++ b/src/crypto_cc.c @@ -120,10 +120,6 @@ static int sqlcipher_cc_cipher(void *ctx, int mode, unsigned char *key, int key_ return SQLITE_OK; } -static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) { - return SQLITE_OK; -} - static const char* sqlcipher_cc_get_cipher(void *ctx) { return "aes-256-cbc"; } @@ -182,7 +178,6 @@ int sqlcipher_cc_setup(sqlcipher_provider *p) { p->hmac = sqlcipher_cc_hmac; p->kdf = sqlcipher_cc_kdf; p->cipher = sqlcipher_cc_cipher; - p->set_cipher = sqlcipher_cc_set_cipher; p->get_cipher = sqlcipher_cc_get_cipher; p->get_key_sz = sqlcipher_cc_get_key_sz; p->get_iv_sz = sqlcipher_cc_get_iv_sz; diff --git a/src/crypto_impl.c b/src/crypto_impl.c index dd68da32..d93af8f5 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -423,7 +423,7 @@ static void sqlcipher_cipher_ctx_free(codec_ctx* ctx, cipher_ctx **iCtx) { } static int sqlcipher_codec_ctx_reserve_setup(codec_ctx *ctx) { - int base_reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */ + int base_reserve = ctx->iv_sz;; /* base reserve size will be IV only */ int reserve = base_reserve; ctx->hmac_sz = ctx->provider->get_hmac_sz(ctx->provider_ctx, ctx->hmac_algorithm); @@ -593,24 +593,6 @@ int sqlcipher_codec_ctx_set_pass(codec_ctx *ctx, const void *zKey, int nKey, int return SQLITE_OK; } -int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name) { - int rc; - - rc = ctx->provider->set_cipher(ctx->provider_ctx, cipher_name); - if(rc != SQLITE_OK){ - sqlcipher_codec_ctx_set_error(ctx, rc); - return rc; - } - ctx->key_sz = ctx->provider->get_key_sz(ctx->provider_ctx); - ctx->iv_sz = ctx->provider->get_iv_sz(ctx->provider_ctx); - ctx->block_sz = ctx->provider->get_block_sz(ctx->provider_ctx); - - sqlcipher_set_derive_key(ctx, 1); - - sqlcipher_codec_ctx_reserve_setup(ctx); - return SQLITE_OK; -} - const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx) { return ctx->provider->get_cipher(ctx->provider_ctx); } @@ -884,9 +866,9 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n"); if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc; - /* setup the cipher to establish the key_sz, iv_sz, etc */ - CODEC_TRACE("sqlcipher_codec_ctx_init: setting cipher\n"); - if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER)) != SQLITE_OK) return rc; + ctx->key_sz = ctx->provider->get_key_sz(ctx->provider_ctx); + ctx->iv_sz = ctx->provider->get_iv_sz(ctx->provider_ctx); + ctx->block_sz = ctx->provider->get_block_sz(ctx->provider_ctx); /* establic the size for a hex-formated key specification, containing the raw encryption key and the salt used to generate it format. will be x'hexkey...hexsalt' diff --git a/src/crypto_libtomcrypt.c b/src/crypto_libtomcrypt.c index 49bcace1..52bcd72b 100644 --- a/src/crypto_libtomcrypt.c +++ b/src/crypto_libtomcrypt.c @@ -37,10 +37,12 @@ #define FORTUNA_MAX_SZ 32 static prng_state prng; -static unsigned int ltc_init = 0; -static unsigned int ltc_ref_count = 0; +static volatile unsigned int ltc_init = 0; +static volatile unsigned int ltc_ref_count = 0; static sqlite3_mutex* ltc_rand_mutex = NULL; +#define LTC_CIPHER "rijndael" + static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) { int rc = 0; int data_to_read = length; @@ -206,14 +208,14 @@ static int sqlcipher_ltc_kdf(void *ctx, int algorithm, const unsigned char *pass } static const char* sqlcipher_ltc_get_cipher(void *ctx) { - return "rijndael"; + return "aes-256-cbc"; } static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) { int rc, cipher_idx; symmetric_CBC cbc; - if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR; + if((cipher_idx = find_cipher(LTC_CIPHER)) == -1) return SQLITE_ERROR; if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR; rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc); if(rc != CRYPT_OK) return SQLITE_ERROR; @@ -221,22 +223,18 @@ static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key return SQLITE_OK; } -static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) { - return SQLITE_OK; -} - static int sqlcipher_ltc_get_key_sz(void *ctx) { - int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx)); + int cipher_idx = find_cipher(LTC_CIPHER); return cipher_descriptor[cipher_idx].max_key_length; } static int sqlcipher_ltc_get_iv_sz(void *ctx) { - int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx)); + int cipher_idx = find_cipher(LTC_CIPHER); return cipher_descriptor[cipher_idx].block_length; } static int sqlcipher_ltc_get_block_sz(void *ctx) { - int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx)); + int cipher_idx = find_cipher(LTC_CIPHER); return cipher_descriptor[cipher_idx].block_length; } @@ -291,7 +289,6 @@ int sqlcipher_ltc_setup(sqlcipher_provider *p) { p->hmac = sqlcipher_ltc_hmac; p->kdf = sqlcipher_ltc_kdf; p->cipher = sqlcipher_ltc_cipher; - p->set_cipher = sqlcipher_ltc_set_cipher; p->get_cipher = sqlcipher_ltc_get_cipher; p->get_key_sz = sqlcipher_ltc_get_key_sz; p->get_iv_sz = sqlcipher_ltc_get_iv_sz; diff --git a/src/crypto_openssl.c b/src/crypto_openssl.c index e8a119e3..4dbb4176 100644 --- a/src/crypto_openssl.c +++ b/src/crypto_openssl.c @@ -85,6 +85,9 @@ static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) { return SQLITE_OK; } +#define OPENSSL_CIPHER "aes-256-cbc" + + /* activate and initialize sqlcipher. Most importantly, this will automatically intialize OpenSSL's EVP system if it hasn't already be externally. Note that this function may be called multiple times as new codecs are intiialized. @@ -99,7 +102,7 @@ static int sqlcipher_openssl_activate(void *ctx) { sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered static master mutex"); - if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) { + if(openssl_init_count == 0 && EVP_get_cipherbyname(OPENSSL_CIPHER) != NULL) { /* if openssl has not yet been initialized by this library, but a call to get_cipherbyname works, then the openssl library has been initialized externally already. */ @@ -265,15 +268,6 @@ static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int return SQLITE_OK; } -static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) { - openssl_ctx *o_ctx = (openssl_ctx *)ctx; - EVP_CIPHER* cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name); - if(cipher != NULL) { - o_ctx->evp_cipher = cipher; - } - return cipher != NULL ? SQLITE_OK : SQLITE_ERROR; -} - static const char* sqlcipher_openssl_get_cipher(void *ctx) { return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher); } @@ -316,10 +310,15 @@ static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) { } static int sqlcipher_openssl_ctx_init(void **ctx) { + openssl_ctx *o_ctx; + *ctx = sqlcipher_malloc(sizeof(openssl_ctx)); if(*ctx == NULL) return SQLITE_NOMEM; sqlcipher_openssl_activate(*ctx); - return SQLITE_OK; + + o_ctx = (openssl_ctx *)*ctx; + o_ctx->evp_cipher = (EVP_CIPHER *) EVP_get_cipherbyname(OPENSSL_CIPHER); + return o_ctx->evp_cipher != NULL ? SQLITE_OK : SQLITE_ERROR; } static int sqlcipher_openssl_ctx_free(void **ctx) { @@ -344,7 +343,6 @@ int sqlcipher_openssl_setup(sqlcipher_provider *p) { p->hmac = sqlcipher_openssl_hmac; p->kdf = sqlcipher_openssl_kdf; p->cipher = sqlcipher_openssl_cipher; - p->set_cipher = sqlcipher_openssl_set_cipher; p->get_cipher = sqlcipher_openssl_get_cipher; p->get_key_sz = sqlcipher_openssl_get_key_sz; p->get_iv_sz = sqlcipher_openssl_get_iv_sz; diff --git a/src/sqlcipher.h b/src/sqlcipher.h index a27095a5..f668d620 100644 --- a/src/sqlcipher.h +++ b/src/sqlcipher.h @@ -60,7 +60,6 @@ typedef struct { int (*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); int (*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); int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out); - int (*set_cipher)(void *ctx, const char *cipher_name); const char* (*get_cipher)(void *ctx); int (*get_key_sz)(void *ctx); int (*get_iv_sz)(void *ctx); diff --git a/test/crypto.test b/test/crypto.test index 1ce10238..e900d1bd 100644 --- a/test/crypto.test +++ b/test/crypto.test @@ -611,6 +611,19 @@ do_test verify-errors-for-rekey-kdf-and-cipher-changes { db close file delete -force test.db + +setup test.db "'testkey'" +do_test verify-errors-for-cipher-change { + sqlite_orig db test.db + execsql { + PRAGMA key = 'testkey'; + PRAGMA cipher = 'aes-256-ecb'; + } +} {{PRAGMA cipher is no longer supported.}} +db close +file delete -force test.db + + # create an unencrypted database, attach a new encrypted volume # copy data between, verify the encypted database is good afterwards do_test unencrypted-attach { @@ -981,7 +994,6 @@ do_test attached-database-pragmas { COMMIT; ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2'; PRAGMA db2.cipher_page_size = 8192; - PRAGMA db2.cipher = 'aes-128-cbc'; PRAGMA db2.kdf_iter = 1000; PRAGMA db2.cipher_use_hmac = OFF; CREATE TABLE db2.t1(a,b); @@ -994,12 +1006,11 @@ do_test attached-database-pragmas { execsql { PRAGMA key = 'testkey2'; PRAGMA cipher_page_size = 8192; - PRAGMA cipher = 'aes-128-cbc'; PRAGMA kdf_iter = 1000; PRAGMA cipher_use_hmac = OFF; SELECT count(*) FROM t1; } -} {{PRAGMA cipher command is deprecated, please remove from usage.} 1000} +} {1000} db close file delete -force test.db file delete -force test2.db @@ -1380,7 +1391,6 @@ do_test cipher-options-before-keys { execsql { PRAGMA kdf_iter = 1000; PRAGMA cipher_page_size = 8192; - PRAGMA cipher = 'aes-128-cbc'; PRAGMA cipher_use_hmac = OFF; PRAGMA key = 'testkey'; CREATE table t1(a,b); @@ -1903,19 +1913,6 @@ if_built_with_openssl verify-pragma-cipher-default { db close file delete -force test.db -# verify the pragma cipher -# reports a change in value -if_built_with_openssl verify-pragma-cipher-changed { - sqlite_orig db test.db - execsql { - PRAGMA key = 'test'; - PRAGMA cipher = 'AES-256-ECB'; - PRAGMA cipher; - } -} {{PRAGMA cipher command is deprecated, please remove from usage.} AES-256-ECB} -db close -file delete -force test.db - # verify the pragma cipher_hmac_salt_mask reports default do_test verify-pragma-hmac-salt-mask-reports-default { sqlite_orig db test.db @@ -2022,13 +2019,23 @@ do_test 2.0-beta-to-2.0-migration { db close file delete -force test.db +if_built_with_openssl verify-default-cipher { + sqlite_orig db test.db + execsql { + PRAGMA key='test'; + PRAGMA cipher; + } +} {AES-256-CBC} +db close +file delete -force test.db + if_built_with_libtomcrypt verify-default-cipher { sqlite_orig db test.db execsql { PRAGMA key='test'; PRAGMA cipher; } -} {rijndael} +} {aes-256-cbc} db close file delete -force test.db @@ -2276,27 +2283,6 @@ do_test attach_database_with_non_default_page_size { db close file delete -force test.db test2.db -if_built_with_openssl wont-write-database-with-invalid-cipher { - sqlite_orig db test.db - catchsql { - PRAGMA key = 'test'; - PRAGMA cipher = 'foobar'; - CREATE TABLE t1(a,b); - } -} {1 {SQL logic error}} -db close -file delete -force test.db - -if_built_with_openssl wont-write-database-with-invalid-cipher-2 { - sqlite_orig db test.db - execsql { - PRAGMA key = 'test'; - PRAGMA cipher = 'foobar'; - } -} {{PRAGMA cipher command is deprecated, please remove from usage.}} -db close -file delete -force test.db - do_test verify-cipher-export-with-trace-configured { sqlite_orig db plain.db execsql {