Skip to content

Commit f7591e0

Browse files
committed
rework hmac key derivation based on low iteration PBKDF2 with static salt mask
1 parent 9c0dd8d commit f7591e0

File tree

5 files changed

+28
-33
lines changed

5 files changed

+28
-33
lines changed

src/crypto.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ int codec_set_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
5050
return SQLITE_ERROR;
5151
}
5252

53-
int codec_set_hmac_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
53+
int codec_set_fast_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
5454
struct Db *pDb = &db->aDb[nDb];
5555
CODEC_TRACE(("codec_set_kdf_iter: entered db=%d nDb=%d kdf_iter=%d for_ctx=%d\n", db, nDb, kdf_iter, for_ctx));
5656

5757
if(pDb->pBt) {
5858
codec_ctx *ctx;
5959
sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
60-
return sqlcipher_codec_ctx_set_hmac_kdf_iter(ctx, kdf_iter, for_ctx);
60+
return sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, kdf_iter, for_ctx);
6161
}
6262
return SQLITE_ERROR;
6363
}

src/crypto.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,20 @@
5656
#define DEFAULT_USE_HMAC 1
5757
#endif
5858

59-
/* by default, sqlcipher will use an equal number of rounds to generate
60-
the HMAC key as it will to generate the encryption key */
61-
#ifndef HMAC_PBKDF2_ITER
62-
#define HMAC_PBKDF2_ITER PBKDF2_ITER
59+
/* by default, sqlcipher will use a reduced number of iterations to generate
60+
the HMAC key / or transform a raw cipher key
61+
*/
62+
#ifndef FAST_PBKDF2_ITER
63+
#define FAST_PBKDF2_ITER 2
6364
#endif
6465

6566
/* this if a fixed random array that will be xor'd with the database salt to ensure that the
6667
salt passed to the HMAC key derivation function is not the same as that used to derive
6768
the encryption key. This can be overridden at compile time but it will make the resulting
6869
binary incompatible with the default builds when using HMAC. A future version of SQLcipher
6970
will likely allow this to be defined at runtime via pragma */
70-
#ifndef HMAC_FIXED_SALT
71-
#define HMAC_FIXED_SALT {42,172,104,131,19,119,84,255,184,238,54,135,186,222,53,250}
72-
#endif
73-
74-
#ifndef HMAC_FIXED_SALT_SZ
75-
#define HMAC_FIXED_SALT_SZ 16
71+
#ifndef HMAC_SALT_MASK
72+
#define HMAC_SALT_MASK 0x3a
7673
#endif
7774

7875
#ifdef CODEC_DEBUG
@@ -144,7 +141,7 @@ int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
144141
int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
145142
void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx);
146143

147-
int sqlcipher_codec_ctx_set_hmac_kdf_iter(codec_ctx *, int, int);
144+
int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int, int);
148145

149146
int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *, int);
150147

src/crypto_impl.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
#endif
4848
#endif
4949

50-
static unsigned char cipher_hmac_fixed_salt[HMAC_FIXED_SALT_SZ] = HMAC_FIXED_SALT;
51-
5250
/* the default implementation of SQLCipher uses a cipher_ctx
5351
to keep track of read / write state separately. The following
5452
struct and associated functions are defined here */
@@ -58,7 +56,7 @@ typedef struct {
5856
EVP_CIPHER_CTX ectx;
5957
HMAC_CTX hctx;
6058
int kdf_iter;
61-
int hmac_kdf_iter;
59+
int fast_kdf_iter;
6260
int key_sz;
6361
int iv_sz;
6462
int block_sz;
@@ -205,7 +203,7 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
205203
c1->evp_cipher == c2->evp_cipher
206204
&& c1->iv_sz == c2->iv_sz
207205
&& c1->kdf_iter == c2->kdf_iter
208-
&& c1->hmac_kdf_iter == c2->hmac_kdf_iter
206+
&& c1->fast_kdf_iter == c2->fast_kdf_iter
209207
&& c1->key_sz == c2->key_sz
210208
&& c1->pass_sz == c2->pass_sz
211209
&& (
@@ -313,11 +311,11 @@ int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx)
313311
return SQLITE_OK;
314312
}
315313

