diff --git a/sqlcipher-2.3-testkey.db b/sqlcipher-2.3-testkey.db new file mode 100644 index 0000000..da27623 Binary files /dev/null and b/sqlcipher-2.3-testkey.db differ diff --git a/src/crypto.c b/src/crypto.c index 2551e6b..b0cd3c2 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -110,6 +110,15 @@ int codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const c if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){ if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only }else + if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){ + if( zRight ) { + sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations + } else { + char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter()); + codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter); + sqlite3_free(kdf_iter); + } + }else if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){ if(ctx) { if( zRight ) { diff --git a/src/crypto.h b/src/crypto.h index 39924f7..5a82882 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -59,7 +59,7 @@ #define CIPHER_READWRITE_CTX 2 #ifndef PBKDF2_ITER -#define PBKDF2_ITER 4000 +#define PBKDF2_ITER 64000 #endif /* possible flags for cipher_ctx->flags */ @@ -173,6 +173,9 @@ int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int); int sqlcipher_codec_ctx_get_pagesize(codec_ctx *); int sqlcipher_codec_ctx_get_reservesize(codec_ctx *); +void sqlcipher_set_default_kdf_iter(int iter); +int sqlcipher_get_default_kdf_iter(); + int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int); int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int); diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 589696d..76bd9be 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -66,6 +66,7 @@ typedef struct { static unsigned int default_flags = DEFAULT_CIPHER_FLAGS; static unsigned char hmac_salt_mask = HMAC_SALT_MASK; +static int default_kdf_iter = PBKDF2_ITER; static sqlcipher_provider *default_provider = NULL; @@ -386,6 +387,15 @@ const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) { return c_ctx->provider->get_cipher(c_ctx->provider_ctx); } +/* set the global default KDF iteration */ +void sqlcipher_set_default_kdf_iter(int iter) { + default_kdf_iter = iter; +} + +int sqlcipher_get_default_kdf_iter() { + return default_kdf_iter; +} + int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) { cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx; int rc; @@ -572,7 +582,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f } if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc; - if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, PBKDF2_ITER, 0)) != SQLITE_OK) return rc; + if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc; if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc; if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc; diff --git a/test/crypto.test b/test/crypto.test index 90439c6..94a72f2 100644 --- a/test/crypto.test +++ b/test/crypto.test @@ -879,6 +879,7 @@ do_test open-1.1.8-database { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_use_hmac = OFF; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; SELECT * FROM t1; } @@ -893,6 +894,7 @@ do_test attach-and-copy-1.1.8 { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_use_hmac = OFF; + PRAGMA kdf_iter = 4000; ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac'; CREATE TABLE db2.t1(a,b); INSERT INTO db2.t1 SELECT * FROM main.t1; @@ -1350,20 +1352,22 @@ do_test cipher-options-before-keys { db close file delete -force test.db -# open a 1.1.8 database (no HMAC), then +# open a 1.1.8 database (no HMAC, 4K iter), then # try to open another 1.1.8 database. The # attached database should have the same hmac # setting as the original -do_test default-use-hmac-attach { +do_test default-hmac-kdf-attach { file copy -force sqlcipher-1.1.8-testkey.db test.db sqlite_orig db test.db execsql { PRAGMA cipher_default_use_hmac = OFF; + PRAGMA cipher_default_kdf_iter = 4000; PRAGMA key = 'testkey'; SELECT count(*) FROM t1; ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; SELECT count(*) from db2.t1; PRAGMA cipher_default_use_hmac = ON; + PRAGMA cipher_default_kdf_iter = 64000; } } {4 4} db close @@ -1384,12 +1388,12 @@ do_test attach-1.1.8-database-from-2.0-fails { db close file delete -force test.db -# open a 2.0 database (with HMAC), then +# open a 2.0 database (with HMAC, 4k iter), then # set the default hmac setting to OFF. # try to a 1.1.8 database. this should # succeed now that hmac is off by default # before the attach -do_test change-default-use-hmac-attach { +do_test change-default-hmac-kdf-attach { sqlite_orig db test.db execsql { PRAGMA key = 'testkey'; @@ -1402,9 +1406,11 @@ do_test change-default-use-hmac-attach { PRAGMA key = 'testkey'; SELECT count(*) FROM t1; PRAGMA cipher_default_use_hmac = OFF; + PRAGMA cipher_default_kdf_iter = 4000; ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2; SELECT count(*) from db2.t1; PRAGMA cipher_default_use_hmac = ON; + PRAGMA cipher_default_kdf_iter = 64000; } } {1 4} db close @@ -1580,12 +1586,25 @@ do_test multipage-schema-autovacuum-shortread-wal { db close file delete -force test.db +# open a 2.3 database with little endian hmac page numbers (default) +# verify it can be opened +do_test open-2.3-le-database { + sqlite_orig db sqlcipher-2.3-testkey.db + execsql { + PRAGMA key = 'testkey'; + SELECT count(*) FROM t1; + SELECT * FROM t1; + } +} {4 1 1 one one 1 2 one two} +db close + # open a 2.0 database with little endian hmac page numbers (default) # verify it can be opened do_test open-2.0-le-database { sqlite_orig db sqlcipher-2.0-le-testkey.db execsql { PRAGMA key = 'testkey'; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; SELECT * FROM t1; } @@ -1599,6 +1618,7 @@ do_test open-2.0-be-database { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_pgno = be; + PRAGMA kdf_iter = 4000; SELECT count(*) FROM t1; SELECT * FROM t1; } @@ -1615,6 +1635,7 @@ do_test be-to-le-migration { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_pgno = be; + PRAGMA kdf_iter = 4000; ATTACH DATABASE 'test.db' AS db2 KEY 'testkey'; CREATE TABLE db2.t1(a,b); INSERT INTO db2.t1 SELECT * FROM main.t1; @@ -1684,6 +1705,31 @@ do_test verify-pragma-cipher-default-use-hmac-off { db close file delete -force test.db +# verify the pragma default_cipher_kdf_iter +# is set to 64000 by default +do_test verify-pragma-cipher-default-kdf-iter-default { + sqlite_orig db test.db + execsql { + PRAGMA cipher_default_kdf_iter; + } +} {64000} +db close +file delete -force test.db + + +# verify the pragma default_cipher_kdf_ter +# reports changes +do_test verify-pragma-cipher-default-use-hmac-off { + sqlite_orig db test.db + execsql { + PRAGMA cipher_default_kdf_iter = 1000; + PRAGMA cipher_default_kdf_iter; + PRAGMA cipher_default_kdf_iter = 64000; + } +} {1000} +db close +file delete -force test.db + # verify the pragma kdf_iter # reports the default value do_test verify-pragma-kdf-iter-reports-default { @@ -1692,7 +1738,7 @@ do_test verify-pragma-kdf-iter-reports-default { PRAGMA key = 'test'; PRAGMA kdf_iter; } -} {4000} +} {64000} db close file delete -force test.db @@ -1843,6 +1889,7 @@ do_test open-2.0-beta-database { sqlite_orig db sqlcipher-2.0-beta-testkey.db execsql { PRAGMA key = 'testkey'; + PRAGMA kdf_iter = 4000; PRAGMA fast_kdf_iter = 4000; PRAGMA cipher_hmac_salt_mask = "x'00'"; SELECT count(*) FROM t1; @@ -1861,6 +1908,7 @@ do_test 2.0-beta-to-2.0-migration { execsql { PRAGMA key = 'testkey'; PRAGMA cipher_hmac_salt_mask = "x'00'"; + PRAGMA kdf_iter = 4000; PRAGMA fast_kdf_iter = 4000; SELECT count(*) FROM sqlite_master;