Skip to content

Commit caf3865

Browse files
committed
pragmas to override hmac salt mask and allow migration of 2.0 beta databases
1 parent 2fd20b3 commit caf3865

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

sqlcipher-2.0-beta-testkey.db

2 KB
Binary file not shown.

src/crypto.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,16 @@ int codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const c
163163
sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
164164
sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
165165
}
166+
}else
167+
if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
168+
if(zRight) {
169+
if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
170+
unsigned char mask = 0;
171+
const char *hex = zRight+2;
172+
cipher_hex2bin(hex,2,&mask);
173+
sqlcipher_set_hmac_salt_mask(mask);
174+
}
175+
}
166176
}else {
167177
return 0;
168178
}

src/crypto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *);
177177
void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
178178

179179
void sqlcipher_set_default_use_hmac(int use);
180+
void sqlcipher_set_hmac_salt_mask(unsigned char mask);
180181

181182
int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
182183

src/crypto_impl.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *, cipher_ctx *);
8080
int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *);
8181

8282
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
83+
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
8384

8485
static unsigned int openssl_external_init = 0;
8586
static unsigned int openssl_init_count = 0;
@@ -397,6 +398,10 @@ void sqlcipher_set_default_use_hmac(int use) {
397398
else default_flags &= ~CIPHER_FLAG_HMAC;
398399
}
399400

401+
void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
402+
hmac_salt_mask = mask;
403+
}
404+
400405
int sqlcipher_get_default_use_hmac(Parse *pParse) {
401406
int default_use_hmac_set = default_flags & CIPHER_FLAG_HMAC > 0;
402407
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) {
749754
to generate the encryption key */
750755
memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
751756
for(i = 0; i < ctx->kdf_salt_sz; i++) {
752-
ctx->hmac_kdf_salt[i] ^= HMAC_SALT_MASK;
757+
ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
753758
}
754759

755760
CODEC_TRACE(("codec_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",

test/crypto.test

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,10 @@ do_test verify-pragma-cipher-default-use-hmac-off {
16491649
execsql {
16501650
PRAGMA cipher_default_use_hmac = off;
16511651
PRAGMA cipher_default_use_hmac;
1652+
-- Be sure to turn cipher_default_use_hmac
1653+
-- back on or it will break later tests
1654+
-- (it's a global flag)
1655+
PRAGMA cipher_default_use_hmac = ON;
16521656
}
16531657
} {0}
16541658
db close
@@ -1729,4 +1733,50 @@ do_test verify-pragma-cipher-changed {
17291733
db close
17301734
file delete -force test.db
17311735

1736+
# open a 2.0 beta database with 4000 round hmac kdf and 0x00
1737+
# hmac salt mask
1738+
# verify it can be opened
1739+
do_test open-2.0-beta-database {
1740+
sqlite_orig db sqlcipher-2.0-beta-testkey.db
1741+
execsql {
1742+
PRAGMA key = 'testkey';
1743+
PRAGMA fast_kdf_iter = 4000;
1744+
PRAGMA cipher_hmac_salt_mask = "x'00'";
1745+
SELECT count(*) FROM t1;
1746+
SELECT * FROM t1;
1747+
}
1748+
} {2 test-0-0 test-0-1 test-1-0 test-1-1}
1749+
db close
1750+
1751+
# open a 2.0 beta database
1752+
# attach a new standard database
1753+
# copy schema between the two, and verify the latter
1754+
# can be opened
1755+
do_test 2.0-beta-to-2.0-migration {
1756+
sqlite_orig db sqlcipher-2.0-beta-testkey.db
1757+
1758+
execsql {
1759+
PRAGMA key = 'testkey';
1760+
PRAGMA cipher_hmac_salt_mask = "x'00'";
1761+
PRAGMA fast_kdf_iter = 4000;
1762+
SELECT count(*) FROM sqlite_master;
1763+
1764+
PRAGMA cipher_hmac_salt_mask = "x'3a'";
1765+
ATTACH DATABASE 'test.db' AS db2 KEY 'testkey';
1766+
1767+
CREATE TABLE db2.t1(a,b);
1768+
INSERT INTO db2.t1 SELECT * FROM main.t1;
1769+
DETACH DATABASE db2;
1770+
}
1771+
db close
1772+
1773+
sqlite_orig db test.db
1774+
execsql {
1775+
PRAGMA key = 'testkey';
1776+
SELECT * FROM t1;
1777+
}
1778+
} {test-0-0 test-0-1 test-1-0 test-1-1}
1779+
db close
1780+
file delete -force test.db
1781+
17321782
finish_test

0 commit comments

Comments
 (0)