316-
int sqlcipher_codec_ctx_set_hmac_kdf_iter(codec_ctx *ctx, int hmac_kdf_iter, int for_ctx) {
314+
int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int for_ctx) {
317315
cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
318316
int rc;
319317

320-
c_ctx->hmac_kdf_iter = hmac_kdf_iter;
318+
c_ctx->fast_kdf_iter = fast_kdf_iter;
321319
c_ctx->derive_key = 1;
322320

323321
if(for_ctx == 2)
@@ -429,7 +427,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
429427

430428
if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
431429
if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
432-
if((rc = sqlcipher_codec_ctx_set_hmac_kdf_iter(ctx, HMAC_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
430+
if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
433431
if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc;
434432

435433
/* Use HMAC signatures by default. Note that codec_set_use_hmac will implicity call
@@ -561,19 +559,19 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
561559
int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
562560
CODEC_TRACE(("codec_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
563561
ctx->kdf_salt=%d ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
564-
ctx->hmac_kdf_salt=%d, c_ctx->hmac_kdf_iter=%d c_ctx->key_sz=%d\n",
562+
ctx->hmac_kdf_salt=%d, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n",
565563
c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
566-
ctx->hmac_kdf_salt, c_ctx->hmac_kdf_iter, c_ctx->key_sz));
564+
ctx->hmac_kdf_salt, c_ctx->fast_kdf_iter, c_ctx->key_sz));
567565

568566

569567
if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
570568
if (c_ctx->pass_sz == ((c_ctx->key_sz*2)+3) && sqlite3StrNICmp(c_ctx->pass ,"x'", 2) == 0) {
571569
int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
572-
const char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
570+
const char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
573571
CODEC_TRACE(("codec_key_derive: deriving key from hex\n"));
574572
cipher_hex2bin(z, n, c_ctx->key);
575573
} else {
576-
CODEC_TRACE(("codec_key_derive: deriving key using PBKDF2\n"));
574+
CODEC_TRACE(("codec_key_derive: deriving key using full PBKDF2 with %d iterations\n", c_ctx->kdf_iter));
577575
PKCS5_PBKDF2_HMAC_SHA1( c_ctx->pass, c_ctx->pass_sz,
578576
ctx->kdf_salt, ctx->kdf_salt_sz,
579577
c_ctx->kdf_iter, c_ctx->key_sz, c_ctx->key);
@@ -592,15 +590,15 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
592590
easy to derive and publically known, is not the same as the salt used
593591
to generate the encryption key */
594592
memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
595-
for(i = 0; i < HMAC_FIXED_SALT_SZ && i < ctx->kdf_salt_sz; i++) {
596-
ctx->hmac_kdf_salt[i] = ctx->hmac_kdf_salt[i] ^ cipher_hmac_fixed_salt[i];
593+
for(i = 0; i < ctx->kdf_salt_sz; i++) {
594+
ctx->hmac_kdf_salt[i] ^= HMAC_SALT_MASK;
597595
}
598596

599597
CODEC_TRACE(("codec_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",
600-
HMAC_PBKDF2_ITER));
598+
c_ctx->fast_kdf_iter));
601599
PKCS5_PBKDF2_HMAC_SHA1( (const char*)c_ctx->key, c_ctx->key_sz,
602600
ctx->hmac_kdf_salt, ctx->kdf_salt_sz,
603-
c_ctx->hmac_kdf_iter, c_ctx->key_sz, c_ctx->hmac_key);
601+
c_ctx->fast_kdf_iter, c_ctx->key_sz, c_ctx->hmac_key);
604602
}
605603

606604
c_ctx->derive_key = 0;

src/pragma.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,9 +1503,9 @@ void sqlite3Pragma(
15031503
extern int codec_set_kdf_iter(sqlite3*, int, int, int);
15041504
codec_set_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
15051505
}else
1506-
if( sqlite3StrICmp(zLeft, "hmac_kdf_iter")==0 && zRight ){
1507-
extern int codec_set_hmac_kdf_iter(sqlite3*, int, int, int);
1508-
codec_set_hmac_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
1506+
if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0 && zRight ){
1507+
extern int codec_set_fast_kdf_iter(sqlite3*, int, int, int);
1508+
codec_set_fast_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
15091509
}else
15101510
if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
15111511
extern int codec_set_kdf_iter(sqlite3*, int, int, int);

test/crypto.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ do_test custom-hmac-kdf-iter {
936936

937937
execsql {
938938
PRAGMA key = 'testkey';
939-
PRAGMA hmac_kdf_iter = 10;
939+
PRAGMA fast_kdf_iter = 10;
940940
CREATE table t1(a,b);
941941
BEGIN;
942942
}
@@ -955,7 +955,7 @@ do_test custom-hmac-kdf-iter {
955955

956956
execsql {
957957
PRAGMA key = 'testkey';
958-
PRAGMA hmac_kdf_iter = 10;
958+
PRAGMA fast_kdf_iter = 10;
959959
SELECT count(*) FROM t1;
960960
}
961961

0 commit comments

Comments
 (0)