From bcbbfce020cd186d72ca37cef9b90a260f001591 Mon Sep 17 00:00:00 2001 From: Nick Parker Date: Fri, 16 Aug 2013 11:09:18 -0500 Subject: [PATCH] Generate new salt on rekey --- src/crypto.c | 20 +++++++++++++++++--- src/crypto.h | 2 ++ src/crypto_impl.c | 8 ++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 2551e6b..a440be0 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -354,6 +354,9 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { int rc, page_count; Pgno pgno; PgHdr *page; + char *new_salt; + char *original_salt; + int kdf_salt_sz = FILE_HEADER_SZ; Pager *pPager = pDb->pBt->pBt->pPager; sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx); @@ -363,11 +366,11 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { CODEC_TRACE(("sqlite3_rekey: no codec attached to db, exiting\n")); return SQLITE_OK; } - + sqlite3_mutex_enter(db->mutex); codec_set_pass_key(db, 0, pKey, nKey, CIPHER_WRITE_CTX); - + /* do stuff here to rewrite the database ** 1. Create a transaction on the database ** 2. Iterate through each page, reading it and then writing it. @@ -375,6 +378,15 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { ** note: don't deallocate rekey since it may be used in a subsequent iteration */ rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */ + + original_salt = sqlite3_malloc(kdf_salt_sz); + memset(original_salt, 0, kdf_salt_sz); + memcpy(original_salt, sqlcipher_codec_ctx_get_kdf_salt(ctx), kdf_salt_sz); + new_salt = sqlite3_malloc(kdf_salt_sz); + memset(new_salt, 0, kdf_salt_sz); + sqlcipher_codec_ctx_random(ctx, new_salt, kdf_salt_sz); + sqlcipher_codec_ctx_set_kdf_salt(ctx, new_salt); + sqlite3PagerPagecount(pPager, &page_count); for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ @@ -399,9 +411,11 @@ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX); } else { CODEC_TRACE(("sqlite3_rekey: rollback\n")); + sqlcipher_codec_ctx_set_kdf_salt(ctx, original_salt); sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK); } - + sqlite3_free(new_salt); + sqlite3_free(original_salt); sqlite3_mutex_leave(db->mutex); } return SQLITE_OK; diff --git a/src/crypto.h b/src/crypto.h index a45b57c..5dee294 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -202,6 +202,8 @@ int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag); int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx); const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx); +void sqlcipher_codec_ctx_random(codec_ctx *ctx, void *dest, int dest_sz); +void sqlcipher_codec_ctx_set_kdf_salt(codec_ctx *ctx, void *salt); #endif #endif /* END SQLCIPHER */ diff --git a/src/crypto_impl.c b/src/crypto_impl.c index 1e7fa99..d61868e 100644 --- a/src/crypto_impl.c +++ b/src/crypto_impl.c @@ -839,5 +839,13 @@ const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) { return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx); } +void sqlcipher_codec_ctx_random(codec_ctx *ctx, void *dest, int dest_sz){ + ctx->read_ctx->provider->random(ctx->read_ctx->provider_ctx, dest, dest_sz); +} + +void sqlcipher_codec_ctx_set_kdf_salt(codec_ctx *ctx, void *salt) { + memcpy(ctx->kdf_salt, salt, ctx->kdf_salt_sz); +} + #endif /* END SQLCIPHER */