pragmas to override hmac salt mask and allow migration of 2.0 beta databases

This commit is contained in:
Stephen Lombardo 2012-11-16 11:13:14 -05:00
parent 2fd20b36e1
commit caf3865b8b
5 changed files with 67 additions and 1 deletions

BIN
sqlcipher-2.0-beta-testkey.db Executable file

Binary file not shown.

View File

@ -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;
}

View File

@ -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);

View File

@ -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",

View File

@ -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