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 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
));
47 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
48 return sqlcipher_codec_ctx_set_kdf_iter(ctx
, kdf_iter
, for_ctx
);
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
));
59 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
60 return sqlcipher_codec_ctx_set_fast_kdf_iter(ctx
, kdf_iter
, for_ctx
);
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
);
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
));
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
);
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
));
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
);
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
));
130 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
131 return sqlcipher_codec_ctx_set_cipher(ctx
, cipher_name
, for_ctx
);
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
));
141 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
142 return sqlcipher_codec_ctx_set_pass(ctx
, zKey
, nKey
, for_ctx
);
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
);
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
));
173 case 0: /* decrypt */
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 */
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 */
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 */
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
) {
215 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
216 sqlite3_file
*fd
= sqlite3Pager_get_fd(pPager
);
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
);
231 sqlite3BtreeSetAutoVacuum(pDb
->pBt
, SQLITE_DEFAULT_AUTOVACUUM
);
233 sqlite3_mutex_leave(db
->mutex
);
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
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
));
273 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
275 sqlite3pager_get_codec(pDb
->pBt
->pBt
->pPager
, (void **) &ctx
);
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"));
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
);
314 CODEC_TRACE(("sqlite3_rekey: rollback\n"));
315 sqlite3BtreeRollback(pDb
->pBt
);
318 sqlite3_mutex_leave(db
->mutex
);
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
));
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
);