3 ** crypto.c developed by Stephen Lombardo (Zetetic LLC)
4 ** sjlombardo at zetetic dot net
7 ** Copyright (c) 2009, ZETETIC LLC
8 ** All rights reserved.
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.
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.
34 #ifdef SQLITE_HAS_CODEC
37 #include "sqliteInt.h"
41 const char* codec_get_cipher_version() {
42 return CIPHER_VERSION
;
45 /* Generate code to return a string value */
46 void codec_vdbe_return_static_string(Parse
*pParse
, const char *zLabel
, const char *value
){
47 Vdbe
*v
= sqlite3GetVdbe(pParse
);
48 sqlite3VdbeSetNumCols(v
, 1);
49 sqlite3VdbeSetColName(v
, 0, COLNAME_NAME
, zLabel
, SQLITE_STATIC
);
50 sqlite3VdbeAddOp4(v
, OP_String8
, 0, 1, 0, value
, 0);
51 sqlite3VdbeAddOp2(v
, OP_ResultRow
, 1, 1);
54 int codec_set_kdf_iter(sqlite3
* db
, int nDb
, int kdf_iter
, int for_ctx
) {
55 struct Db
*pDb
= &db
->aDb
[nDb
];
56 CODEC_TRACE(("codec_set_kdf_iter: entered db=%p nDb=%d kdf_iter=%d for_ctx=%d\n", db
, nDb
, kdf_iter
, for_ctx
));
60 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
61 if(ctx
) return sqlcipher_codec_ctx_set_kdf_iter(ctx
, kdf_iter
, for_ctx
);
66 int codec_set_fast_kdf_iter(sqlite3
* db
, int nDb
, int kdf_iter
, int for_ctx
) {
67 struct Db
*pDb
= &db
->aDb
[nDb
];
68 CODEC_TRACE(("codec_set_kdf_iter: entered db=%p nDb=%d kdf_iter=%d for_ctx=%d\n", db
, nDb
, kdf_iter
, for_ctx
));
72 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
73 if(ctx
) return sqlcipher_codec_ctx_set_fast_kdf_iter(ctx
, kdf_iter
, for_ctx
);
78 static int codec_set_btree_to_codec_pagesize(sqlite3
*db
, Db
*pDb
, codec_ctx
*ctx
) {
79 int rc
, page_sz
, reserve_sz
;
81 page_sz
= sqlcipher_codec_ctx_get_pagesize(ctx
);
82 reserve_sz
= sqlcipher_codec_ctx_get_reservesize(ctx
);
84 sqlite3_mutex_enter(db
->mutex
);
85 db
->nextPagesize
= page_sz
;
87 /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else
88 sqliteBtreeSetPageSize will block the change */
89 pDb
->pBt
->pBt
->btsFlags
&= ~BTS_PAGESIZE_FIXED
;
90 CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz
, reserve_sz
));
91 rc
= sqlite3BtreeSetPageSize(pDb
->pBt
, page_sz
, reserve_sz
, 0);
92 sqlite3_mutex_leave(db
->mutex
);
96 void codec_set_default_use_hmac(int use
) {
97 sqlcipher_set_default_use_hmac(use
);
100 int codec_set_use_hmac(sqlite3
* db
, int nDb
, int use
) {
101 struct Db
*pDb
= &db
->aDb
[nDb
];
103 CODEC_TRACE(("codec_set_use_hmac: entered db=%p nDb=%d use=%d\n", db
, nDb
, use
));
108 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
110 rc
= sqlcipher_codec_ctx_set_use_hmac(ctx
, use
);
111 if(rc
!= SQLITE_OK
) return rc
;
112 /* since the use of hmac has changed, the page size may also change */
113 return codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
119 int codec_set_page_size(sqlite3
* db
, int nDb
, int size
) {
120 struct Db
*pDb
= &db
->aDb
[nDb
];
121 CODEC_TRACE(("codec_set_page_size: entered db=%p nDb=%d size=%d\n", db
, nDb
, size
));
126 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
129 rc
= sqlcipher_codec_ctx_set_pagesize(ctx
, size
);
130 if(rc
!= SQLITE_OK
) return rc
;
131 return codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
139 * when for_ctx == 0 then it will change for read
140 * when for_ctx == 1 then it will change for write
141 * when for_ctx == 2 then it will change for both
143 int codec_set_cipher_name(sqlite3
* db
, int nDb
, const char *cipher_name
, int for_ctx
) {
144 struct Db
*pDb
= &db
->aDb
[nDb
];
145 CODEC_TRACE(("codec_set_cipher_name: entered db=%p nDb=%d cipher_name=%s for_ctx=%d\n", db
, nDb
, cipher_name
, for_ctx
));
149 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
150 if(ctx
) return sqlcipher_codec_ctx_set_cipher(ctx
, cipher_name
, for_ctx
);
155 int codec_set_pass_key(sqlite3
* db
, int nDb
, const void *zKey
, int nKey
, int for_ctx
) {
156 struct Db
*pDb
= &db
->aDb
[nDb
];
157 CODEC_TRACE(("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db
, nDb
, (char *)zKey
, nKey
, for_ctx
));
160 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
161 if(ctx
) return sqlcipher_codec_ctx_set_pass(ctx
, zKey
, nKey
, for_ctx
);
167 * sqlite3Codec can be called in multiple modes.
168 * encrypt mode - expected to return a pointer to the
169 * encrypted data without altering pData.
170 * decrypt mode - expected to return a pointer to pData, with
171 * the data decrypted in the input buffer
173 void* sqlite3Codec(void *iCtx
, void *data
, Pgno pgno
, int mode
) {
174 codec_ctx
*ctx
= (codec_ctx
*) iCtx
;
175 int offset
= 0, rc
= 0;
176 int page_sz
= sqlcipher_codec_ctx_get_pagesize(ctx
);
177 unsigned char *pData
= (unsigned char *) data
;
178 void *buffer
= sqlcipher_codec_ctx_get_data(ctx
);
179 void *kdf_salt
= sqlcipher_codec_ctx_get_kdf_salt(ctx
);
180 CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno
, mode
, page_sz
));
182 /* call to derive keys if not present yet */
183 if((rc
= sqlcipher_codec_key_derive(ctx
)) != SQLITE_OK
) {
184 sqlcipher_codec_ctx_set_error(ctx
, rc
);
188 if(pgno
== 1) offset
= FILE_HEADER_SZ
; /* adjust starting pointers in data page for header offset on first page*/
190 CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n", mode
, offset
));
192 case 0: /* decrypt */
195 if(pgno
== 1) memcpy(buffer
, SQLITE_FILE_HEADER
, FILE_HEADER_SZ
); /* copy file header to the first 16 bytes of the page */
196 rc
= sqlcipher_page_cipher(ctx
, CIPHER_READ_CTX
, pgno
, CIPHER_DECRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
197 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
198 memcpy(pData
, buffer
, page_sz
); /* copy buffer data back to pData and return */
201 case 6: /* encrypt */
202 if(pgno
== 1) memcpy(buffer
, kdf_salt
, FILE_HEADER_SZ
); /* copy salt to output buffer */
203 rc
= sqlcipher_page_cipher(ctx
, CIPHER_WRITE_CTX
, pgno
, CIPHER_ENCRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
204 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
205 return buffer
; /* return persistent buffer data, pData remains intact */
208 if(pgno
== 1) memcpy(buffer
, kdf_salt
, FILE_HEADER_SZ
); /* copy salt to output buffer */
209 rc
= sqlcipher_page_cipher(ctx
, CIPHER_READ_CTX
, pgno
, CIPHER_ENCRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
210 if(rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, rc
);
211 return buffer
; /* return persistent buffer data, pData remains intact */
219 void sqlite3FreeCodecArg(void *pCodecArg
) {
220 codec_ctx
*ctx
= (codec_ctx
*) pCodecArg
;
221 if(pCodecArg
== NULL
) return;
222 sqlcipher_codec_ctx_free(&ctx
); // wipe and free allocated memory for the context
225 int sqlite3CodecAttach(sqlite3
* db
, int nDb
, const void *zKey
, int nKey
) {
226 struct Db
*pDb
= &db
->aDb
[nDb
];
228 CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb
, (char *)zKey
, nKey
));
230 sqlcipher_activate();
232 if(nKey
&& zKey
&& pDb
->pBt
) {
234 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
235 sqlite3_file
*fd
= sqlite3Pager_get_fd(pPager
);
238 /* point the internal codec argument against the contet to be prepared */
239 rc
= sqlcipher_codec_ctx_init(&ctx
, pDb
, pDb
->pBt
->pBt
->pPager
, fd
, zKey
, nKey
);
241 sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb
->pBt
), sqlite3Codec
, NULL
, sqlite3FreeCodecArg
, (void *) ctx
);
243 codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
245 /* force secure delete. This has the benefit of wiping internal data when deleted
246 and also ensures that all pages are written to disk (i.e. not skipped by
247 sqlite3PagerDontWrite optimizations) */
248 sqlite3BtreeSecureDelete(pDb
->pBt
, 1);
250 /* if fd is null, then this is an in-memory database and
251 we dont' want to overwrite the AutoVacuum settings
252 if not null, then set to the default */
253 sqlite3_mutex_enter(db
->mutex
);
255 sqlite3BtreeSetAutoVacuum(pDb
->pBt
, SQLITE_DEFAULT_AUTOVACUUM
);
257 sqlite3_mutex_leave(db
->mutex
);
262 void sqlite3_activate_see(const char* in
) {
263 /* do nothing, security enhancements are always active */
266 int sqlite3_key(sqlite3
*db
, const void *pKey
, int nKey
) {
267 CODEC_TRACE(("sqlite3_key: entered db=%p pKey=%s nKey=%d\n", db
, (char *)pKey
, nKey
));
268 /* attach key if db and pKey are not null and nKey is > 0 */
269 if(db
&& pKey
&& nKey
) {
270 sqlite3CodecAttach(db
, 0, pKey
, nKey
); // operate only on the main db
277 ** Given a database, this will reencrypt the database using a new key.
278 ** There is only one possible modes of operation - to encrypt a database
279 ** that is already encrpyted. If the database is not already encrypted
280 ** this should do nothing
281 ** The proposed logic for this function follows:
282 ** 1. Determine if the database is already encryptped
283 ** 2. If there is NOT already a key present do nothing
284 ** 3. If there is a key present, re-encrypt the database with the new key
286 int sqlite3_rekey(sqlite3
*db
, const void *pKey
, int nKey
) {
287 CODEC_TRACE(("sqlite3_rekey: entered db=%p pKey=%s, nKey=%d\n", db
, (char *)pKey
, nKey
));
288 sqlcipher_activate();
289 if(db
&& pKey
&& nKey
) {
290 struct Db
*pDb
= &db
->aDb
[0];
291 CODEC_TRACE(("sqlite3_rekey: database pDb=%p\n", pDb
));
297 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
299 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
302 /* there was no codec attached to this database, so this should do nothing! */
303 CODEC_TRACE(("sqlite3_rekey: no codec attached to db, exiting\n"));
307 sqlite3_mutex_enter(db
->mutex
);
309 codec_set_pass_key(db
, 0, pKey
, nKey
, CIPHER_WRITE_CTX
);
311 /* do stuff here to rewrite the database
312 ** 1. Create a transaction on the database
313 ** 2. Iterate through each page, reading it and then writing it.
314 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
315 ** note: don't deallocate rekey since it may be used in a subsequent iteration
317 rc
= sqlite3BtreeBeginTrans(pDb
->pBt
, 1); /* begin write transaction */
318 sqlite3PagerPagecount(pPager
, &page_count
);
319 for(pgno
= 1; rc
== SQLITE_OK
&& pgno
<= page_count
; pgno
++) { /* pgno's start at 1 see pager.c:pagerAcquire */
320 if(!sqlite3pager_is_mj_pgno(pPager
, pgno
)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
321 rc
= sqlite3PagerGet(pPager
, pgno
, &page
);
322 if(rc
== SQLITE_OK
) { /* write page see pager_incr_changecounter for example */
323 rc
= sqlite3PagerWrite(page
);
324 if(rc
== SQLITE_OK
) {
325 sqlite3PagerUnref(page
);
327 CODEC_TRACE(("sqlite3_rekey: error %d occurred writing page %d\n", rc
, pgno
));
330 CODEC_TRACE(("sqlite3_rekey: error %d occurred getting page %d\n", rc
, pgno
));
335 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
336 if(rc
== SQLITE_OK
) {
337 CODEC_TRACE(("sqlite3_rekey: committing\n"));
338 rc
= sqlite3BtreeCommit(pDb
->pBt
);
339 sqlcipher_codec_key_copy(ctx
, CIPHER_WRITE_CTX
);
341 CODEC_TRACE(("sqlite3_rekey: rollback\n"));
342 sqlite3BtreeRollback(pDb
->pBt
, SQLITE_ABORT_ROLLBACK
);
345 sqlite3_mutex_leave(db
->mutex
);
352 void sqlite3CodecGetKey(sqlite3
* db
, int nDb
, void **zKey
, int *nKey
) {
353 struct Db
*pDb
= &db
->aDb
[nDb
];
354 CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db
, nDb
));
358 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
360 if(ctx
) { /* if the codec has an attached codec_context user the raw key data */
361 sqlcipher_codec_get_pass(ctx
, zKey
, nKey
);