rework hmac key derivation based on low iteration PBKDF2 with static salt mask
[sqlcipher.git] / src / crypto.c
blobcf1fdc315e1b8c360bd52a8142c69bc865b64493
1 /*
2 ** SQLCipher
3 ** crypto.c developed by Stephen Lombardo (Zetetic LLC)
4 ** sjlombardo at zetetic dot net
5 ** http://zetetic.net
6 **
7 ** Copyright (c) 2009, ZETETIC LLC
8 ** All rights reserved.
9 **
10 ** Redistribution and use in source and binary forms, with or without
11 ** modification, are permitted provided that the following conditions are met:
12 ** * Redistributions of source code must retain the above copyright
13 ** notice, this list of conditions and the following disclaimer.
14 ** * Redistributions in binary form must reproduce the above copyright
15 ** notice, this list of conditions and the following disclaimer in the
16 ** documentation and/or other materials provided with the distribution.
17 ** * Neither the name of the ZETETIC LLC nor the
18 ** names of its contributors may be used to endorse or promote products
19 ** derived from this software without specific prior written permission.
20 **
21 ** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
22 ** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 ** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
25 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 **
33 /* BEGIN CRYPTO */
34 #ifdef SQLITE_HAS_CODEC
36 #include <assert.h>
37 #include "sqliteInt.h"
38 #include "btreeInt.h"
39 #include "crypto.h"
41 int codec_set_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
42 struct Db *pDb = &db->aDb[nDb];
43 CODEC_TRACE(("codec_set_kdf_iter: entered db=%d nDb=%d kdf_iter=%d for_ctx=%d\n", db, nDb, kdf_iter, for_ctx));
45 if(pDb->pBt) {
46 codec_ctx *ctx;
47 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
48 return sqlcipher_codec_ctx_set_kdf_iter(ctx, kdf_iter, for_ctx);
50 return SQLITE_ERROR;
53 int codec_set_fast_kdf_iter(sqlite3* db, int nDb, int kdf_iter, int for_ctx) {
54 struct Db *pDb = &db->aDb[nDb];
55 CODEC_TRACE(("codec_set_kdf_iter: entered db=%d nDb=%d kdf_iter=%d for_ctx=%d\n", db, nDb, kdf_iter, for_ctx));
57 if(pDb->pBt) {
58 codec_ctx *ctx;
59 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
60 return sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, kdf_iter, for_ctx);
62 return SQLITE_ERROR;
65 static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
66 int rc, page_sz, reserve_sz;
68 page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
69 reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
71 sqlite3_mutex_enter(db->mutex);
72 db->nextPagesize = page_sz;
73 pDb->pBt->pBt->pageSizeFixed = 0;
74 CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz));
75 rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
76 sqlite3_mutex_leave(db->mutex);
77 return rc;
80 int codec_set_use_hmac(sqlite3* db, int nDb, int use) {
81 struct Db *pDb = &db->aDb[nDb];
83 CODEC_TRACE(("codec_set_use_hmac: entered db=%d nDb=%d use=%d\n", db, nDb, use));
85 if(pDb->pBt) {
86 int rc;
87 codec_ctx *ctx;
88 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
90 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, use);
91 if(rc != SQLITE_OK) return rc;
93 /* since the use of hmac has changed, the page size may also change */
94 /* Note: before forcing the page size we need to force pageSizeFixed to 0, else
95 sqliteBtreeSetPageSize will block the change */
96 return codec_set_btree_to_codec_pagesize(db, pDb, ctx);
98 return SQLITE_ERROR;
101 int codec_set_page_size(sqlite3* db, int nDb, int size) {
102 struct Db *pDb = &db->aDb[nDb];
103 CODEC_TRACE(("codec_set_page_size: entered db=%d nDb=%d size=%d\n", db, nDb, size));
105 if(pDb->pBt) {
106 int rc;
107 codec_ctx *ctx;
108 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
110 rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
111 if(rc != SQLITE_OK) return rc;
113 return codec_set_btree_to_codec_pagesize(db, pDb, ctx);
115 return SQLITE_ERROR;
120 * when for_ctx == 0 then it will change for read
121 * when for_ctx == 1 then it will change for write
122 * when for_ctx == 2 then it will change for both
124 int codec_set_cipher_name(sqlite3* db, int nDb, const char *cipher_name, int for_ctx) {
125 struct Db *pDb = &db->aDb[nDb];
126 CODEC_TRACE(("codec_set_cipher_name: entered db=%d nDb=%d cipher_name=%s for_ctx=%d\n", db, nDb, cipher_name, for_ctx));
128 if(pDb->pBt) {
129 codec_ctx *ctx;
130 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
131 return sqlcipher_codec_ctx_set_cipher(ctx, cipher_name, for_ctx);
133 return SQLITE_ERROR;
136 int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
137 struct Db *pDb = &db->aDb[nDb];
138 CODEC_TRACE(("codec_set_pass_key: entered db=%d nDb=%d cipher_name=%s nKey=%d for_ctx=%d\n", db, nDb, zKey, nKey, for_ctx));
139 if(pDb->pBt) {
140 codec_ctx *ctx;
141 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
142 return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
144 return SQLITE_ERROR;
148 * sqlite3Codec can be called in multiple modes.
149 * encrypt mode - expected to return a pointer to the
150 * encrypted data without altering pData.
151 * decrypt mode - expected to return a pointer to pData, with
152 * the data decrypted in the input buffer
154 void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
155 codec_ctx *ctx = (codec_ctx *) iCtx;
156 int offset = 0, rc = 0;
157 int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
158 unsigned char *pData = (unsigned char *) data;
159 void *buffer = sqlcipher_codec_ctx_get_data(ctx);
160 void *kdf_salt = sqlcipher_codec_ctx_get_kdf_salt(ctx);
161 CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz));
163 /* call to derive keys if not present yet */
164 if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
165 sqlcipher_codec_ctx_set_error(ctx, rc);
166 return NULL;
169 if(pgno == 1) offset = FILE_HEADER_SZ; /* adjust starting pointers in data page for header offset on first page*/
171 CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n", mode, offset));
172 switch(mode) {
173 case 0: /* decrypt */
174 case 2:
175 case 3:
176 if(pgno == 1) memcpy(buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ); /* copy file header to the first 16 bytes of the page */
177 rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
178 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
179 memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
180 return pData;
181 break;
182 case 6: /* encrypt */
183 if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */
184 rc = sqlcipher_page_cipher(ctx, CIPHER_WRITE_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
185 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
186 return buffer; /* return persistent buffer data, pData remains intact */
187 break;
188 case 7:
189 if(pgno == 1) memcpy(buffer, kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */
190 rc = sqlcipher_page_cipher(ctx, CIPHER_READ_CTX, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
191 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
192 return buffer; /* return persistent buffer data, pData remains intact */
193 break;
194 default:
195 return pData;
196 break;
200 void sqlite3FreeCodecArg(void *pCodecArg) {
201 codec_ctx *ctx = (codec_ctx *) pCodecArg;
202 if(pCodecArg == NULL) return;
203 sqlcipher_codec_ctx_free(&ctx); // wipe and free allocated memory for the context
206 int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
207 struct Db *pDb = &db->aDb[nDb];
209 CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, zKey, nKey));
211 sqlcipher_activate();
213 if(nKey && zKey && pDb->pBt) {
214 int rc;
215 Pager *pPager = pDb->pBt->pBt->pPager;
216 sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
217 codec_ctx *ctx;
219 /* point the internal codec argument against the contet to be prepared */
220 rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey);
222 sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
224 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
226 /* if fd is null, then this is an in-memory database and
227 we dont' want to overwrite the AutoVacuum settings
228 if not null, then set to the default */
229 sqlite3_mutex_enter(db->mutex);
230 if(fd != NULL) {
231 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
233 sqlite3_mutex_leave(db->mutex);
235 return SQLITE_OK;
238 void sqlite3_activate_see(const char* in) {
239 /* do nothing, security enhancements are always active */
242 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
243 CODEC_TRACE(("sqlite3_key: entered db=%d pKey=%s nKey=%d\n", db, pKey, nKey));
244 /* attach key if db and pKey are not null and nKey is > 0 */
245 if(db && pKey && nKey) {
246 sqlite3CodecAttach(db, 0, pKey, nKey); // operate only on the main db
247 return SQLITE_OK;
249 return SQLITE_ERROR;
252 /* sqlite3_rekey
253 ** Given a database, this will reencrypt the database using a new key.
254 ** There is only one possible modes of operation - to encrypt a database
255 ** that is already encrpyted. If the database is not already encrypted
256 ** this should do nothing
257 ** The proposed logic for this function follows:
258 ** 1. Determine if the database is already encryptped
259 ** 2. If there is NOT already a key present do nothing
260 ** 3. If there is a key present, re-encrypt the database with the new key
262 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
263 CODEC_TRACE(("sqlite3_rekey: entered db=%d pKey=%s, nKey=%d\n", db, pKey, nKey));
264 sqlcipher_activate();
265 if(db && pKey && nKey) {
266 struct Db *pDb = &db->aDb[0];
267 CODEC_TRACE(("sqlite3_rekey: database pDb=%d\n", pDb));
268 if(pDb->pBt) {
269 codec_ctx *ctx;
270 int rc, page_count;
271 Pgno pgno;
272 PgHdr *page;
273 Pager *pPager = pDb->pBt->pBt->pPager;
275 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
277 if(ctx == NULL) {
278 /* there was no codec attached to this database, so this should do nothing! */
279 CODEC_TRACE(("sqlite3_rekey: no codec attached to db, exiting\n"));
280 return SQLITE_OK;
283 sqlite3_mutex_enter(db->mutex);
285 codec_set_pass_key(db, 0, pKey, nKey, CIPHER_WRITE_CTX);
287 /* do stuff here to rewrite the database
288 ** 1. Create a transaction on the database
289 ** 2. Iterate through each page, reading it and then writing it.
290 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
291 ** note: don't deallocate rekey since it may be used in a subsequent iteration
293 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
294 sqlite3PagerPagecount(pPager, &page_count);
295 for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
296 if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
297 rc = sqlite3PagerGet(pPager, pgno, &page);
298 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
299 rc = sqlite3PagerWrite(page);
300 //printf("sqlite3PagerWrite(%d)\n", pgno);
301 if(rc == SQLITE_OK) {
302 sqlite3PagerUnref(page);
308 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
309 if(rc == SQLITE_OK) {
310 CODEC_TRACE(("sqlite3_rekey: committing\n"));
311 rc = sqlite3BtreeCommit(pDb->pBt);
312 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
313 } else {
314 CODEC_TRACE(("sqlite3_rekey: rollback\n"));
315 sqlite3BtreeRollback(pDb->pBt);
318 sqlite3_mutex_leave(db->mutex);
320 return SQLITE_OK;
322 return SQLITE_ERROR;
325 void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
326 struct Db *pDb = &db->aDb[nDb];
327 CODEC_TRACE(("sqlite3CodecGetKey: entered db=%d, nDb=%d\n", db, nDb));
329 if( pDb->pBt ) {
330 codec_ctx *ctx;
331 sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
333 if(ctx) { /* if the codec has an attached codec_context user the raw key data */
334 sqlcipher_codec_get_pass(ctx, zKey, nKey);
335 } else {
336 *zKey = NULL;
337 *nKey = 0;
343 /* END CRYPTO */
344 #endif