rework hmac key derivation based on low iteration PBKDF2 with static salt mask

This commit is contained in:
Stephen Lombardo 2012-01-12 23:42:55 -05:00
parent 9c0dd8d449
commit f7591e02fe
5 changed files with 28 additions and 33 deletions

View File

@ -50,14 +50,14 @@ int codec_set_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
return SQLITE_ERROR;
}
int codec_set_hmac_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
int codec_set_fast_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
struct Db *pDb = &db->aDb[nDb];
CODEC_TRACE(("codec_set_kdf_iter: entered db=%d nDb=%d kdf_iter=%d for_ctx=%d\n", db, nDb, kdf_iter, for_ctx));
if(pDb->pBt) {
codec_ctx *ctx;
sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
return sqlcipher_codec_ctx_set_hmac_kdf_iter(ctx, kdf_iter, for_ctx);
return sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, kdf_iter, for_ctx);
}
return SQLITE_ERROR;
}

View File

@ -56,10 +56,11 @@
#define DEFAULT_USE_HMAC 1
#endif
/* by default, sqlcipher will use an equal number of rounds to generate
the HMAC key as it will to generate the encryption key */
#ifndef HMAC_PBKDF2_ITER
#define HMAC_PBKDF2_ITER PBKDF2_ITER
/* by default, sqlcipher will use a reduced number of iterations to generate
the HMAC key / or transform a raw cipher key
*/
#ifndef FAST_PBKDF2_ITER
#define FAST_PBKDF2_ITER 2
#endif
/* this if a fixed random array that will be xor'd with the database salt to ensure that the
@ -67,12 +68,8 @@
the encryption key. This can be overridden at compile time but it will make the resulting
binary incompatible with the default builds when using HMAC. A future version of SQLcipher
will likely allow this to be defined at runtime via pragma */
#ifndef HMAC_FIXED_SALT
#define HMAC_FIXED_SALT {42,172,104,131,19,119,84,255,184,238,54,135,186,222,53,250}
#endif
#ifndef HMAC_FIXED_SALT_SZ
#define HMAC_FIXED_SALT_SZ 16
#ifndef HMAC_SALT_MASK
#define HMAC_SALT_MASK 0x3a
#endif
#ifdef CODEC_DEBUG
@ -144,7 +141,7 @@ int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx);
int sqlcipher_codec_ctx_set_hmac_kdf_iter(codec_ctx *, int, int);
int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *, int, int);
int sqlcipher_codec_ctx_set_cipher(codec_ctx *, const char *, int);

View File

@ -47,8 +47,6 @@
#endif
#endif
static unsigned char cipher_hmac_fixed_salt[HMAC_FIXED_SALT_SZ] = HMAC_FIXED_SALT;
/* the default implementation of SQLCipher uses a cipher_ctx
to keep track of read / write state separately. The following
struct and associated functions are defined here */
@ -58,7 +56,7 @@ typedef struct {
EVP_CIPHER_CTX ectx;
HMAC_CTX hctx;
int kdf_iter;
int hmac_kdf_iter;
int fast_kdf_iter;
int key_sz;
int iv_sz;
int block_sz;
@ -205,7 +203,7 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
c1->evp_cipher == c2->evp_cipher
&& c1->iv_sz == c2->iv_sz
&& c1->kdf_iter == c2->kdf_iter
&& c1->hmac_kdf_iter == c2->hmac_kdf_iter
&& c1->fast_kdf_iter == c2->fast_kdf_iter
&& c1->key_sz == c2->key_sz
&& c1->pass_sz == c2->pass_sz
&& (
@ -313,11 +311,11 @@ int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx)
return SQLITE_OK;
}
int sqlcipher_codec_ctx_set_hmac_kdf_iter(codec_ctx *ctx, int hmac_kdf_iter, int for_ctx) {
int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int for_ctx) {
cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
int rc;
c_ctx->hmac_kdf_iter = hmac_kdf_iter;
c_ctx->fast_kdf_iter = fast_kdf_iter;
c_ctx->derive_key = 1;
if(for_ctx == 2)
@ -429,7 +427,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_hmac_kdf_iter(ctx, HMAC_PBKDF2_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;
/* Use HMAC signatures by default. Note that codec_set_use_hmac will implicity call
@ -561,9 +559,9 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
CODEC_TRACE(("codec_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
ctx->kdf_salt=%d ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
ctx->hmac_kdf_salt=%d, c_ctx->hmac_kdf_iter=%d c_ctx->key_sz=%d\n",
ctx->hmac_kdf_salt=%d, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n",
c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
ctx->hmac_kdf_salt, c_ctx->hmac_kdf_iter, c_ctx->key_sz));
ctx->hmac_kdf_salt, c_ctx->fast_kdf_iter, c_ctx->key_sz));
if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
@ -573,7 +571,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
CODEC_TRACE(("codec_key_derive: deriving key from hex\n"));
cipher_hex2bin(z, n, c_ctx->key);
} else {
CODEC_TRACE(("codec_key_derive: deriving key using PBKDF2\n"));
CODEC_TRACE(("codec_key_derive: deriving key using full PBKDF2 with %d iterations\n", c_ctx->kdf_iter));
PKCS5_PBKDF2_HMAC_SHA1( c_ctx->pass, c_ctx->pass_sz,
ctx->kdf_salt, ctx->kdf_salt_sz,
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) {
easy to derive and publically known, is not the same as the salt used
to generate the encryption key */
memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
for(i = 0; i < HMAC_FIXED_SALT_SZ && i < ctx->kdf_salt_sz; i++) {
ctx->hmac_kdf_salt[i] = ctx->hmac_kdf_salt[i] ^ cipher_hmac_fixed_salt[i];
for(i = 0; i < ctx->kdf_salt_sz; i++) {
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",
HMAC_PBKDF2_ITER));
c_ctx->fast_kdf_iter));
PKCS5_PBKDF2_HMAC_SHA1( (const char*)c_ctx->key, c_ctx->key_sz,
ctx->hmac_kdf_salt, ctx->kdf_salt_sz,
c_ctx->hmac_kdf_iter, c_ctx->key_sz, c_ctx->hmac_key);
c_ctx->fast_kdf_iter, c_ctx->key_sz, c_ctx->hmac_key);
}
c_ctx->derive_key = 0;

View File

@ -1503,9 +1503,9 @@ void sqlite3Pragma(
extern int codec_set_kdf_iter(sqlite3*, int, int, int);
codec_set_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
}else
if( sqlite3StrICmp(zLeft, "hmac_kdf_iter")==0 && zRight ){
extern int codec_set_hmac_kdf_iter(sqlite3*, int, int, int);
codec_set_hmac_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0 && zRight ){
extern int codec_set_fast_kdf_iter(sqlite3*, int, int, int);
codec_set_fast_kdf_iter(db, iDb, atoi(zRight), 2); // change of RW PBKDF2 iteration
}else
if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
extern int codec_set_kdf_iter(sqlite3*, int, int, int);

View File

@ -936,7 +936,7 @@ do_test custom-hmac-kdf-iter {
execsql {
PRAGMA key = 'testkey';
PRAGMA hmac_kdf_iter = 10;
PRAGMA fast_kdf_iter = 10;
CREATE table t1(a,b);
BEGIN;
}
@ -955,7 +955,7 @@ do_test custom-hmac-kdf-iter {
execsql {
PRAGMA key = 'testkey';
PRAGMA hmac_kdf_iter = 10;
PRAGMA fast_kdf_iter = 10;
SELECT count(*) FROM t1;
}