update version
[sqlcipher.git] / src / crypto.c
blobde923b043e014d242f00fde648f9de8ed5efc63a
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 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d", page_sz, reserve_sz);
58 sqlcipher_log(SQLCIPHER_LOG_TRACE, "codec_set_btree_to_codec_pagesize: entering database mutex %p", db->mutex);
59 sqlite3_mutex_enter(db->mutex);
60 sqlcipher_log(SQLCIPHER_LOG_TRACE, "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 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize returned %d", rc);
70 sqlcipher_log(SQLCIPHER_LOG_TRACE, "codec_set_btree_to_codec_pagesize: leaving database mutex %p", db->mutex);
71 sqlite3_mutex_leave(db->mutex);
72 sqlcipher_log(SQLCIPHER_LOG_TRACE, "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 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "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) {
84 return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
85 } else {
86 sqlcipher_log(SQLCIPHER_LOG_ERROR, "codec_set_pass_key: error ocurred fetching codec from pager on db %d", nDb);
87 return SQLITE_ERROR;
90 sqlcipher_log(SQLCIPHER_LOG_ERROR, "codec_set_pass_key: no btree present on db %d", nDb);
91 return SQLITE_ERROR;
94 int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
95 struct Db *pDb = &db->aDb[iDb];
96 codec_ctx *ctx = NULL;
97 int rc;
99 if(pDb->pBt) {
100 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
103 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p", db, iDb, pParse, zLeft, zRight, ctx);
105 #ifdef SQLCIPHER_EXT
106 if( sqlite3_stricmp(zLeft, "cipher_license")==0 && zRight ){
107 char *license_result = sqlite3_mprintf("%d", sqlcipher_license_key(zRight));
108 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
109 } else
110 if( sqlite3_stricmp(zLeft, "cipher_license")==0 && !zRight ){
111 if(ctx) {
112 char *license_result = sqlite3_mprintf("%d", ctx
113 ? sqlcipher_license_key_status(ctx->provider)
114 : SQLITE_ERROR);
115 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
117 } else
118 #endif
119 #ifdef SQLCIPHER_TEST
120 if( sqlite3_stricmp(zLeft,"cipher_test_on")==0 ){
121 if( zRight ) {
122 unsigned int flags = sqlcipher_get_test_flags();
123 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
124 flags |= TEST_FAIL_ENCRYPT;
125 } else
126 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
127 flags |= TEST_FAIL_DECRYPT;
128 } else
129 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
130 flags |= TEST_FAIL_MIGRATE;
132 sqlcipher_set_test_flags(flags);
134 } else
135 if( sqlite3_stricmp(zLeft,"cipher_test_off")==0 ){
136 if( zRight ) {
137 unsigned int flags = sqlcipher_get_test_flags();
138 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
139 flags &= ~TEST_FAIL_ENCRYPT;
140 } else
141 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
142 flags &= ~TEST_FAIL_DECRYPT;
143 } else
144 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
145 flags &= ~TEST_FAIL_MIGRATE;
147 sqlcipher_set_test_flags(flags);
149 } else
150 if( sqlite3_stricmp(zLeft,"cipher_test")==0 ){
151 char *flags = sqlite3_mprintf("%u", sqlcipher_get_test_flags());
152 codec_vdbe_return_string(pParse, "cipher_test", flags, P4_DYNAMIC);
153 }else
154 if( sqlite3_stricmp(zLeft,"cipher_test_rand")==0 ){
155 if( zRight ) {
156 int rand = atoi(zRight);
157 sqlcipher_set_test_rand(rand);
158 } else {
159 char *rand = sqlite3_mprintf("%d", sqlcipher_get_test_rand());
160 codec_vdbe_return_string(pParse, "cipher_test_rand", rand, P4_DYNAMIC);
162 } else
163 #endif
164 if( sqlite3_stricmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
165 if(ctx) {
166 char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
167 codec_vdbe_return_string(pParse, "cipher_fips_status", fips_mode_status, P4_DYNAMIC);
169 } else
170 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && zRight ) {
171 if(ctx) {
172 char *deprecation = "PRAGMA cipher_store_pass is deprecated, please remove from use";
173 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
174 codec_vdbe_return_string(pParse, "cipher_store_pass", deprecation, P4_TRANSIENT);
175 sqlite3_log(SQLITE_WARNING, deprecation);
177 } else
178 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
179 if(ctx){
180 char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
181 codec_vdbe_return_string(pParse, "cipher_store_pass", store_pass_value, P4_DYNAMIC);
184 if( sqlite3_stricmp(zLeft, "cipher_profile")== 0 && zRight ){
185 char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
186 codec_vdbe_return_string(pParse, "cipher_profile", profile_status, P4_DYNAMIC);
187 } else
188 if( sqlite3_stricmp(zLeft, "cipher_add_random")==0 && zRight ){
189 if(ctx) {
190 char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
191 codec_vdbe_return_string(pParse, "cipher_add_random", add_random_status, P4_DYNAMIC);
193 } else
194 if( sqlite3_stricmp(zLeft, "cipher_migrate")==0 && !zRight ){
195 if(ctx){
196 int status = sqlcipher_codec_ctx_migrate(ctx);
197 char *migrate_status = sqlite3_mprintf("%d", status);
198 codec_vdbe_return_string(pParse, "cipher_migrate", migrate_status, P4_DYNAMIC);
199 if(status != SQLITE_OK) {
200 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlcipher_codec_pragma: error occurred during cipher_migrate: %d", status);
201 sqlcipher_codec_ctx_set_error(ctx, status);
204 } else
205 if( sqlite3_stricmp(zLeft, "cipher_provider")==0 && !zRight ){
206 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider",
207 sqlcipher_codec_get_cipher_provider(ctx), P4_TRANSIENT);
209 } else
210 if( sqlite3_stricmp(zLeft, "cipher_provider_version")==0 && !zRight){
211 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider_version",
212 sqlcipher_codec_get_provider_version(ctx), P4_TRANSIENT);
214 } else
215 if( sqlite3_stricmp(zLeft, "cipher_version")==0 && !zRight ){
216 codec_vdbe_return_string(pParse, "cipher_version", sqlcipher_version(), P4_DYNAMIC);
217 }else
218 if( sqlite3_stricmp(zLeft, "cipher")==0 ){
219 if(ctx) {
220 if( zRight ) {
221 const char* message = "PRAGMA cipher is no longer supported.";
222 codec_vdbe_return_string(pParse, "cipher", message, P4_TRANSIENT);
223 sqlite3_log(SQLITE_WARNING, message);
224 }else {
225 codec_vdbe_return_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx), P4_TRANSIENT);
228 }else
229 if( sqlite3_stricmp(zLeft, "rekey_cipher")==0 && zRight ){
230 const char* message = "PRAGMA rekey_cipher is no longer supported.";
231 codec_vdbe_return_string(pParse, "rekey_cipher", message, P4_TRANSIENT);
232 sqlite3_log(SQLITE_WARNING, message);
233 }else
234 if( sqlite3_stricmp(zLeft,"cipher_default_kdf_iter")==0 ){
235 if( zRight ) {
236 sqlcipher_set_default_kdf_iter(atoi(zRight)); /* change default KDF iterations */
237 } else {
238 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
239 codec_vdbe_return_string(pParse, "cipher_default_kdf_iter", kdf_iter, P4_DYNAMIC);
241 }else
242 if( sqlite3_stricmp(zLeft, "kdf_iter")==0 ){
243 if(ctx) {
244 if( zRight ) {
245 sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
246 } else {
247 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx));
248 codec_vdbe_return_string(pParse, "kdf_iter", kdf_iter, P4_DYNAMIC);
251 }else
252 if( sqlite3_stricmp(zLeft, "fast_kdf_iter")==0){
253 if(ctx) {
254 if( zRight ) {
255 char *deprecation = "PRAGMA fast_kdf_iter is deprecated, please remove from use";
256 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
257 codec_vdbe_return_string(pParse, "fast_kdf_iter", deprecation, P4_TRANSIENT);
258 sqlite3_log(SQLITE_WARNING, deprecation);
259 } else {
260 char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx));
261 codec_vdbe_return_string(pParse, "fast_kdf_iter", fast_kdf_iter, P4_DYNAMIC);
264 }else
265 if( sqlite3_stricmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
266 const char* message = "PRAGMA rekey_kdf_iter is no longer supported.";
267 codec_vdbe_return_string(pParse, "rekey_kdf_iter", message, P4_TRANSIENT);
268 sqlite3_log(SQLITE_WARNING, message);
269 }else
270 if( sqlite3_stricmp(zLeft,"cipher_page_size")==0 ){
271 if(ctx) {
272 if( zRight ) {
273 int size = atoi(zRight);
274 rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
275 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
276 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
277 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
278 } else {
279 char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
280 codec_vdbe_return_string(pParse, "cipher_page_size", page_size, P4_DYNAMIC);
283 }else
284 if( sqlite3_stricmp(zLeft,"cipher_default_page_size")==0 ){
285 if( zRight ) {
286 sqlcipher_set_default_pagesize(atoi(zRight));
287 } else {
288 char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
289 codec_vdbe_return_string(pParse, "cipher_default_page_size", default_page_size, P4_DYNAMIC);
291 }else
292 if( sqlite3_stricmp(zLeft,"cipher_default_use_hmac")==0 ){
293 if( zRight ) {
294 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
295 } else {
296 char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
297 codec_vdbe_return_string(pParse, "cipher_default_use_hmac", default_use_hmac, P4_DYNAMIC);
299 }else
300 if( sqlite3_stricmp(zLeft,"cipher_use_hmac")==0 ){
301 if(ctx) {
302 if( zRight ) {
303 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
304 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
305 /* since the use of hmac has changed, the page size may also change */
306 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
307 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
308 } else {
309 char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx));
310 codec_vdbe_return_string(pParse, "cipher_use_hmac", hmac_flag, P4_DYNAMIC);
313 }else
314 if( sqlite3_stricmp(zLeft,"cipher_hmac_pgno")==0 ){
315 if(ctx) {
316 if(zRight) {
317 char *deprecation = "PRAGMA cipher_hmac_pgno is deprecated, please remove from use";
318 /* clear both pgno endian flags */
319 if(sqlite3_stricmp(zRight, "le") == 0) {
320 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
321 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
322 } else if(sqlite3_stricmp(zRight, "be") == 0) {
323 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
324 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
325 } else if(sqlite3_stricmp(zRight, "native") == 0) {
326 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
327 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
329 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", deprecation, P4_TRANSIENT);
330 sqlite3_log(SQLITE_WARNING, deprecation);
332 } else {
333 if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO)) {
334 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "le", P4_TRANSIENT);
335 } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO)) {
336 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "be", P4_TRANSIENT);
337 } else {
338 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "native", P4_TRANSIENT);
342 }else
343 if( sqlite3_stricmp(zLeft,"cipher_hmac_salt_mask")==0 ){
344 if(ctx) {
345 if(zRight) {
346 char *deprecation = "PRAGMA cipher_hmac_salt_mask is deprecated, please remove from use";
347 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
348 unsigned char mask = 0;
349 const unsigned char *hex = (const unsigned char *)zRight+2;
350 cipher_hex2bin(hex,2,&mask);
351 sqlcipher_set_hmac_salt_mask(mask);
353 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", deprecation, P4_TRANSIENT);
354 sqlite3_log(SQLITE_WARNING, deprecation);
355 } else {
356 char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
357 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask, P4_DYNAMIC);
360 }else
361 if( sqlite3_stricmp(zLeft,"cipher_plaintext_header_size")==0 ){
362 if(ctx) {
363 if( zRight ) {
364 int size = atoi(zRight);
365 /* deliberately ignore result code, if size is invalid it will be set to -1
366 and trip the error later in the codec */
367 sqlcipher_codec_ctx_set_plaintext_header_size(ctx, size);
368 } else {
369 char *size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
370 codec_vdbe_return_string(pParse, "cipher_plaintext_header_size", size, P4_DYNAMIC);
373 }else
374 if( sqlite3_stricmp(zLeft,"cipher_default_plaintext_header_size")==0 ){
375 if( zRight ) {
376 sqlcipher_set_default_plaintext_header_size(atoi(zRight));
377 } else {
378 char *size = sqlite3_mprintf("%d", sqlcipher_get_default_plaintext_header_size());
379 codec_vdbe_return_string(pParse, "cipher_default_plaintext_header_size", size, P4_DYNAMIC);
381 }else
382 if( sqlite3_stricmp(zLeft,"cipher_salt")==0 ){
383 if(ctx) {
384 if(zRight) {
385 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == (FILE_HEADER_SZ*2)+3) {
386 unsigned char *salt = (unsigned char*) sqlite3_malloc(FILE_HEADER_SZ);
387 const unsigned char *hex = (const unsigned char *)zRight+2;
388 cipher_hex2bin(hex,FILE_HEADER_SZ*2,salt);
389 sqlcipher_codec_ctx_set_kdf_salt(ctx, salt, FILE_HEADER_SZ);
390 sqlite3_free(salt);
392 } else {
393 void *salt;
394 char *hexsalt = (char*) sqlite3_malloc((FILE_HEADER_SZ*2)+1);
395 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &salt)) == SQLITE_OK) {
396 cipher_bin2hex(salt, FILE_HEADER_SZ, hexsalt);
397 codec_vdbe_return_string(pParse, "cipher_salt", hexsalt, P4_DYNAMIC);
398 } else {
399 sqlite3_free(hexsalt);
400 sqlcipher_codec_ctx_set_error(ctx, rc);
404 }else
405 if( sqlite3_stricmp(zLeft,"cipher_hmac_algorithm")==0 ){
406 if(ctx) {
407 if(zRight) {
408 rc = SQLITE_ERROR;
409 if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
410 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
411 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
412 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA256);
413 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
414 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
416 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
417 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
418 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
419 } else {
420 int algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
421 if(algorithm == SQLCIPHER_HMAC_SHA1) {
422 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
423 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
424 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
425 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
426 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
430 }else
431 if( sqlite3_stricmp(zLeft,"cipher_default_hmac_algorithm")==0 ){
432 if(zRight) {
433 rc = SQLITE_ERROR;
434 if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
435 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
436 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
437 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA256);
438 } else if(sqlite3_stricmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
439 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
441 } else {
442 int algorithm = sqlcipher_get_default_hmac_algorithm();
443 if(algorithm == SQLCIPHER_HMAC_SHA1) {
444 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
445 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
446 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
447 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
448 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
451 }else
452 if( sqlite3_stricmp(zLeft,"cipher_kdf_algorithm")==0 ){
453 if(ctx) {
454 if(zRight) {
455 rc = SQLITE_ERROR;
456 if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
457 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
458 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
459 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA256);
460 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
461 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
463 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
464 } else {
465 int algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
466 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
467 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
468 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
469 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
470 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
471 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
475 }else
476 if( sqlite3_stricmp(zLeft,"cipher_default_kdf_algorithm")==0 ){
477 if(zRight) {
478 rc = SQLITE_ERROR;
479 if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
480 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
481 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
482 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA256);
483 } else if(sqlite3_stricmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
484 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
486 } else {
487 int algorithm = sqlcipher_get_default_kdf_algorithm();
488 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
489 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
490 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
491 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
492 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
493 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
496 }else
497 if( sqlite3_stricmp(zLeft,"cipher_compatibility")==0 ){
498 if(ctx) {
499 if(zRight) {
500 int version = atoi(zRight);
502 switch(version) {
503 case 1:
504 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
505 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
506 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
507 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
508 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
509 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
510 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
511 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
512 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 0);
513 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
514 break;
516 case 2:
517 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
518 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
519 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
520 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
521 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
522 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
523 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
524 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
525 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
526 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
527 break;
529 case 3:
530 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
531 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
532 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
533 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
534 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
535 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
536 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 64000);
537 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
538 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
539 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
540 break;
542 default:
543 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 4096);
544 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
545 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
546 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
547 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
548 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
549 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 256000);
550 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
551 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
552 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
553 break;
556 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
557 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
560 }else
561 if( sqlite3_stricmp(zLeft,"cipher_default_compatibility")==0 ){
562 if(zRight) {
563 int version = atoi(zRight);
564 switch(version) {
565 case 1:
566 sqlcipher_set_default_pagesize(1024);
567 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
568 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
569 sqlcipher_set_default_kdf_iter(4000);
570 sqlcipher_set_default_use_hmac(0);
571 break;
573 case 2:
574 sqlcipher_set_default_pagesize(1024);
575 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
576 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
577 sqlcipher_set_default_kdf_iter(4000);
578 sqlcipher_set_default_use_hmac(1);
579 break;
581 case 3:
582 sqlcipher_set_default_pagesize(1024);
583 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
584 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
585 sqlcipher_set_default_kdf_iter(64000);
586 sqlcipher_set_default_use_hmac(1);
587 break;
589 default:
590 sqlcipher_set_default_pagesize(4096);
591 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
592 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
593 sqlcipher_set_default_kdf_iter(256000);
594 sqlcipher_set_default_use_hmac(1);
595 break;
598 }else
599 if( sqlite3_stricmp(zLeft,"cipher_memory_security")==0 ){
600 if( zRight ) {
601 sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1));
602 } else {
603 char *on = sqlite3_mprintf("%d", sqlcipher_get_mem_security());
604 codec_vdbe_return_string(pParse, "cipher_memory_security", on, P4_DYNAMIC);
606 }else
607 if( sqlite3_stricmp(zLeft,"cipher_settings")==0 ){
608 if(ctx) {
609 int algorithm;
610 char *pragma;
612 pragma = sqlite3_mprintf("PRAGMA kdf_iter = %d;", sqlcipher_codec_ctx_get_kdf_iter(ctx));
613 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
615 pragma = sqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx));
616 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
618 pragma = sqlite3_mprintf("PRAGMA cipher_use_hmac = %d;", sqlcipher_codec_ctx_get_use_hmac(ctx));
619 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
621 pragma = sqlite3_mprintf("PRAGMA cipher_plaintext_header_size = %d;", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
622 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
624 algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
625 pragma = NULL;
626 if(algorithm == SQLCIPHER_HMAC_SHA1) {
627 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
628 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
629 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
630 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
631 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
633 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
635 algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
636 pragma = NULL;
637 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
638 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
639 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
640 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
641 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
642 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
644 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
647 }else
648 if( sqlite3_stricmp(zLeft,"cipher_default_settings")==0 ){
649 int algorithm;
650 char *pragma;
652 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_iter = %d;", sqlcipher_get_default_kdf_iter());
653 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
655 pragma = sqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize());
656 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
658 pragma = sqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac());
659 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
661 pragma = sqlite3_mprintf("PRAGMA cipher_default_plaintext_header_size = %d;", sqlcipher_get_default_plaintext_header_size());
662 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
664 algorithm = sqlcipher_get_default_hmac_algorithm();
665 pragma = NULL;
666 if(algorithm == SQLCIPHER_HMAC_SHA1) {
667 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
668 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
669 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
670 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
671 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
673 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
675 algorithm = sqlcipher_get_default_kdf_algorithm();
676 pragma = NULL;
677 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
678 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
679 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
680 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
681 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
682 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
684 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
685 }else
686 if( sqlite3_stricmp(zLeft,"cipher_integrity_check")==0 ){
687 if(ctx) {
688 sqlcipher_codec_ctx_integrity_check(ctx, pParse, "cipher_integrity_check");
690 } else
691 if( sqlite3_stricmp(zLeft, "cipher_log_level")==0 && zRight){
692 unsigned int level = SQLCIPHER_LOG_NONE;
693 if(sqlite3_stricmp(zRight, "ERROR")==0) level = SQLCIPHER_LOG_ERROR;
694 else if(sqlite3_stricmp(zRight, "WARN" )==0) level = SQLCIPHER_LOG_WARN;
695 else if(sqlite3_stricmp(zRight, "INFO" )==0) level = SQLCIPHER_LOG_INFO;
696 else if(sqlite3_stricmp(zRight, "DEBUG")==0) level = SQLCIPHER_LOG_DEBUG;
697 else if(sqlite3_stricmp(zRight, "TRACE")==0) level = SQLCIPHER_LOG_TRACE;
698 sqlcipher_set_log_level(level);
699 codec_vdbe_return_string(pParse, "cipher_log_level", sqlite3_mprintf("%u", level), P4_DYNAMIC);
700 } else
701 if( sqlite3_stricmp(zLeft, "cipher_log")== 0 && zRight ){
702 char *status = sqlite3_mprintf("%d", sqlcipher_set_log(zRight));
703 codec_vdbe_return_string(pParse, "cipher_log", status, P4_DYNAMIC);
704 }else {
705 return 0;
707 return 1;
710 /* these constants are used internally within SQLite's pager.c to differentiate between
711 operations on the main database or journal pages. This is important in the context
712 of a rekey operations, where the journal must be written using the original key
713 material (to allow a transactional rollback), while the new database pages are being
714 written with the new key material*/
715 #define CODEC_READ_OP 3
716 #define CODEC_WRITE_OP 6
717 #define CODEC_JOURNAL_OP 7
720 * sqlite3Codec can be called in multiple modes.
721 * encrypt mode - expected to return a pointer to the
722 * encrypted data without altering pData.
723 * decrypt mode - expected to return a pointer to pData, with
724 * the data decrypted in the input buffer
726 static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
727 codec_ctx *ctx = (codec_ctx *) iCtx;
728 int offset = 0, rc = 0;
729 int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
730 unsigned char *pData = (unsigned char *) data;
731 void *buffer = sqlcipher_codec_ctx_get_data(ctx);
732 int plaintext_header_sz = sqlcipher_codec_ctx_get_plaintext_header_size(ctx);
733 int cctx = CIPHER_READ_CTX;
735 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d", pgno, mode, page_sz);
737 #ifdef SQLCIPHER_EXT
738 if(sqlcipher_license_check(ctx) != SQLITE_OK) return NULL;
739 #endif
741 /* call to derive keys if not present yet */
742 if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
743 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error occurred during key derivation: %d", rc);
744 sqlcipher_codec_ctx_set_error(ctx, rc);
745 return NULL;
748 /* if the plaintext_header_size is negative that means an invalid size was set via
749 PRAGMA. We can't set the error state on the pager at that point because the pager
750 may not be open yet. However, this is a fatal error state, so abort the codec */
751 if(plaintext_header_sz < 0) {
752 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error invalid plaintext_header_sz: %d", plaintext_header_sz);
753 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
754 return NULL;
757 if(pgno == 1) /* adjust starting pointers in data page for header offset on first page*/
758 offset = plaintext_header_sz ? plaintext_header_sz : FILE_HEADER_SZ;
761 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3Codec: switch mode=%d offset=%d", mode, offset);
762 switch(mode) {
763 case CODEC_READ_OP: /* decrypt */
764 if(pgno == 1) /* copy initial part of file header or SQLite magic to buffer */
765 memcpy(buffer, plaintext_header_sz ? pData : (void *) SQLITE_FILE_HEADER, offset);
767 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
768 #ifdef SQLCIPHER_TEST
769 if((sqlcipher_get_test_flags() & TEST_FAIL_DECRYPT) > 0 && sqlcipher_get_test_fail()) {
770 rc = SQLITE_ERROR;
771 sqlcipher_log(SQLCIPHER_LOG_ERROR, "simulating decryption failure for pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
773 #endif
774 if(rc != SQLITE_OK) {
775 /* failure to decrypt a page is considered a permanent error and will render the pager unusable
776 in order to prevent inconsistent data being loaded into page cache */
777 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error decrypting page %d data: %d", pgno, rc);
778 sqlcipher_memset((unsigned char*) buffer+offset, 0, page_sz-offset);
779 sqlcipher_codec_ctx_set_error(ctx, rc);
781 memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
782 return pData;
783 break;
785 case CODEC_WRITE_OP: /* encrypt database page, operate on write context and fall through to case 7, so the write context is used*/
786 cctx = CIPHER_WRITE_CTX;
788 case CODEC_JOURNAL_OP: /* encrypt journal page, operate on read context use to get the original page data from the database */
789 if(pgno == 1) { /* copy initial part of file header or salt to buffer */
790 void *kdf_salt = NULL;
791 /* retrieve the kdf salt */
792 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &kdf_salt)) != SQLITE_OK) {
793 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error retrieving salt: %d", rc);
794 sqlcipher_codec_ctx_set_error(ctx, rc);
795 return NULL;
797 memcpy(buffer, plaintext_header_sz ? pData : kdf_salt, offset);
799 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
800 #ifdef SQLCIPHER_TEST
801 if((sqlcipher_get_test_flags() & TEST_FAIL_ENCRYPT) > 0 && sqlcipher_get_test_fail()) {
802 rc = SQLITE_ERROR;
803 sqlcipher_log(SQLCIPHER_LOG_ERROR, "simulating encryption failure for pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
805 #endif
806 if(rc != SQLITE_OK) {
807 /* failure to encrypt a page is considered a permanent error and will render the pager unusable
808 in order to prevent corrupted pages from being written to the main databased when using WAL */
809 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error encrypting page %d data: %d", pgno, rc);
810 sqlcipher_memset((unsigned char*)buffer+offset, 0, page_sz-offset);
811 sqlcipher_codec_ctx_set_error(ctx, rc);
812 return NULL;
814 return buffer; /* return persistent buffer data, pData remains intact */
815 break;
817 default:
818 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error unsupported codec mode %d", mode);
819 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); /* unsupported mode, set error */
820 return pData;
821 break;
825 static void sqlite3FreeCodecArg(void *pCodecArg) {
826 codec_ctx *ctx = (codec_ctx *) pCodecArg;
827 if(pCodecArg == NULL) return;
828 sqlcipher_codec_ctx_free(&ctx); /* wipe and free allocated memory for the context */
829 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
832 int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
833 struct Db *pDb = &db->aDb[nDb];
835 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%p, nKey=%d", db, nDb, zKey, nKey);
837 if(nKey && zKey && pDb->pBt) {
838 int rc;
839 Pager *pPager = pDb->pBt->pBt->pPager;
840 sqlite3_file *fd;
841 codec_ctx *ctx;
843 /* check if the sqlite3_file is open, and if not force handle to NULL */
844 if((fd = sqlite3PagerFile(pPager))->pMethods == 0) fd = NULL;
846 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling sqlcipher_activate()");
847 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
849 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: entering database mutex %p", db->mutex);
850 sqlite3_mutex_enter(db->mutex);
851 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: entered database mutex %p", db->mutex);
853 #ifdef SQLCIPHER_EXT
854 if((rc = sqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) {
855 sqlite3_mutex_leave(db->mutex);
856 return rc;
858 #endif
860 /* point the internal codec argument against the contet to be prepared */
861 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()");
862 rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, zKey, nKey);
864 if(rc != SQLITE_OK) {
865 /* initialization failed, do not attach potentially corrupted context */
866 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3CodecAttach: context initialization failed forcing error state with rc=%d", rc);
867 /* force an error at the pager level, such that even the upstream caller ignores the return code
868 the pager will be in an error state and will process no further operations */
869 sqlite3pager_error(pPager, rc);
870 pDb->pBt->pBt->db->errCode = rc;
871 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)", db->mutex, rc);
872 sqlite3_mutex_leave(db->mutex);
873 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: left database mutex %p (early return on rc=%d)", db->mutex, rc);
874 return rc;
877 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling sqlite3PagerSetCodec()");
878 sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
880 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()");
881 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
883 /* force secure delete. This has the benefit of wiping internal data when deleted
884 and also ensures that all pages are written to disk (i.e. not skipped by
885 sqlite3PagerDontWrite optimizations) */
886 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()");
887 sqlite3BtreeSecureDelete(pDb->pBt, 1);
889 /* if fd is null, then this is an in-memory database and
890 we dont' want to overwrite the AutoVacuum settings
891 if not null, then set to the default */
892 if(fd != NULL) {
893 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()");
894 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
896 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: leaving database mutex %p", db->mutex);
897 sqlite3_mutex_leave(db->mutex);
898 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3CodecAttach: left database mutex %p", db->mutex);
900 return SQLITE_OK;
903 int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
904 int db_index;
905 if(zDb == NULL){
906 return 0;
908 for(db_index = 0; db_index < db->nDb; db_index++) {
909 struct Db *pDb = &db->aDb[db_index];
910 if(strcmp(pDb->zDbSName, zDb) == 0) {
911 return db_index;
914 return 0;
917 void sqlite3_activate_see(const char* in) {
918 /* do nothing, security enhancements are always active */
921 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
922 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_key entered: db=%p pKey=%p nKey=%d", db, pKey, nKey);
923 return sqlite3_key_v2(db, "main", pKey, nKey);
926 int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
927 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_key_v2: entered db=%p zDb=%s pKey=%p nKey=%d", db, zDb, pKey, nKey);
928 /* attach key if db and pKey are not null and nKey is > 0 */
929 if(db && pKey && nKey) {
930 int db_index = sqlcipher_find_db_index(db, zDb);
931 return sqlite3CodecAttach(db, db_index, pKey, nKey);
933 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_key_v2: no key provided");
934 return SQLITE_ERROR;
937 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
938 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey entered: db=%p pKey=%p nKey=%d", db, pKey, nKey);
939 return sqlite3_rekey_v2(db, "main", pKey, nKey);
942 /* sqlite3_rekey_v2
943 ** Given a database, this will reencrypt the database using a new key.
944 ** There is only one possible modes of operation - to encrypt a database
945 ** that is already encrpyted. If the database is not already encrypted
946 ** this should do nothing
947 ** The proposed logic for this function follows:
948 ** 1. Determine if the database is already encryptped
949 ** 2. If there is NOT already a key present do nothing
950 ** 3. If there is a key present, re-encrypt the database with the new key
952 int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
953 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%p, nKey=%d", db, zDb, pKey, nKey);
954 if(db && pKey && nKey) {
955 int db_index = sqlcipher_find_db_index(db, zDb);
956 struct Db *pDb = &db->aDb[db_index];
957 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: database pDb=%p db_index:%d", pDb, db_index);
958 if(pDb->pBt) {
959 codec_ctx *ctx;
960 int rc, page_count;
961 Pgno pgno;
962 PgHdr *page;
963 Pager *pPager = pDb->pBt->pBt->pPager;
965 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
967 if(ctx == NULL) {
968 /* there was no codec attached to this database, so this should do nothing! */
969 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: no codec attached to db, exiting");
970 return SQLITE_OK;
973 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: entering database mutex %p", db->mutex);
974 sqlite3_mutex_enter(db->mutex);
975 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: entered database mutex %p", db->mutex);
977 codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
979 /* do stuff here to rewrite the database
980 ** 1. Create a transaction on the database
981 ** 2. Iterate through each page, reading it and then writing it.
982 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
983 ** note: don't deallocate rekey since it may be used in a subsequent iteration
985 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */
986 sqlite3PagerPagecount(pPager, &page_count);
987 for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
988 if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
989 rc = sqlite3PagerGet(pPager, pgno, &page, 0);
990 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
991 rc = sqlite3PagerWrite(page);
992 if(rc == SQLITE_OK) {
993 sqlite3PagerUnref(page);
994 } else {
995 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: error %d occurred writing page %d", rc, pgno);
997 } else {
998 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: error %d occurred getting page %d", rc, pgno);
1003 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
1004 if(rc == SQLITE_OK) {
1005 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: committing");
1006 rc = sqlite3BtreeCommit(pDb->pBt);
1007 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
1008 } else {
1009 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: rollback");
1010 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
1013 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: leaving database mutex %p", db->mutex);
1014 sqlite3_mutex_leave(db->mutex);
1015 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: left database mutex %p", db->mutex);
1017 return SQLITE_OK;
1019 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: no key provided");
1020 return SQLITE_ERROR;
1023 void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
1024 struct Db *pDb = &db->aDb[nDb];
1025 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3CodecGetKey: entered db=%p, nDb=%d", db, nDb);
1026 if( pDb->pBt ) {
1027 codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
1029 if(ctx) {
1030 /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass
1031 is set or keyspec has not yet been derived, in which case pass
1032 back the password key material */
1033 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
1034 if(sqlcipher_codec_get_store_pass(ctx) == 1 || *zKey == NULL) {
1035 sqlcipher_codec_get_pass(ctx, zKey, nKey);
1037 } else {
1038 *zKey = NULL;
1039 *nKey = 0;
1045 * Implementation of an "export" function that allows a caller
1046 * to duplicate the main database to an attached database. This is intended
1047 * as a conveneince for users who need to:
1049 * 1. migrate from an non-encrypted database to an encrypted database
1050 * 2. move from an encrypted database to a non-encrypted database
1051 * 3. convert beween the various flavors of encrypted databases.
1053 * This implementation is based heavily on the procedure and code used
1054 * in vacuum.c, but is exposed as a function that allows export to any
1055 * named attached database.
1059 ** Finalize a prepared statement. If there was an error, store the
1060 ** text of the error message in *pzErrMsg. Return the result code.
1062 ** Based on vacuumFinalize from vacuum.c
1064 static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
1065 int rc;
1066 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
1067 if( rc ){
1068 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1070 return rc;
1074 ** Execute zSql on database db. Return an error code.
1076 ** Based on execSql from vacuum.c
1078 static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1079 sqlite3_stmt *pStmt;
1080 VVA_ONLY( int rc; )
1081 if( !zSql ){
1082 return SQLITE_NOMEM;
1084 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
1085 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1086 return sqlite3_errcode(db);
1088 VVA_ONLY( rc = ) sqlite3_step(pStmt);
1089 assert( rc!=SQLITE_ROW );
1090 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1094 ** Execute zSql on database db. The statement returns exactly
1095 ** one column. Execute this as SQL on the same database.
1097 ** Based on execExecSql from vacuum.c
1099 static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1100 sqlite3_stmt *pStmt;
1101 int rc;
1103 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
1104 if( rc!=SQLITE_OK ) return rc;
1106 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1107 rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
1108 if( rc!=SQLITE_OK ){
1109 sqlcipher_finalize(db, pStmt, pzErrMsg);
1110 return rc;
1114 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1118 * copy database and schema from the main database to an attached database
1120 * Based on sqlite3RunVacuum from vacuum.c
1122 void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
1123 sqlite3 *db = sqlite3_context_db_handle(context);
1124 const char* targetDb, *sourceDb;
1125 int targetDb_idx = 0;
1126 u64 saved_flags = db->flags; /* Saved value of the db->flags */
1127 u32 saved_mDbFlags = db->mDbFlags; /* Saved value of the db->mDbFlags */
1128 int saved_nChange = db->nChange; /* Saved value of db->nChange */
1129 int saved_nTotalChange = db->nTotalChange; /* Saved value of db->nTotalChange */
1130 u8 saved_mTrace = db->mTrace; /* Saved value of db->mTrace */
1131 int rc = SQLITE_OK; /* Return code from service routines */
1132 char *zSql = NULL; /* SQL statements */
1133 char *pzErrMsg = NULL;
1135 if(argc != 1 && argc != 2) {
1136 rc = SQLITE_ERROR;
1137 pzErrMsg = sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc);
1138 goto end_of_export;
1141 if(sqlite3_value_type(argv[0]) == SQLITE_NULL) {
1142 rc = SQLITE_ERROR;
1143 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1144 goto end_of_export;
1147 targetDb = (const char*) sqlite3_value_text(argv[0]);
1148 sourceDb = "main";
1150 if(argc == 2) {
1151 if(sqlite3_value_type(argv[1]) == SQLITE_NULL) {
1152 rc = SQLITE_ERROR;
1153 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1154 goto end_of_export;
1156 sourceDb = (char *) sqlite3_value_text(argv[1]);
1160 /* if the name of the target is not main, but the index returned is zero
1161 there is a mismatch and we should not proceed */
1162 targetDb_idx = sqlcipher_find_db_index(db, targetDb);
1163 if(targetDb_idx == 0 && targetDb != NULL && sqlite3_stricmp("main", targetDb) != 0) {
1164 rc = SQLITE_ERROR;
1165 pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb);
1166 goto end_of_export;
1168 db->init.iDb = targetDb_idx;
1170 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
1171 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
1172 db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows);
1173 db->mTrace = 0;
1175 /* Query the schema of the main database. Create a mirror schema
1176 ** in the temporary database.
1178 zSql = sqlite3_mprintf(
1179 "SELECT sql "
1180 " FROM %s.sqlite_schema WHERE type='table' AND name!='sqlite_sequence'"
1181 " AND rootpage>0"
1182 , sourceDb);
1183 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1184 if( rc!=SQLITE_OK ) goto end_of_export;
1185 sqlite3_free(zSql);
1187 zSql = sqlite3_mprintf(
1188 "SELECT sql "
1189 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE INDEX %%' "
1190 , sourceDb);
1191 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1192 if( rc!=SQLITE_OK ) goto end_of_export;
1193 sqlite3_free(zSql);
1195 zSql = sqlite3_mprintf(
1196 "SELECT sql "
1197 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
1198 , sourceDb);
1199 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1200 if( rc!=SQLITE_OK ) goto end_of_export;
1201 sqlite3_free(zSql);
1203 /* Loop through the tables in the main database. For each, do
1204 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
1205 ** the contents to the temporary database.
1207 zSql = sqlite3_mprintf(
1208 "SELECT 'INSERT INTO %s.' || quote(name) "
1209 "|| ' SELECT * FROM %s.' || quote(name) || ';'"
1210 "FROM %s.sqlite_schema "
1211 "WHERE type = 'table' AND name!='sqlite_sequence' "
1212 " AND rootpage>0"
1213 , targetDb, sourceDb, sourceDb);
1214 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1215 if( rc!=SQLITE_OK ) goto end_of_export;
1216 sqlite3_free(zSql);
1218 /* Copy over the contents of the sequence table
1220 zSql = sqlite3_mprintf(
1221 "SELECT 'INSERT INTO %s.' || quote(name) "
1222 "|| ' SELECT * FROM %s.' || quote(name) || ';' "
1223 "FROM %s.sqlite_schema WHERE name=='sqlite_sequence';"
1224 , targetDb, sourceDb, targetDb);
1225 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1226 if( rc!=SQLITE_OK ) goto end_of_export;
1227 sqlite3_free(zSql);
1229 /* Copy the triggers, views, and virtual tables from the main database
1230 ** over to the temporary database. None of these objects has any
1231 ** associated storage, so all we have to do is copy their entries
1232 ** from the SQLITE_MASTER table.
1234 zSql = sqlite3_mprintf(
1235 "INSERT INTO %s.sqlite_schema "
1236 " SELECT type, name, tbl_name, rootpage, sql"
1237 " FROM %s.sqlite_schema"
1238 " WHERE type='view' OR type='trigger'"
1239 " OR (type='table' AND rootpage=0)"
1240 , targetDb, sourceDb);
1241 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
1242 if( rc!=SQLITE_OK ) goto end_of_export;
1243 sqlite3_free(zSql);
1245 zSql = NULL;
1246 end_of_export:
1247 db->init.iDb = 0;
1248 db->flags = saved_flags;
1249 db->mDbFlags = saved_mDbFlags;
1250 db->nChange = saved_nChange;
1251 db->nTotalChange = saved_nTotalChange;
1252 db->mTrace = saved_mTrace;
1254 if(zSql) sqlite3_free(zSql);
1256 if(rc) {
1257 if(pzErrMsg != NULL) {
1258 sqlite3_result_error(context, pzErrMsg, -1);
1259 sqlite3DbFree(db, pzErrMsg);
1260 } else {
1261 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
1265 #endif
1266 /* END SQLCIPHER */