add logcat option to PRAGMA cipher_profile
[sqlcipher.git] / src / crypto.c
blob33cebd0f20554a05913e1c30992c5af63b01f683
1 /*
2 ** SQLCipher
3 ** http://sqlcipher.net
4 **
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
7 **
8 ** Redistribution and use in source and binary forms, with or without
9 ** modification, are permitted provided that the following conditions are met:
10 ** * Redistributions of source code must retain the above copyright
11 ** notice, this list of conditions and the following disclaimer.
12 ** * Redistributions in binary form must reproduce the above copyright
13 ** notice, this list of conditions and the following disclaimer in the
14 ** documentation and/or other materials provided with the distribution.
15 ** * Neither the name of the ZETETIC LLC nor the
16 ** names of its contributors may be used to endorse or promote products
17 ** derived from this software without specific prior written permission.
18 **
19 ** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
20 ** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 ** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
23 ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 **
31 /* BEGIN SQLCIPHER */
32 #ifdef SQLITE_HAS_CODEC
34 #include <assert.h>
35 #include "sqlcipher.h"
36 #include "crypto.h"
38 #ifdef SQLCIPHER_EXT
39 #include "sqlcipher_ext.h"
40 #endif
42 static void codec_vdbe_return_string(Parse *pParse, const char *zLabel, const char *value, int value_type){
43 Vdbe *v = sqlite3GetVdbe(pParse);
44 sqlite3VdbeSetNumCols(v, 1);
45 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
46 sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, value_type);
47 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
50 static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
51 int rc, page_sz, reserve_sz;
53 page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
54 reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
56 CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d", page_sz, reserve_sz);
58 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entering database mutex %p", db->mutex);
59 sqlite3_mutex_enter(db->mutex);
60 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entered database mutex %p", db->mutex);
61 db->nextPagesize = page_sz;
63 /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else
64 sqliteBtreeSetPageSize will block the change */
65 pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
66 rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
68 CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize returned %d", rc);
70 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: leaving database mutex %p", db->mutex);
71 sqlite3_mutex_leave(db->mutex);
72 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: left database mutex %p", db->mutex);
74 return rc;
77 static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
78 struct Db *pDb = &db->aDb[nDb];
79 CODEC_TRACE("codec_set_pass_key: entered db=%p nDb=%d zKey=%p nKey=%d for_ctx=%d", db, nDb, zKey, nKey, for_ctx);
80 if(pDb->pBt) {
81 codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
83 if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
85 return SQLITE_ERROR;
88 int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
89 struct Db *pDb = &db->aDb[iDb];
90 codec_ctx *ctx = NULL;
91 int rc;
93 if(pDb->pBt) {
94 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
97 CODEC_TRACE("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p", db, iDb, pParse, zLeft, zRight, ctx);
99 #ifdef SQLCIPHER_EXT
100 if( sqlite3_stricmp(zLeft, "cipher_license")==0 && zRight ){
101 char *license_result = sqlite3_mprintf("%d", sqlcipher_license_key(zRight));
102 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
103 } else
104 if( sqlite3_stricmp(zLeft, "cipher_license")==0 && !zRight ){
105 if(ctx) {
106 char *license_result = sqlite3_mprintf("%d", ctx
107 ? sqlcipher_license_key_status(ctx->provider)
108 : SQLITE_ERROR);
109 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
111 } else
112 #endif
113 #ifdef SQLCIPHER_TEST
114 if( sqlite3_stricmp(zLeft,"cipher_test_on")==0 ){
115 if( zRight ) {
116 unsigned int flags = sqlcipher_get_test_flags();
117 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
118 flags |= TEST_FAIL_ENCRYPT;
119 } else
120 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
121 flags |= TEST_FAIL_DECRYPT;
122 } else
123 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
124 flags |= TEST_FAIL_MIGRATE;
126 sqlcipher_set_test_flags(flags);
128 } else
129 if( sqlite3_stricmp(zLeft,"cipher_test_off")==0 ){
130 if( zRight ) {
131 unsigned int flags = sqlcipher_get_test_flags();
132 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
133 flags &= ~TEST_FAIL_ENCRYPT;
134 } else
135 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
136 flags &= ~TEST_FAIL_DECRYPT;
137 } else
138 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
139 flags &= ~TEST_FAIL_MIGRATE;
141 sqlcipher_set_test_flags(flags);
143 } else
144 if( sqlite3_stricmp(zLeft,"cipher_test")==0 ){
145 char *flags = sqlite3_mprintf("%u", sqlcipher_get_test_flags());
146 codec_vdbe_return_string(pParse, "cipher_test", flags, P4_DYNAMIC);
147 }else
148 if( sqlite3_stricmp(zLeft,"cipher_test_rand")==0 ){
149 if( zRight ) {
150 int rand = atoi(zRight);
151 sqlcipher_set_test_rand(rand);
152 } else {
153 char *rand = sqlite3_mprintf("%d", sqlcipher_get_test_rand());
154 codec_vdbe_return_string(pParse, "cipher_test_rand", rand, P4_DYNAMIC);
156 } else
157 #endif
158 if( sqlite3_stricmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
159 if(ctx) {
160 char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
161 codec_vdbe_return_string(pParse, "cipher_fips_status", fips_mode_status, P4_DYNAMIC);
163 } else
164 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && zRight ) {
165 if(ctx) {
166 char *deprecation = "PRAGMA cipher_store_pass is deprecated, please remove from use";
167 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
168 codec_vdbe_return_string(pParse, "cipher_store_pass", deprecation, P4_TRANSIENT);
169 sqlite3_log(SQLITE_WARNING, deprecation);
171 } else
172 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
173 if(ctx){
174 char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
175 codec_vdbe_return_string(pParse, "cipher_store_pass", store_pass_value, P4_DYNAMIC);
178 if( sqlite3_stricmp(zLeft, "cipher_profile")== 0 && zRight ){
179 char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
180 codec_vdbe_return_string(pParse, "cipher_profile", profile_status, P4_DYNAMIC);
181 } else
182 if( sqlite3_stricmp(zLeft, "cipher_add_random")==0 && zRight ){
183 if(ctx) {
184 char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
185 codec_vdbe_return_string(pParse, "cipher_add_random", add_random_status, P4_DYNAMIC);
187 } else
188 if( sqlite3_stricmp(zLeft, "cipher_migrate")==0 && !zRight ){
189 if(ctx){
190 int status = sqlcipher_codec_ctx_migrate(ctx);
191 char *migrate_status = sqlite3_mprintf("%d", status);
192 codec_vdbe_return_string(pParse, "cipher_migrate", migrate_status, P4_DYNAMIC);
193 if(status != SQLITE_OK) {
194 CODEC_TRACE("sqlcipher_codec_pragma: error occurred during cipher_migrate: %d", status);
195 sqlcipher_codec_ctx_set_error(ctx, status);
198 } else
199 if( sqlite3_stricmp(zLeft, "cipher_provider")==0 && !zRight ){
200 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider",
201 sqlcipher_codec_get_cipher_provider(ctx), P4_TRANSIENT);
203 } else
204 if( sqlite3_stricmp(zLeft, "cipher_provider_version")==0 && !zRight){
205 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider_version",
206 sqlcipher_codec_get_provider_version(ctx), P4_TRANSIENT);
208 } else
209 if( sqlite3_stricmp(zLeft, "cipher_version")==0 && !zRight ){
210 codec_vdbe_return_string(pParse, "cipher_version", sqlcipher_version(), P4_DYNAMIC);
211 }else
212 if( sqlite3_stricmp(zLeft, "cipher")==0 ){
213 if(ctx) {
214 if( zRight ) {
215 const char* message = "PRAGMA cipher is no longer supported.";
216 codec_vdbe_return_string(pParse, "cipher", message, P4_TRANSIENT);
217 sqlite3_log(SQLITE_WARNING, message);
218 }else {
219 codec_vdbe_return_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx), P4_TRANSIENT);
222 }else
223 if( sqlite3_stricmp(zLeft, "rekey_cipher")==0 && zRight ){
224 const char* message = "PRAGMA rekey_cipher is no longer supported.";
225 codec_vdbe_return_string(pParse, "rekey_cipher", message, P4_TRANSIENT);
226 sqlite3_log(SQLITE_WARNING, message);
227 }else
228 if( sqlite3_stricmp(zLeft,"cipher_default_kdf_iter")==0 ){
229 if( zRight ) {
230 sqlcipher_set_default_kdf_iter(atoi(zRight)); /* change default KDF iterations */
231 } else {
232 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
233 codec_vdbe_return_string(pParse, "cipher_default_kdf_iter", kdf_iter, P4_DYNAMIC);
235 }else
236 if( sqlite3_stricmp(zLeft, "kdf_iter")==0 ){
237 if(ctx) {
238 if( zRight ) {
239 sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
240 } else {
241 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx));
242 codec_vdbe_return_string(pParse, "kdf_iter", kdf_iter, P4_DYNAMIC);
245 }else
246 if( sqlite3_stricmp(zLeft, "fast_kdf_iter")==0){
247 if(ctx) {
248 if( zRight ) {
249 char *deprecation = "PRAGMA fast_kdf_iter is deprecated, please remove from use";
250 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
251 codec_vdbe_return_string(pParse, "fast_kdf_iter", deprecation, P4_TRANSIENT);
252 sqlite3_log(SQLITE_WARNING, deprecation);
253 } else {
254 char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx));
255 codec_vdbe_return_string(pParse, "fast_kdf_iter", fast_kdf_iter, P4_DYNAMIC);
258 }else
259 if( sqlite3_stricmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
260 const char* message = "PRAGMA rekey_kdf_iter is no longer supported.";
261 codec_vdbe_return_string(pParse, "rekey_kdf_iter", message, P4_TRANSIENT);
262 sqlite3_log(SQLITE_WARNING, message);
263 }else
264 if( sqlite3_stricmp(zLeft,"cipher_page_size")==0 ){
265 if(ctx) {
266 if( zRight ) {
267 int size = atoi(zRight);
268 rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
269 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
270 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
271 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
272 } else {
273 char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
274 codec_vdbe_return_string(pParse, "cipher_page_size", page_size, P4_DYNAMIC);
277 }else
278 if( sqlite3_stricmp(zLeft,"cipher_default_page_size")==0 ){
279 if( zRight ) {
280 sqlcipher_set_default_pagesize(atoi(zRight));
281 } else {
282 char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
283 codec_vdbe_return_string(pParse, "cipher_default_page_size", default_page_size, P4_DYNAMIC);
285 }else
286 if( sqlite3_stricmp(zLeft,"cipher_default_use_hmac")==0 ){
287 if( zRight ) {
288 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
289 } else {
290 char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
291 codec_vdbe_return_string(pParse, "cipher_default_use_hmac", default_use_hmac, P4_DYNAMIC);
293 }else
294 if( sqlite3_stricmp(zLeft,"cipher_use_hmac")==0 ){
295 if(ctx) {
296 if( zRight ) {
297 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
298 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
299 /* since the use of hmac has changed, the page size may also change */
300 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
301 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
302 } else {
303 char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx));
304 codec_vdbe_return_string(pParse, "cipher_use_hmac", hmac_flag, P4_DYNAMIC);
307 }else
308 if( sqlite3_stricmp(zLeft,"cipher_hmac_pgno")==0 ){
309 if(ctx) {
310 if(zRight) {
311 char *deprecation = "PRAGMA cipher_hmac_pgno is deprecated, please remove from use";
312 /* clear both pgno endian flags */
313 if(sqlite3_stricmp(zRight, "le") == 0) {
314 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
315 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
316 } else if(sqlite3_stricmp(zRight, "be") == 0) {
317 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
318 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
319 } else if(sqlite3_stricmp(zRight, "native") == 0) {
320 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
321 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
323 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", deprecation, P4_TRANSIENT);
324 sqlite3_log(SQLITE_WARNING, deprecation);
326 } else {
327 if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO)) {
328 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "le", P4_TRANSIENT);
329 } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO)) {
330 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "be", P4_TRANSIENT);
331 } else {
332 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "native", P4_TRANSIENT);
336 }else
337 if( sqlite3_stricmp(zLeft,"cipher_hmac_salt_mask")==0 ){
338 if(ctx) {
339 if(zRight) {
340 char *deprecation = "PRAGMA cipher_hmac_salt_mask is deprecated, please remove from use";
341 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
342 unsigned char mask = 0;
343 const unsigned char *hex = (const unsigned char *)zRight+2;
344 cipher_hex2bin(hex,2,&mask);
345 sqlcipher_set_hmac_salt_mask(mask);
347 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", deprecation, P4_TRANSIENT);
348 sqlite3_log(SQLITE_WARNING, deprecation);
349 } else {
350 char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
351 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask, P4_DYNAMIC);
354 }else
355 if( sqlite3_stricmp(zLeft,"cipher_plaintext_header_size")==0 ){
356 if(ctx) {
357 if( zRight ) {
358 int size = atoi(zRight);
359 /* deliberately ignore result code, if size is invalid it will be set to -1
360 and trip the error later in the codec */
361 sqlcipher_codec_ctx_set_plaintext_header_size(ctx, size);
362 } else {
363 char *size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
364 codec_vdbe_return_string(pParse, "cipher_plaintext_header_size", size, P4_DYNAMIC);
367 }else
368 if( sqlite3_stricmp(zLeft,"cipher_default_plaintext_header_size")==0 ){
369 if( zRight ) {
370 sqlcipher_set_default_plaintext_header_size(atoi(zRight));
371 } else {
372 char *size = sqlite3_mprintf("%d", sqlcipher_get_default_plaintext_header_size());
373 codec_vdbe_return_string(pParse, "cipher_default_plaintext_header_size", size, P4_DYNAMIC);
375 }else
376 if( sqlite3_stricmp(zLeft,"cipher_salt")==0 ){
377 if(ctx) {
378 if(zRight) {
379 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == (FILE_HEADER_SZ*2)+3) {
380 unsigned char *salt = (unsigned char*) sqlite3_malloc(FILE_HEADER_SZ);
381 const unsigned char *hex = (const unsigned char *)zRight+2;
382 cipher_hex2bin(hex,FILE_HEADER_SZ*2,salt);
383 sqlcipher_codec_ctx_set_kdf_salt(ctx, salt, FILE_HEADER_SZ);
384 sqlite3_free(salt);
386 } else {
387 void *salt;
388 char *hexsalt = (char*) sqlite3_malloc((FILE_HEADER_SZ*2)+1);
389 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &salt)) == SQLITE_OK) {
390 cipher_bin2hex(salt, FILE_HEADER_SZ, hexsalt);
391 codec_vdbe_return_string(pParse, "cipher_salt", hexsalt, P4_DYNAMIC);
392 } else {
393 sqlite3_free(hexsalt);
394 sqlcipher_codec_ctx_set_error(ctx, rc);
398 }else
399 if( sqlite3_stricmp(zLeft,"cipher_hmac_algorithm")==0 ){
400 if(ctx) {
401 if(zRight) {
402 rc = SQLITE_ERROR;
403 if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
404 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
405 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
406 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA256);
407 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
408 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
410 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
411 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
412 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
413 } else {
414 int algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
415 if(algorithm == SQLCIPHER_HMAC_SHA1) {
416 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
417 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
418 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
419 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
420 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
424 }else
425 if( sqlite3_stricmp(zLeft,"cipher_default_hmac_algorithm")==0 ){
426 if(zRight) {
427 rc = SQLITE_ERROR;
428 if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
429 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
430 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
431 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA256);
432 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
433 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
435 } else {
436 int algorithm = sqlcipher_get_default_hmac_algorithm();
437 if(algorithm == SQLCIPHER_HMAC_SHA1) {
438 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
439 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
440 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
441 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
442 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
445 }else
446 if( sqlite3_stricmp(zLeft,"cipher_kdf_algorithm")==0 ){
447 if(ctx) {
448 if(zRight) {
449 rc = SQLITE_ERROR;
450 if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
451 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
452 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
453 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA256);
454 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
455 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
457 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
458 } else {
459 int algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
460 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
461 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
462 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
463 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
464 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
465 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
469 }else
470 if( sqlite3_stricmp(zLeft,"cipher_default_kdf_algorithm")==0 ){
471 if(zRight) {
472 rc = SQLITE_ERROR;
473 if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
474 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
475 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
476 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA256);
477 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
478 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
480 } else {
481 int algorithm = sqlcipher_get_default_kdf_algorithm();
482 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
483 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
484 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
485 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
486 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
487 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
490 }else
491 if( sqlite3_stricmp(zLeft,"cipher_compatibility")==0 ){
492 if(ctx) {
493 if(zRight) {
494 int version = atoi(zRight);
496 switch(version) {
497 case 1:
498 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
499 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
500 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
501 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
502 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
503 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
504 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
505 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
506 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 0);
507 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
508 break;
510 case 2:
511 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
512 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
513 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
514 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
515 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
516 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
517 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
518 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
519 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
520 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
521 break;
523 case 3:
524 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
525 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
526 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
527 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
528 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
529 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
530 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 64000);
531 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
532 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
533 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
534 break;
536 default:
537 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 4096);
538 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
539 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
540 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
541 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
542 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
543 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 256000);
544 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
545 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
546 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
547 break;
550 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
551 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
554 }else
555 if( sqlite3_stricmp(zLeft,"cipher_default_compatibility")==0 ){
556 if(zRight) {
557 int version = atoi(zRight);
558 switch(version) {
559 case 1:
560 sqlcipher_set_default_pagesize(1024);
561 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
562 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
563 sqlcipher_set_default_kdf_iter(4000);
564 sqlcipher_set_default_use_hmac(0);
565 break;
567 case 2:
568 sqlcipher_set_default_pagesize(1024);
569 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
570 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
571 sqlcipher_set_default_kdf_iter(4000);
572 sqlcipher_set_default_use_hmac(1);
573 break;
575 case 3:
576 sqlcipher_set_default_pagesize(1024);
577 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
578 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
579 sqlcipher_set_default_kdf_iter(64000);
580 sqlcipher_set_default_use_hmac(1);
581 break;
583 default:
584 sqlcipher_set_default_pagesize(4096);
585 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
586 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
587 sqlcipher_set_default_kdf_iter(256000);
588 sqlcipher_set_default_use_hmac(1);
589 break;
592 }else
593 if( sqlite3_stricmp(zLeft,"cipher_memory_security")==0 ){
594 if( zRight ) {
595 sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1));
596 } else {
597 char *on = sqlite3_mprintf("%d", sqlcipher_get_mem_security());
598 codec_vdbe_return_string(pParse, "cipher_memory_security", on, P4_DYNAMIC);
600 }else
601 if( sqlite3_stricmp(zLeft,"cipher_settings")==0 ){
602 if(ctx) {
603 int algorithm;
604 char *pragma;
606 pragma = sqlite3_mprintf("PRAGMA kdf_iter = %d;", sqlcipher_codec_ctx_get_kdf_iter(ctx));
607 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
609 pragma = sqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx));
610 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
612 pragma = sqlite3_mprintf("PRAGMA cipher_use_hmac = %d;", sqlcipher_codec_ctx_get_use_hmac(ctx));
613 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
615 pragma = sqlite3_mprintf("PRAGMA cipher_plaintext_header_size = %d;", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
616 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
618 algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
619 pragma = NULL;
620 if(algorithm == SQLCIPHER_HMAC_SHA1) {
621 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
622 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
623 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
624 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
625 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
627 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
629 algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
630 pragma = NULL;
631 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
632 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
633 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
634 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
635 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
636 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
638 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
641 }else
642 if( sqlite3_stricmp(zLeft,"cipher_default_settings")==0 ){
643 int algorithm;
644 char *pragma;
646 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_iter = %d;", sqlcipher_get_default_kdf_iter());
647 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
649 pragma = sqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize());
650 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
652 pragma = sqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac());
653 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
655 pragma = sqlite3_mprintf("PRAGMA cipher_default_plaintext_header_size = %d;", sqlcipher_get_default_plaintext_header_size());
656 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
658 algorithm = sqlcipher_get_default_hmac_algorithm();
659 pragma = NULL;
660 if(algorithm == SQLCIPHER_HMAC_SHA1) {
661 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
662 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
663 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
664 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
665 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
667 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
669 algorithm = sqlcipher_get_default_kdf_algorithm();
670 pragma = NULL;
671 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
672 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
673 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
674 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
675 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
676 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
678 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
679 }else
680 if( sqlite3_stricmp(zLeft,"cipher_integrity_check")==0 ){
681 if(ctx) {
682 sqlcipher_codec_ctx_integrity_check(ctx, pParse, "cipher_integrity_check");
684 } else
685 if( sqlite3_stricmp(zLeft, "cipher_trace_filter")==0 && zRight){
686 unsigned int filter = 0;
687 if(sqlite3_strlike("%CORE%", zRight, '\'')==0) filter |= SQLCIPHER_TRACE_CORE;
688 if(sqlite3_strlike("%MEMORY%", zRight, '\'')==0) filter |= SQLCIPHER_TRACE_MEMORY;
689 if(sqlite3_strlike("%MUTEX%", zRight, '\'')==0) filter |= SQLCIPHER_TRACE_MUTEX;
690 if(sqlite3_strlike("%PROVIDER%", zRight, '\'')==0) filter |= SQLCIPHER_TRACE_PROVIDER;
691 if(sqlite3_strlike("%ALL%", zRight, '\'')==0) filter |= SQLCIPHER_TRACE_ALL;
692 sqlcipher_set_trace_filter(filter);
693 codec_vdbe_return_string(pParse, "cipher_trace_filter", sqlite3_mprintf("%u", filter), P4_DYNAMIC);
694 } else
695 if( sqlite3_stricmp(zLeft, "cipher_trace")== 0 && zRight ){
696 char *profile_status = sqlite3_mprintf("%d", sqlcipher_set_trace(zRight));
697 codec_vdbe_return_string(pParse, "cipher_trace", profile_status, P4_DYNAMIC);
698 }else {
699 return 0;
701 return 1;
704 /* these constants are used internally within SQLite's pager.c to differentiate between
705 operations on the main database or journal pages. This is important in the context
706 of a rekey operations, where the journal must be written using the original key
707 material (to allow a transactional rollback), while the new database pages are being
708 written with the new key material*/
709 #define CODEC_READ_OP 3
710 #define CODEC_WRITE_OP 6
711 #define CODEC_JOURNAL_OP 7
714 * sqlite3Codec can be called in multiple modes.
715 * encrypt mode - expected to return a pointer to the
716 * encrypted data without altering pData.
717 * decrypt mode - expected to return a pointer to pData, with
718 * the data decrypted in the input buffer
720 static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
721 codec_ctx *ctx = (codec_ctx *) iCtx;
722 int offset = 0, rc = 0;
723 int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
724 unsigned char *pData = (unsigned char *) data;
725 void *buffer = sqlcipher_codec_ctx_get_data(ctx);
726 int plaintext_header_sz = sqlcipher_codec_ctx_get_plaintext_header_size(ctx);
727 int cctx = CIPHER_READ_CTX;
729 CODEC_TRACE("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d", pgno, mode, page_sz);
731 #ifdef SQLCIPHER_EXT
732 if(sqlcipher_license_check(ctx) != SQLITE_OK) return NULL;
733 #endif
735 /* call to derive keys if not present yet */
736 if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
737 CODEC_TRACE("sqlite3Codec: error occurred during key derivation: %d", rc);
738 sqlcipher_codec_ctx_set_error(ctx, rc);
739 return NULL;
742 /* if the plaintext_header_size is negative that means an invalid size was set via
743 PRAGMA. We can't set the error state on the pager at that point because the pager
744 may not be open yet. However, this is a fatal error state, so abort the codec */
745 if(plaintext_header_sz < 0) {
746 CODEC_TRACE("sqlite3Codec: error invalid plaintext_header_sz: %d", plaintext_header_sz);
747 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
748 return NULL;
751 if(pgno == 1) /* adjust starting pointers in data page for header offset on first page*/
752 offset = plaintext_header_sz ? plaintext_header_sz : FILE_HEADER_SZ;
755 CODEC_TRACE("sqlite3Codec: switch mode=%d offset=%d", mode, offset);
756 switch(mode) {
757 case CODEC_READ_OP: /* decrypt */
758 if(pgno == 1) /* copy initial part of file header or SQLite magic to buffer */
759 memcpy(buffer, plaintext_header_sz ? pData : (void *) SQLITE_FILE_HEADER, offset);
761 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
762 #ifdef SQLCIPHER_TEST
763 if((sqlcipher_get_test_flags() & TEST_FAIL_DECRYPT) > 0 && sqlcipher_get_test_fail()) {
764 rc = SQLITE_ERROR;
765 fprintf(stderr, "simulating decryption failure for pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
767 #endif
768 if(rc != SQLITE_OK) {
769 /* failure to decrypt a page is considered a permanent error and will render the pager unusable
770 in order to prevent inconsistent data being loaded into page cache */
771 CODEC_TRACE("sqlite3Codec: error decrypting page data: %d", rc);
772 sqlcipher_memset((unsigned char*) buffer+offset, 0, page_sz-offset);
773 sqlcipher_codec_ctx_set_error(ctx, rc);
775 memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
776 return pData;
777 break;
779 case CODEC_WRITE_OP: /* encrypt database page, operate on write context and fall through to case 7, so the write context is used*/
780 cctx = CIPHER_WRITE_CTX;
782 case CODEC_JOURNAL_OP: /* encrypt journal page, operate on read context use to get the original page data from the database */
783 if(pgno == 1) { /* copy initial part of file header or salt to buffer */
784 void *kdf_salt = NULL;
785 /* retrieve the kdf salt */
786 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &kdf_salt)) != SQLITE_OK) {
787 CODEC_TRACE("sqlite3Codec: error retrieving salt: %d", rc);
788 sqlcipher_codec_ctx_set_error(ctx, rc);
789 return NULL;
791 memcpy(buffer, plaintext_header_sz ? pData : kdf_salt, offset);
793 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
794 #ifdef SQLCIPHER_TEST
795 if((sqlcipher_get_test_flags() & TEST_FAIL_ENCRYPT) > 0 && sqlcipher_get_test_fail()) {
796 rc = SQLITE_ERROR;
797 fprintf(stderr, "simulating encryption failure for pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
799 #endif
800 if(rc != SQLITE_OK) {
801 /* failure to encrypt a page is considered a permanent error and will render the pager unusable
802 in order to prevent corrupted pages from being written to the main databased when using WAL */
803 CODEC_TRACE("sqlite3Codec: error encrypting page data: %d", rc);
804 sqlcipher_memset((unsigned char*)buffer+offset, 0, page_sz-offset);
805 sqlcipher_codec_ctx_set_error(ctx, rc);
806 return NULL;
808 return buffer; /* return persistent buffer data, pData remains intact */
809 break;
811 default:
812 CODEC_TRACE("sqlite3Codec: error unsupported codec mode %d", mode);
813 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); /* unsupported mode, set error */
814 return pData;
815 break;
819 static void sqlite3FreeCodecArg(void *pCodecArg) {
820 codec_ctx *ctx = (codec_ctx *) pCodecArg;
821 if(pCodecArg == NULL) return;
822 sqlcipher_codec_ctx_free(&ctx); /* wipe and free allocated memory for the context */
823 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
826 int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
827 struct Db *pDb = &db->aDb[nDb];
829 CODEC_TRACE("sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%p, nKey=%d", db, nDb, zKey, nKey);
832 if(nKey && zKey && pDb->pBt) {
833 int rc;
834 Pager *pPager = pDb->pBt->pBt->pPager;
835 sqlite3_file *fd;
836 codec_ctx *ctx;
838 /* check if the sqlite3_file is open, and if not force handle to NULL */
839 if((fd = sqlite3PagerFile(pPager))->pMethods == 0) fd = NULL;
841 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_activate()");
842 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
844 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entering database mutex %p", db->mutex);
845 sqlite3_mutex_enter(db->mutex);
846 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entered database mutex %p", db->mutex);
848 #ifdef SQLCIPHER_EXT
849 if((rc = sqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) {
850 sqlite3_mutex_leave(db->mutex);
851 return rc;
853 #endif
855 /* point the internal codec argument against the contet to be prepared */
856 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()");
857 rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, zKey, nKey);
859 if(rc != SQLITE_OK) {
860 /* initialization failed, do not attach potentially corrupted context */
861 CODEC_TRACE("sqlite3CodecAttach: context initialization failed with rc=%d", rc);
862 /* force an error at the pager level, such that even the upstream caller ignores the return code
863 the pager will be in an error state and will process no further operations */
864 sqlite3pager_error(pPager, rc);
865 pDb->pBt->pBt->db->errCode = rc;
866 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)", db->mutex, rc);
867 sqlite3_mutex_leave(db->mutex);
868 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p (early return on rc=%d)", db->mutex, rc);
869 return rc;
872 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3PagerSetCodec()");
873 sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
875 CODEC_TRACE("sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()");
876 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
878 /* force secure delete. This has the benefit of wiping internal data when deleted
879 and also ensures that all pages are written to disk (i.e. not skipped by
880 sqlite3PagerDontWrite optimizations) */
881 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()");
882 sqlite3BtreeSecureDelete(pDb->pBt, 1);
884 /* if fd is null, then this is an in-memory database and
885 we dont' want to overwrite the AutoVacuum settings
886 if not null, then set to the default */
887 if(fd != NULL) {
888 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()");
889 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
891 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p", db->mutex);
892 sqlite3_mutex_leave(db->mutex);
893 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p", db->mutex);
895 return SQLITE_OK;
898 int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
899 int db_index;
900 if(zDb == NULL){
901 return 0;
903 for(db_index = 0; db_index < db->nDb; db_index++) {
904 struct Db *pDb = &db->aDb[db_index];
905 if(strcmp(pDb->zDbSName, zDb) == 0) {
906 return db_index;
909 return 0;
912 void sqlite3_activate_see(const char* in) {
913 /* do nothing, security enhancements are always active */
916 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
917 CODEC_TRACE("sqlite3_key entered: db=%p pKey=%p nKey=%d", db, pKey, nKey);
918 return sqlite3_key_v2(db, "main", pKey, nKey);
921 int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
922 CODEC_TRACE("sqlite3_key_v2: entered db=%p zDb=%s pKey=%p nKey=%d", db, zDb, pKey, nKey);
923 /* attach key if db and pKey are not null and nKey is > 0 */
924 if(db && pKey && nKey) {
925 int db_index = sqlcipher_find_db_index(db, zDb);
926 return sqlite3CodecAttach(db, db_index, pKey, nKey);
928 return SQLITE_ERROR;
931 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
932 CODEC_TRACE("sqlite3_rekey entered: db=%p pKey=%p nKey=%d", db, pKey, nKey);
933 return sqlite3_rekey_v2(db, "main", pKey, nKey);
936 /* sqlite3_rekey_v2
937 ** Given a database, this will reencrypt the database using a new key.
938 ** There is only one possible modes of operation - to encrypt a database
939 ** that is already encrpyted. If the database is not already encrypted
940 ** this should do nothing
941 ** The proposed logic for this function follows:
942 ** 1. Determine if the database is already encryptped
943 ** 2. If there is NOT already a key present do nothing
944 ** 3. If there is a key present, re-encrypt the database with the new key
946 int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
947 CODEC_TRACE("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%p, nKey=%d", db, zDb, pKey, nKey);
948 if(db && pKey && nKey) {
949 int db_index = sqlcipher_find_db_index(db, zDb);
950 struct Db *pDb = &db->aDb[db_index];
951 CODEC_TRACE("sqlite3_rekey_v2: database pDb=%p db_index:%d", pDb, db_index);
952 if(pDb->pBt) {
953 codec_ctx *ctx;
954 int rc, page_count;
955 Pgno pgno;
956 PgHdr *page;
957 Pager *pPager = pDb->pBt->pBt->pPager;
959 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
961 if(ctx == NULL) {
962 /* there was no codec attached to this database, so this should do nothing! */
963 CODEC_TRACE("sqlite3_rekey_v2: no codec attached to db, exiting");
964 return SQLITE_OK;
967 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entering database mutex %p", db->mutex);
968 sqlite3_mutex_enter(db->mutex);
969 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entered database mutex %p", db->mutex);
971 codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
973 /* do stuff here to rewrite the database
974 ** 1. Create a transaction on the database
975 ** 2. Iterate through each page, reading it and then writing it.
976 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
977 ** note: don't deallocate rekey since it may be used in a subsequent iteration
979 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */
980 sqlite3PagerPagecount(pPager, &page_count);
981 for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
982 if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
983 rc = sqlite3PagerGet(pPager, pgno, &page, 0);
984 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
985 rc = sqlite3PagerWrite(page);
986 if(rc == SQLITE_OK) {
987 sqlite3PagerUnref(page);
988 } else {
989 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred writing page %d", rc, pgno);
991 } else {
992 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred getting page %d", rc, pgno);
997 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
998 if(rc == SQLITE_OK) {
999 CODEC_TRACE("sqlite3_rekey_v2: committing");
1000 rc = sqlite3BtreeCommit(pDb->pBt);
1001 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
1002 } else {
1003 CODEC_TRACE("sqlite3_rekey_v2: rollback");
1004 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
1007 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: leaving database mutex %p", db->mutex);
1008 sqlite3_mutex_leave(db->mutex);
1009 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: left database mutex %p", db->mutex);
1011 return SQLITE_OK;
1013 return SQLITE_ERROR;
1016 void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
1017 struct Db *pDb = &db->aDb[nDb];
1018 CODEC_TRACE("sqlite3CodecGetKey: entered db=%p, nDb=%d", db, nDb);
1019 if( pDb->pBt ) {
1020 codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
1022 if(ctx) {
1023 /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass
1024 is set or keyspec has not yet been derived, in which case pass
1025 back the password key material */
1026 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
1027 if(sqlcipher_codec_get_store_pass(ctx) == 1 || *zKey == NULL) {
1028 sqlcipher_codec_get_pass(ctx, zKey, nKey);
1030 } else {
1031 *zKey = NULL;
1032 *nKey = 0;
1038 * Implementation of an "export" function that allows a caller
1039 * to duplicate the main database to an attached database. This is intended
1040 * as a conveneince for users who need to:
1042 * 1. migrate from an non-encrypted database to an encrypted database
1043 * 2. move from an encrypted database to a non-encrypted database
1044 * 3. convert beween the various flavors of encrypted databases.
1046 * This implementation is based heavily on the procedure and code used
1047 * in vacuum.c, but is exposed as a function that allows export to any
1048 * named attached database.
1052 ** Finalize a prepared statement. If there was an error, store the
1053 ** text of the error message in *pzErrMsg. Return the result code.
1055 ** Based on vacuumFinalize from vacuum.c
1057 static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
1058 int rc;
1059 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
1060 if( rc ){
1061 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1063 return rc;
1067 ** Execute zSql on database db. Return an error code.
1069 ** Based on execSql from vacuum.c
1071 static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1072 sqlite3_stmt *pStmt;
1073 VVA_ONLY( int rc; )
1074 if( !zSql ){
1075 return SQLITE_NOMEM;
1077 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
1078 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1079 return sqlite3_errcode(db);
1081 VVA_ONLY( rc = ) sqlite3_step(pStmt);
1082 assert( rc!=SQLITE_ROW );
1083 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1087 ** Execute zSql on database db. The statement returns exactly
1088 ** one column. Execute this as SQL on the same database.
1090 ** Based on execExecSql from vacuum.c
1092 static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1093 sqlite3_stmt *pStmt;
1094 int rc;
1096 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
1097 if( rc!=SQLITE_OK ) return rc;
1099 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1100 rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
1101 if( rc!=SQLITE_OK ){
1102 sqlcipher_finalize(db, pStmt, pzErrMsg);
1103 return rc;
1107 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1111 * copy database and schema from the main database to an attached database
1113 * Based on sqlite3RunVacuum from vacuum.c
1115 void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
1116 sqlite3 *db = sqlite3_context_db_handle(context);
1117 const char* targetDb, *sourceDb;
1118 int targetDb_idx = 0;
1119 u64 saved_flags = db->flags; /* Saved value of the db->flags */
1120 u32 saved_mDbFlags = db->mDbFlags; /* Saved value of the db->mDbFlags */
1121 int saved_nChange = db->nChange; /* Saved value of db->nChange */
1122 int saved_nTotalChange = db->nTotalChange; /* Saved value of db->nTotalChange */
1123 u8 saved_mTrace = db->mTrace; /* Saved value of db->mTrace */
1124 int rc = SQLITE_OK; /* Return code from service routines */
1125 char *zSql = NULL; /* SQL statements */
1126 char *pzErrMsg = NULL;
1128 if(argc != 1 && argc != 2) {
1129 rc = SQLITE_ERROR;
1130 pzErrMsg = sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc);
1131 goto end_of_export;
1134 if(sqlite3_value_type(argv[0]) == SQLITE_NULL) {
1135 rc = SQLITE_ERROR;
1136 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1137 goto end_of_export;
1140 targetDb = (const char*) sqlite3_value_text(argv[0]);
1141 sourceDb = "main";
1143 if(argc == 2) {
1144 if(sqlite3_value_type(argv[1]) == SQLITE_NULL) {
1145 rc = SQLITE_ERROR;
1146 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1147 goto end_of_export;
1149 sourceDb = (char *) sqlite3_value_text(argv[1]);
1153 /* if the name of the target is not main, but the index returned is zero
1154 there is a mismatch and we should not proceed */
1155 targetDb_idx = sqlcipher_find_db_index(db, targetDb);
1156 if(targetDb_idx == 0 && targetDb != NULL && sqlite3_stricmp("main", targetDb) != 0) {
1157 rc = SQLITE_ERROR;
1158 pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb);
1159 goto end_of_export;
1161 db->init.iDb = targetDb_idx;
1163 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
1164 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
1165 db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows);
1166 db->mTrace = 0;
1168 /* Query the schema of the main database. Create a mirror schema
1169 ** in the temporary database.
1171 zSql = sqlite3_mprintf(
1172 "SELECT sql "
1173 " FROM %s.sqlite_schema WHERE type='table' AND name!='sqlite_sequence'"
1174 " AND rootpage>0"
1175 , sourceDb);
1176 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1177 if( rc!=SQLITE_OK ) goto end_of_export;
1178 sqlite3_free(zSql);
1180 zSql = sqlite3_mprintf(
1181 "SELECT sql "
1182 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE INDEX %%' "
1183 , sourceDb);
1184 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1185 if( rc!=SQLITE_OK ) goto end_of_export;
1186 sqlite3_free(zSql);
1188 zSql = sqlite3_mprintf(
1189 "SELECT sql "
1190 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
1191 , sourceDb);
1192 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1193 if( rc!=SQLITE_OK ) goto end_of_export;
1194 sqlite3_free(zSql);
1196 /* Loop through the tables in the main database. For each, do
1197 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
1198 ** the contents to the temporary database.
1200 zSql = sqlite3_mprintf(
1201 "SELECT 'INSERT INTO %s.' || quote(name) "
1202 "|| ' SELECT * FROM %s.' || quote(name) || ';'"
1203 "FROM %s.sqlite_schema "
1204 "WHERE type = 'table' AND name!='sqlite_sequence' "
1205 " AND rootpage>0"
1206 , targetDb, sourceDb, sourceDb);
1207 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1208 if( rc!=SQLITE_OK ) goto end_of_export;
1209 sqlite3_free(zSql);
1211 /* Copy over the contents of the sequence table
1213 zSql = sqlite3_mprintf(
1214 "SELECT 'INSERT INTO %s.' || quote(name) "
1215 "|| ' SELECT * FROM %s.' || quote(name) || ';' "
1216 "FROM %s.sqlite_schema WHERE name=='sqlite_sequence';"
1217 , targetDb, sourceDb, targetDb);
1218 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1219 if( rc!=SQLITE_OK ) goto end_of_export;
1220 sqlite3_free(zSql);
1222 /* Copy the triggers, views, and virtual tables from the main database
1223 ** over to the temporary database. None of these objects has any
1224 ** associated storage, so all we have to do is copy their entries
1225 ** from the SQLITE_MASTER table.
1227 zSql = sqlite3_mprintf(
1228 "INSERT INTO %s.sqlite_schema "
1229 " SELECT type, name, tbl_name, rootpage, sql"
1230 " FROM %s.sqlite_schema"
1231 " WHERE type='view' OR type='trigger'"
1232 " OR (type='table' AND rootpage=0)"
1233 , targetDb, sourceDb);
1234 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
1235 if( rc!=SQLITE_OK ) goto end_of_export;
1236 sqlite3_free(zSql);
1238 zSql = NULL;
1239 end_of_export:
1240 db->init.iDb = 0;
1241 db->flags = saved_flags;
1242 db->mDbFlags = saved_mDbFlags;
1243 db->nChange = saved_nChange;
1244 db->nTotalChange = saved_nTotalChange;
1245 db->mTrace = saved_mTrace;
1247 if(zSql) sqlite3_free(zSql);
1249 if(rc) {
1250 if(pzErrMsg != NULL) {
1251 sqlite3_result_error(context, pzErrMsg, -1);
1252 sqlite3DbFree(db, pzErrMsg);
1253 } else {
1254 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
1258 #endif
1259 /* END SQLCIPHER */