mirror of
https://github.com/status-im/sqlcipher.git
synced 2025-02-24 09:48:10 +00:00
move hmac setting to flags on cipher context
This commit is contained in:
parent
dbbbb7cca7
commit
7a9b9e39a1
@ -56,10 +56,14 @@
|
|||||||
#define PBKDF2_ITER 4000
|
#define PBKDF2_ITER 4000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DEFAULT_USE_HMAC
|
/* possible flags for cipher_ctx->flags */
|
||||||
#define DEFAULT_USE_HMAC 1
|
#define CIPHER_FLAG_HMAC 0x01
|
||||||
|
|
||||||
|
#ifndef DEFAULT_CIPHER_FLAGS
|
||||||
|
#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* by default, sqlcipher will use a reduced number of iterations to generate
|
/* by default, sqlcipher will use a reduced number of iterations to generate
|
||||||
the HMAC key / or transform a raw cipher key
|
the HMAC key / or transform a raw cipher key
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ typedef struct {
|
|||||||
int pass_sz;
|
int pass_sz;
|
||||||
int reserve_sz;
|
int reserve_sz;
|
||||||
int hmac_sz;
|
int hmac_sz;
|
||||||
int use_hmac;
|
unsigned int flags;
|
||||||
unsigned char *key;
|
unsigned char *key;
|
||||||
unsigned char *hmac_key;
|
unsigned char *hmac_key;
|
||||||
char *pass;
|
char *pass;
|
||||||
@ -79,7 +79,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *, cipher_ctx *);
|
|||||||
/* prototype for pager HMAC function */
|
/* prototype for pager HMAC function */
|
||||||
int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *);
|
int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *);
|
||||||
|
|
||||||
static int default_use_hmac = DEFAULT_USE_HMAC;
|
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
|
||||||
|
|
||||||
struct codec_ctx {
|
struct codec_ctx {
|
||||||
int kdf_salt_sz;
|
int kdf_salt_sz;
|
||||||
@ -185,6 +185,10 @@ int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
|
|||||||
ctx->hmac_key = (unsigned char *) sqlcipher_malloc(EVP_MAX_KEY_LENGTH);
|
ctx->hmac_key = (unsigned char *) sqlcipher_malloc(EVP_MAX_KEY_LENGTH);
|
||||||
if(ctx->key == NULL) return SQLITE_NOMEM;
|
if(ctx->key == NULL) return SQLITE_NOMEM;
|
||||||
if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
|
if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
|
||||||
|
|
||||||
|
/* setup default flags */
|
||||||
|
ctx->flags = default_flags;
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +220,7 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
|
|||||||
&& c1->fast_kdf_iter == c2->fast_kdf_iter
|
&& c1->fast_kdf_iter == c2->fast_kdf_iter
|
||||||
&& c1->key_sz == c2->key_sz
|
&& c1->key_sz == c2->key_sz
|
||||||
&& c1->pass_sz == c2->pass_sz
|
&& c1->pass_sz == c2->pass_sz
|
||||||
&& c1->use_hmac == c2->use_hmac
|
&& c1->flags == c2->flags
|
||||||
&& c1->hmac_sz == c2->hmac_sz
|
&& c1->hmac_sz == c2->hmac_sz
|
||||||
&& (
|
&& (
|
||||||
c1->pass == c2->pass
|
c1->pass == c2->pass
|
||||||
@ -339,7 +343,8 @@ int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int
|
|||||||
|
|
||||||
/* set the global default flag for HMAC */
|
/* set the global default flag for HMAC */
|
||||||
void sqlcipher_set_default_use_hmac(int use) {
|
void sqlcipher_set_default_use_hmac(int use) {
|
||||||
default_use_hmac = use;
|
if(use) default_flags |= CIPHER_FLAG_HMAC;
|
||||||
|
else default_flags &= ~CIPHER_FLAG_HMAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the codec flag for whether this individual database should be using hmac */
|
/* set the codec flag for whether this individual database should be using hmac */
|
||||||
@ -356,7 +361,15 @@ int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
|
|||||||
CODEC_TRACE(("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n",
|
CODEC_TRACE(("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n",
|
||||||
use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve));
|
use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve));
|
||||||
|
|
||||||
ctx->write_ctx->use_hmac = ctx->read_ctx->use_hmac = use;
|
|
||||||
|
if(use) {
|
||||||
|
ctx->write_ctx->flags |= CIPHER_FLAG_HMAC;
|
||||||
|
ctx->read_ctx->flags |= CIPHER_FLAG_HMAC;
|
||||||
|
} else {
|
||||||
|
ctx->write_ctx->flags &= ~CIPHER_FLAG_HMAC;
|
||||||
|
ctx->read_ctx->flags &= ~CIPHER_FLAG_HMAC;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
|
ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -449,9 +462,9 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
|
|||||||
if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_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;
|
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
|
/* Note that use_hmac is a special case that requires recalculation of page size
|
||||||
codec_set_page_size to set the default */
|
so we call set_use_hmac to perform setup */
|
||||||
if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_use_hmac)) != SQLITE_OK) return rc;
|
if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_flags & CIPHER_FLAG_HMAC)) != SQLITE_OK) return rc;
|
||||||
|
|
||||||
if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
|
if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
|
||||||
|
|
||||||
@ -524,7 +537,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
|||||||
iv_in = in + size;
|
iv_in = in + size;
|
||||||
|
|
||||||
/* hmac will be written immediately after the initialization vector. the remainder of the page reserve will contain
|
/* hmac will be written immediately after the initialization vector. the remainder of the page reserve will contain
|
||||||
random bytes. note, these pointers are only valid when use_hmac is true */
|
random bytes. note, these pointers are only valid when using hmac */
|
||||||
hmac_in = in + size + c_ctx->iv_sz;
|
hmac_in = in + size + c_ctx->iv_sz;
|
||||||
hmac_out = out + size + c_ctx->iv_sz;
|
hmac_out = out + size + c_ctx->iv_sz;
|
||||||
out_start = out; /* note the original position of the output buffer pointer, as out will be rewritten during encryption */
|
out_start = out; /* note the original position of the output buffer pointer, as out will be rewritten during encryption */
|
||||||
@ -546,7 +559,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
|||||||
memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
|
memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(c_ctx->use_hmac && (mode == CIPHER_DECRYPT)) {
|
if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT)) {
|
||||||
if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
|
if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
|
||||||
memset(out, 0, page_sz);
|
memset(out, 0, page_sz);
|
||||||
CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
|
CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
|
||||||
@ -585,7 +598,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
|||||||
EVP_CIPHER_CTX_cleanup(&c_ctx->ectx);
|
EVP_CIPHER_CTX_cleanup(&c_ctx->ectx);
|
||||||
assert(size == csz);
|
assert(size == csz);
|
||||||
|
|
||||||
if(c_ctx->use_hmac && (mode == CIPHER_ENCRYPT)) {
|
if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
|
||||||
sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out);
|
sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,7 +643,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
|
|||||||
/* if this context is setup to use hmac checks, generate a seperate and different
|
/* if this context is setup to use hmac checks, generate a seperate and different
|
||||||
key for HMAC. In this case, we use the output of the previous KDF as the input to
|
key for HMAC. In this case, we use the output of the previous KDF as the input to
|
||||||
this KDF run. This ensures a distinct but predictable HMAC key. */
|
this KDF run. This ensures a distinct but predictable HMAC key. */
|
||||||
if(c_ctx->use_hmac) {
|
if(c_ctx->flags & CIPHER_FLAG_HMAC) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* start by copying the kdf key into the hmac salt slot
|
/* start by copying the kdf key into the hmac salt slot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user