pragmas to override hmac salt mask and allow migration of 2.0 beta databases
This commit is contained in:
parent
2fd20b36e1
commit
caf3865b8b
Binary file not shown.
10
src/crypto.c
10
src/crypto.c
|
@ -163,6 +163,16 @@ int codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const c
|
|||
sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
|
||||
sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
|
||||
}
|
||||
}else
|
||||
if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
|
||||
if(zRight) {
|
||||
if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
|
||||
unsigned char mask = 0;
|
||||
const char *hex = zRight+2;
|
||||
cipher_hex2bin(hex,2,&mask);
|
||||
sqlcipher_set_hmac_salt_mask(mask);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *);
|
|||
void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
|
||||
|
||||
void sqlcipher_set_default_use_hmac(int use);
|
||||
void sqlcipher_set_hmac_salt_mask(unsigned char mask);
|
||||
|
||||
int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *, cipher_ctx *);
|
|||
int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *);
|
||||
|
||||
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
|
||||
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
|
||||
|
||||
static unsigned int openssl_external_init = 0;
|
||||
static unsigned int openssl_init_count = 0;
|
||||
|
@ -397,6 +398,10 @@ void sqlcipher_set_default_use_hmac(int use) {
|
|||
else default_flags &= ~CIPHER_FLAG_HMAC;
|
||||
}
|
||||
|
||||
void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
|
||||
hmac_salt_mask = mask;
|
||||
}
|
||||
|
||||
int sqlcipher_get_default_use_hmac(Parse *pParse) {
|
||||
int default_use_hmac_set = default_flags & CIPHER_FLAG_HMAC > 0;
|
||||
char *default_use_hmac = sqlite3_mprintf("%d", default_use_hmac_set);
|
||||
|
@ -749,7 +754,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
|
|||
to generate the encryption key */
|
||||
memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
|
||||
for(i = 0; i < ctx->kdf_salt_sz; i++) {
|
||||
ctx->hmac_kdf_salt[i] ^= HMAC_SALT_MASK;
|
||||
ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
|
||||
}
|
||||
|
||||
CODEC_TRACE(("codec_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",
|
||||
|
|
|
@ -1649,6 +1649,10 @@ do_test verify-pragma-cipher-default-use-hmac-off {
|
|||
execsql {
|
||||
PRAGMA cipher_default_use_hmac = off;
|
||||
PRAGMA cipher_default_use_hmac;
|
||||
-- Be sure to turn cipher_default_use_hmac
|
||||
-- back on or it will break later tests
|
||||
-- (it's a global flag)
|
||||
PRAGMA cipher_default_use_hmac = ON;
|
||||
}
|
||||
} {0}
|
||||
db close
|
||||
|
@ -1729,4 +1733,50 @@ do_test verify-pragma-cipher-changed {
|
|||
db close
|
||||
file delete -force test.db
|
||||
|
||||
# open a 2.0 beta database with 4000 round hmac kdf and 0x00
|
||||
# hmac salt mask
|
||||
# verify it can be opened
|
||||
do_test open-2.0-beta-database {
|
||||
sqlite_orig db sqlcipher-2.0-beta-testkey.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA fast_kdf_iter = 4000;
|
||||
PRAGMA cipher_hmac_salt_mask = "x'00'";
|
||||
SELECT count(*) FROM t1;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {2 test-0-0 test-0-1 test-1-0 test-1-1}
|
||||
db close
|
||||
|
||||
# open a 2.0 beta database
|
||||
# attach a new standard database
|
||||
# copy schema between the two, and verify the latter
|
||||
# can be opened
|
||||
do_test 2.0-beta-to-2.0-migration {
|
||||
sqlite_orig db sqlcipher-2.0-beta-testkey.db
|
||||
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
PRAGMA cipher_hmac_salt_mask = "x'00'";
|
||||
PRAGMA fast_kdf_iter = 4000;
|
||||
SELECT count(*) FROM sqlite_master;
|
||||
|
||||
PRAGMA cipher_hmac_salt_mask = "x'3a'";
|
||||
ATTACH DATABASE 'test.db' AS db2 KEY 'testkey';
|
||||
|
||||
CREATE TABLE db2.t1(a,b);
|
||||
INSERT INTO db2.t1 SELECT * FROM main.t1;
|
||||
DETACH DATABASE db2;
|
||||
}
|
||||
db close
|
||||
|
||||
sqlite_orig db test.db
|
||||
execsql {
|
||||
PRAGMA key = 'testkey';
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {test-0-0 test-0-1 test-1-0 test-1-1}
|
||||
db close
|
||||
file delete -force test.db
|
||||
|
||||
finish_test
|
||||
|
|
Loading…
Reference in New Issue