downgrade memory unlock failures to info level and fix function name in log output
[sqlcipher.git] / src / crypto.c
blob4a26117253415217c4d4fa1e9efe9fe3c133716b
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 void sqlcipher_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: db=%p nDb=%d for_ctx=%d", db, nDb, for_ctx);
80 if(pDb->pBt) {
81 codec_ctx *ctx = (codec_ctx*) sqlcipherPagerGetCodec(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*) sqlcipherPagerGetCodec(pDb->pBt->pBt->pPager);
103 if(sqlite3_stricmp(zLeft, "key") !=0 && sqlite3_stricmp(zLeft, "rekey") != 0) {
104 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipher_codec_pragma: db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p", db, iDb, pParse, zLeft, zRight, ctx);
107 #ifdef SQLCIPHER_EXT
108 if(sqlcipher_ext_pragma(db, iDb, pParse, zLeft, zRight)) {
109 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipher_codec_pragma: PRAGMA handled by sqlcipher_ext_pragma");
110 } else
111 #endif
112 #ifdef SQLCIPHER_TEST
113 if( sqlite3_stricmp(zLeft,"cipher_test_on")==0 ){
114 if( zRight ) {
115 unsigned int flags = sqlcipher_get_test_flags();
116 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
117 SQLCIPHER_FLAG_SET(flags,TEST_FAIL_ENCRYPT);
118 } else
119 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
120 SQLCIPHER_FLAG_SET(flags,TEST_FAIL_DECRYPT);
121 } else
122 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
123 SQLCIPHER_FLAG_SET(flags,TEST_FAIL_MIGRATE);
125 sqlcipher_set_test_flags(flags);
127 } else
128 if( sqlite3_stricmp(zLeft,"cipher_test_off")==0 ){
129 if( zRight ) {
130 unsigned int flags = sqlcipher_get_test_flags();
131 if(sqlite3_stricmp(zRight, "fail_encrypt")==0) {
132 SQLCIPHER_FLAG_UNSET(flags,TEST_FAIL_ENCRYPT);
133 } else
134 if(sqlite3_stricmp(zRight, "fail_decrypt")==0) {
135 SQLCIPHER_FLAG_UNSET(flags,TEST_FAIL_DECRYPT);
136 } else
137 if(sqlite3_stricmp(zRight, "fail_migrate")==0) {
138 SQLCIPHER_FLAG_UNSET(flags,TEST_FAIL_MIGRATE);
140 sqlcipher_set_test_flags(flags);
142 } else
143 if( sqlite3_stricmp(zLeft,"cipher_test")==0 ){
144 char *flags = sqlite3_mprintf("%u", sqlcipher_get_test_flags());
145 sqlcipher_vdbe_return_string(pParse, "cipher_test", flags, P4_DYNAMIC);
146 }else
147 if( sqlite3_stricmp(zLeft,"cipher_test_rand")==0 ){
148 if( zRight ) {
149 int rand = atoi(zRight);
150 sqlcipher_set_test_rand(rand);
151 } else {
152 char *rand = sqlite3_mprintf("%d", sqlcipher_get_test_rand());
153 sqlcipher_vdbe_return_string(pParse, "cipher_test_rand", rand, P4_DYNAMIC);
155 } else
156 #endif
157 if( sqlite3_stricmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
158 if(ctx) {
159 char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
160 sqlcipher_vdbe_return_string(pParse, "cipher_fips_status", fips_mode_status, P4_DYNAMIC);
162 } else
163 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && zRight ) {
164 if(ctx) {
165 char *deprecation = "PRAGMA cipher_store_pass is deprecated, please remove from use";
166 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
167 sqlcipher_vdbe_return_string(pParse, "cipher_store_pass", deprecation, P4_TRANSIENT);
168 sqlite3_log(SQLITE_WARNING, deprecation);
170 } else
171 if( sqlite3_stricmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
172 if(ctx){
173 char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
174 sqlcipher_vdbe_return_string(pParse, "cipher_store_pass", store_pass_value, P4_DYNAMIC);
177 if( sqlite3_stricmp(zLeft, "cipher_profile")== 0 && zRight ){
178 char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
179 sqlcipher_vdbe_return_string(pParse, "cipher_profile", profile_status, P4_DYNAMIC);
180 } else
181 if( sqlite3_stricmp(zLeft, "cipher_add_random")==0 && zRight ){
182 if(ctx) {
183 char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
184 sqlcipher_vdbe_return_string(pParse, "cipher_add_random", add_random_status, P4_DYNAMIC);
186 } else
187 if( sqlite3_stricmp(zLeft, "cipher_migrate")==0 && !zRight ){
188 if(ctx){
189 int status = sqlcipher_codec_ctx_migrate(ctx);
190 char *migrate_status = sqlite3_mprintf("%d", status);
191 sqlcipher_vdbe_return_string(pParse, "cipher_migrate", migrate_status, P4_DYNAMIC);
192 if(status != SQLITE_OK) {
193 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlcipher_codec_pragma: error occurred during cipher_migrate: %d", status);
194 sqlcipher_codec_ctx_set_error(ctx, status);
197 } else
198 if( sqlite3_stricmp(zLeft, "cipher_provider")==0 && !zRight ){
199 if(ctx) { sqlcipher_vdbe_return_string(pParse, "cipher_provider",
200 sqlcipher_codec_get_cipher_provider(ctx), P4_TRANSIENT);
202 } else
203 if( sqlite3_stricmp(zLeft, "cipher_provider_version")==0 && !zRight){
204 if(ctx) { sqlcipher_vdbe_return_string(pParse, "cipher_provider_version",
205 sqlcipher_codec_get_provider_version(ctx), P4_TRANSIENT);
207 } else
208 if( sqlite3_stricmp(zLeft, "cipher_version")==0 && !zRight ){
209 sqlcipher_vdbe_return_string(pParse, "cipher_version", sqlcipher_version(), P4_DYNAMIC);
210 }else
211 if( sqlite3_stricmp(zLeft, "cipher")==0 ){
212 if(ctx) {
213 if( zRight ) {
214 const char* message = "PRAGMA cipher is no longer supported.";
215 sqlcipher_vdbe_return_string(pParse, "cipher", message, P4_TRANSIENT);
216 sqlite3_log(SQLITE_WARNING, message);
217 }else {
218 sqlcipher_vdbe_return_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx), P4_TRANSIENT);
221 }else
222 if( sqlite3_stricmp(zLeft, "rekey_cipher")==0 && zRight ){
223 const char* message = "PRAGMA rekey_cipher is no longer supported.";
224 sqlcipher_vdbe_return_string(pParse, "rekey_cipher", message, P4_TRANSIENT);
225 sqlite3_log(SQLITE_WARNING, message);
226 }else
227 if( sqlite3_stricmp(zLeft,"cipher_default_kdf_iter")==0 ){
228 if( zRight ) {
229 sqlcipher_set_default_kdf_iter(atoi(zRight)); /* change default KDF iterations */
230 } else {
231 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
232 sqlcipher_vdbe_return_string(pParse, "cipher_default_kdf_iter", kdf_iter, P4_DYNAMIC);
234 }else
235 if( sqlite3_stricmp(zLeft, "kdf_iter")==0 ){
236 if(ctx) {
237 if( zRight ) {
238 sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
239 } else {
240 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx));
241 sqlcipher_vdbe_return_string(pParse, "kdf_iter", kdf_iter, P4_DYNAMIC);
244 }else
245 if( sqlite3_stricmp(zLeft, "fast_kdf_iter")==0){
246 if(ctx) {
247 if( zRight ) {
248 char *deprecation = "PRAGMA fast_kdf_iter is deprecated, please remove from use";
249 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
250 sqlcipher_vdbe_return_string(pParse, "fast_kdf_iter", deprecation, P4_TRANSIENT);
251 sqlite3_log(SQLITE_WARNING, deprecation);
252 } else {
253 char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx));
254 sqlcipher_vdbe_return_string(pParse, "fast_kdf_iter", fast_kdf_iter, P4_DYNAMIC);
257 }else
258 if( sqlite3_stricmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
259 const char* message = "PRAGMA rekey_kdf_iter is no longer supported.";
260 sqlcipher_vdbe_return_string(pParse, "rekey_kdf_iter", message, P4_TRANSIENT);
261 sqlite3_log(SQLITE_WARNING, message);
262 }else
263 if( sqlite3_stricmp(zLeft,"page_size")==0 || sqlite3_stricmp(zLeft,"cipher_page_size")==0 ){
264 /* PRAGMA cipher_page_size will alter the size of the database pages while ensuring that the
265 required reserve space is allocated at the end of each page. This will also override the
266 standard SQLite PRAGMA page_size behavior if a codec context is attached to the database handle.
267 If PRAGMA page_size is invoked but a codec context is not attached (i.e. dealing with a standard
268 unencrypted database) then return early and allow the standard PRAGMA page_size logic to apply. */
269 if(ctx) {
270 if( zRight ) {
271 int size = atoi(zRight);
272 rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
273 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
274 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
275 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
276 } else {
277 char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
278 sqlcipher_vdbe_return_string(pParse, "cipher_page_size", page_size, P4_DYNAMIC);
280 } else {
281 return 0; /* return early so that the PragTyp_PAGE_SIZE case logic in pragma.c will take effect */
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 sqlcipher_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 sqlcipher_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 sqlcipher_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_FLAG_UNSET(ctx->flags, CIPHER_FLAG_BE_PGNO);
321 SQLCIPHER_FLAG_SET(ctx->flags, CIPHER_FLAG_LE_PGNO);
322 } else if(sqlite3_stricmp(zRight, "be") == 0) {
323 SQLCIPHER_FLAG_UNSET(ctx->flags, CIPHER_FLAG_LE_PGNO);
324 SQLCIPHER_FLAG_SET(ctx->flags, CIPHER_FLAG_BE_PGNO);
325 } else if(sqlite3_stricmp(zRight, "native") == 0) {
326 SQLCIPHER_FLAG_UNSET(ctx->flags, CIPHER_FLAG_LE_PGNO);
327 SQLCIPHER_FLAG_UNSET(ctx->flags, CIPHER_FLAG_BE_PGNO);
329 sqlcipher_vdbe_return_string(pParse, "cipher_hmac_pgno", deprecation, P4_TRANSIENT);
330 sqlite3_log(SQLITE_WARNING, deprecation);
332 } else {
333 if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_LE_PGNO)) {
334 sqlcipher_vdbe_return_string(pParse, "cipher_hmac_pgno", "le", P4_TRANSIENT);
335 } else if(SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_BE_PGNO)) {
336 sqlcipher_vdbe_return_string(pParse, "cipher_hmac_pgno", "be", P4_TRANSIENT);
337 } else {
338 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
423 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
424 sqlcipher_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
425 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
426 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
445 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
446 sqlcipher_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
447 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
448 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
468 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
469 sqlcipher_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
470 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
471 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
490 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
491 sqlcipher_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
492 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
493 sqlcipher_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 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
615 pragma = sqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx));
616 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
655 pragma = sqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize());
656 sqlcipher_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
658 pragma = sqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac());
659 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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 sqlcipher_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: 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_WARN, "sqlite3Codec: 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);
780 } else {
781 SQLCIPHER_FLAG_SET(ctx->flags, CIPHER_FLAG_KEY_USED);
783 memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
784 return pData;
785 break;
787 case CODEC_WRITE_OP: /* encrypt database page, operate on write context and fall through to case 7, so the write context is used*/
788 cctx = CIPHER_WRITE_CTX;
790 case CODEC_JOURNAL_OP: /* encrypt journal page, operate on read context use to get the original page data from the database */
791 if(pgno == 1) { /* copy initial part of file header or salt to buffer */
792 void *kdf_salt = NULL;
793 /* retrieve the kdf salt */
794 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &kdf_salt)) != SQLITE_OK) {
795 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error retrieving salt: %d", rc);
796 sqlcipher_codec_ctx_set_error(ctx, rc);
797 return NULL;
799 memcpy(buffer, plaintext_header_sz ? pData : kdf_salt, offset);
801 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
802 #ifdef SQLCIPHER_TEST
803 if((sqlcipher_get_test_flags() & TEST_FAIL_ENCRYPT) > 0 && sqlcipher_get_test_fail()) {
804 rc = SQLITE_ERROR;
805 sqlcipher_log(SQLCIPHER_LOG_WARN, "sqlite3Codec: simulating encryption failure for pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
807 #endif
808 if(rc != SQLITE_OK) {
809 /* failure to encrypt a page is considered a permanent error and will render the pager unusable
810 in order to prevent corrupted pages from being written to the main databased when using WAL */
811 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error encrypting page %d data: %d", pgno, rc);
812 sqlcipher_memset((unsigned char*)buffer+offset, 0, page_sz-offset);
813 sqlcipher_codec_ctx_set_error(ctx, rc);
814 return NULL;
816 SQLCIPHER_FLAG_SET(ctx->flags, CIPHER_FLAG_KEY_USED);
817 return buffer; /* return persistent buffer data, pData remains intact */
818 break;
820 default:
821 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3Codec: error unsupported codec mode %d", mode);
822 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); /* unsupported mode, set error */
823 return pData;
824 break;
828 static void sqlite3FreeCodecArg(void *pCodecArg) {
829 codec_ctx *ctx = (codec_ctx *) pCodecArg;
830 if(pCodecArg == NULL) return;
831 sqlcipher_codec_ctx_free(&ctx); /* wipe and free allocated memory for the context */
832 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
835 int sqlcipherCodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
836 struct Db *pDb = &db->aDb[nDb];
838 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: db=%p, nDb=%d", db, nDb);
840 if(nKey && zKey && pDb->pBt) {
841 int rc;
842 Pager *pPager = pDb->pBt->pBt->pPager;
843 sqlite3_file *fd;
844 codec_ctx *ctx;
846 ctx = (codec_ctx*) sqlcipherPagerGetCodec(pDb->pBt->pBt->pPager);
848 if(ctx != NULL && SQLCIPHER_FLAG_GET(ctx->flags, CIPHER_FLAG_KEY_USED)) {
849 /* there is already a codec attached to this database, so we should not proceed */
850 sqlcipher_log(SQLCIPHER_LOG_WARN, "sqlcipherCodecAttach: no codec attached to db");
851 return SQLITE_OK;
854 /* check if the sqlite3_file is open, and if not force handle to NULL */
855 if((fd = sqlite3PagerFile(pPager))->pMethods == 0) fd = NULL;
857 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling sqlcipher_activate()");
858 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
860 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: entering database mutex %p", db->mutex);
861 sqlite3_mutex_enter(db->mutex);
862 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: entered database mutex %p", db->mutex);
864 #ifdef SQLCIPHER_EXT
865 if((rc = sqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) {
866 sqlite3_mutex_leave(db->mutex);
867 return rc;
869 #endif
871 /* point the internal codec argument against the contet to be prepared */
872 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling sqlcipher_codec_ctx_init()");
873 rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, zKey, nKey);
875 if(rc != SQLITE_OK) {
876 /* initialization failed, do not attach potentially corrupted context */
877 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlcipherCodecAttach: context initialization failed, forcing error state with rc=%d", rc);
878 /* force an error at the pager level, such that even the upstream caller ignores the return code
879 the pager will be in an error state and will process no further operations */
880 sqlite3pager_error(pPager, rc);
881 pDb->pBt->pBt->db->errCode = rc;
882 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: leaving database mutex %p (early return on rc=%d)", db->mutex, rc);
883 sqlite3_mutex_leave(db->mutex);
884 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: left database mutex %p (early return on rc=%d)", db->mutex, rc);
885 return rc;
888 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling sqlcipherPagerSetCodec()");
889 sqlcipherPagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
891 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling codec_set_btree_to_codec_pagesize()");
892 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
894 /* force secure delete. This has the benefit of wiping internal data when deleted
895 and also ensures that all pages are written to disk (i.e. not skipped by
896 sqlite3PagerDontWrite optimizations) */
897 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling sqlite3BtreeSecureDelete()");
898 sqlite3BtreeSecureDelete(pDb->pBt, 1);
900 /* if fd is null, then this is an in-memory database and
901 we dont' want to overwrite the AutoVacuum settings
902 if not null, then set to the default */
903 if(fd != NULL) {
904 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecAttach: calling sqlite3BtreeSetAutoVacuum()");
905 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
907 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: leaving database mutex %p", db->mutex);
908 sqlite3_mutex_leave(db->mutex);
909 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlcipherCodecAttach: left database mutex %p", db->mutex);
911 return SQLITE_OK;
914 int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
915 int db_index;
916 if(zDb == NULL){
917 return 0;
919 for(db_index = 0; db_index < db->nDb; db_index++) {
920 struct Db *pDb = &db->aDb[db_index];
921 if(strcmp(pDb->zDbSName, zDb) == 0) {
922 return db_index;
925 return 0;
928 void sqlite3_activate_see(const char* in) {
929 /* do nothing, security enhancements are always active */
932 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
933 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_key: db=%p", db);
934 return sqlite3_key_v2(db, "main", pKey, nKey);
937 int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
938 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_key_v2: db=%p zDb=%s", db, zDb);
939 /* attach key if db and pKey are not null and nKey is > 0 */
940 if(db && pKey && nKey) {
941 int db_index = sqlcipher_find_db_index(db, zDb);
942 return sqlcipherCodecAttach(db, db_index, pKey, nKey);
944 sqlcipher_log(SQLCIPHER_LOG_WARN, "sqlite3_key_v2: no key provided");
945 return SQLITE_ERROR;
948 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
949 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey: db=%p", db);
950 return sqlite3_rekey_v2(db, "main", pKey, nKey);
953 /* sqlite3_rekey_v2
954 ** Given a database, this will reencrypt the database using a new key.
955 ** There is only one possible modes of operation - to encrypt a database
956 ** that is already encrpyted. If the database is not already encrypted
957 ** this should do nothing
958 ** The proposed logic for this function follows:
959 ** 1. Determine if the database is already encryptped
960 ** 2. If there is NOT already a key present do nothing
961 ** 3. If there is a key present, re-encrypt the database with the new key
963 int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
964 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: db=%p zDb=%s", db, zDb);
965 if(db && pKey && nKey) {
966 int db_index = sqlcipher_find_db_index(db, zDb);
967 struct Db *pDb = &db->aDb[db_index];
968 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: database zDb=%p db_index:%d", zDb, db_index);
969 if(pDb->pBt) {
970 codec_ctx *ctx;
971 int rc, page_count;
972 Pgno pgno;
973 PgHdr *page;
974 Pager *pPager = pDb->pBt->pBt->pPager;
976 ctx = (codec_ctx*) sqlcipherPagerGetCodec(pDb->pBt->pBt->pPager);
978 if(ctx == NULL) {
979 /* there was no codec attached to this database, so this should do nothing! */
980 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: no codec attached to db %s: rekey can't be used on an unencrypted database", zDb);
981 return SQLITE_MISUSE;
984 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: entering database mutex %p", db->mutex);
985 sqlite3_mutex_enter(db->mutex);
986 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: entered database mutex %p", db->mutex);
988 codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
990 /* do stuff here to rewrite the database
991 ** 1. Create a transaction on the database
992 ** 2. Iterate through each page, reading it and then writing it.
993 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
994 ** note: don't deallocate rekey since it may be used in a subsequent iteration
996 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */
997 sqlite3PagerPagecount(pPager, &page_count);
998 for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
999 if(!sqlite3pager_is_sj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
1000 rc = sqlite3PagerGet(pPager, pgno, &page, 0);
1001 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
1002 rc = sqlite3PagerWrite(page);
1003 if(rc == SQLITE_OK) {
1004 sqlite3PagerUnref(page);
1005 } else {
1006 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: error %d occurred writing page %d", rc, pgno);
1008 } else {
1009 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: error %d occurred reading page %d", rc, pgno);
1014 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
1015 if(rc == SQLITE_OK) {
1016 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: committing");
1017 rc = sqlite3BtreeCommit(pDb->pBt);
1018 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
1019 } else {
1020 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlite3_rekey_v2: rollback");
1021 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
1024 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: leaving database mutex %p", db->mutex);
1025 sqlite3_mutex_leave(db->mutex);
1026 sqlcipher_log(SQLCIPHER_LOG_TRACE, "sqlite3_rekey_v2: left database mutex %p", db->mutex);
1028 return SQLITE_OK;
1030 sqlcipher_log(SQLCIPHER_LOG_ERROR, "sqlite3_rekey_v2: no key provided for db %s: rekey can't be used to decrypt an encrypted database", zDb);
1031 return SQLITE_ERROR;
1034 void sqlcipherCodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
1035 struct Db *pDb = &db->aDb[nDb];
1036 sqlcipher_log(SQLCIPHER_LOG_DEBUG, "sqlcipherCodecGetKey:db=%p, nDb=%d", db, nDb);
1037 if( pDb->pBt ) {
1038 codec_ctx *ctx = (codec_ctx*) sqlcipherPagerGetCodec(pDb->pBt->pBt->pPager);
1040 if(ctx) {
1041 /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass
1042 is set or keyspec has not yet been derived, in which case pass
1043 back the password key material */
1044 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
1045 if(sqlcipher_codec_get_store_pass(ctx) == 1 || *zKey == NULL) {
1046 sqlcipher_codec_get_pass(ctx, zKey, nKey);
1048 } else {
1049 *zKey = NULL;
1050 *nKey = 0;
1056 * Implementation of an "export" function that allows a caller
1057 * to duplicate the main database to an attached database. This is intended
1058 * as a conveneince for users who need to:
1060 * 1. migrate from an non-encrypted database to an encrypted database
1061 * 2. move from an encrypted database to a non-encrypted database
1062 * 3. convert beween the various flavors of encrypted databases.
1064 * This implementation is based heavily on the procedure and code used
1065 * in vacuum.c, but is exposed as a function that allows export to any
1066 * named attached database.
1070 ** Finalize a prepared statement. If there was an error, store the
1071 ** text of the error message in *pzErrMsg. Return the result code.
1073 ** Based on vacuumFinalize from vacuum.c
1075 static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
1076 int rc;
1077 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
1078 if( rc ){
1079 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1081 return rc;
1085 ** Execute zSql on database db. Return an error code.
1087 ** Based on execSql from vacuum.c
1089 static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1090 sqlite3_stmt *pStmt;
1091 VVA_ONLY( int rc; )
1092 if( !zSql ){
1093 return SQLITE_NOMEM;
1095 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
1096 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
1097 return sqlite3_errcode(db);
1099 VVA_ONLY( rc = ) sqlite3_step(pStmt);
1100 assert( rc!=SQLITE_ROW );
1101 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1105 ** Execute zSql on database db. The statement returns exactly
1106 ** one column. Execute this as SQL on the same database.
1108 ** Based on execExecSql from vacuum.c
1110 static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
1111 sqlite3_stmt *pStmt;
1112 int rc;
1114 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
1115 if( rc!=SQLITE_OK ) return rc;
1117 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1118 rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
1119 if( rc!=SQLITE_OK ){
1120 sqlcipher_finalize(db, pStmt, pzErrMsg);
1121 return rc;
1125 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1129 * copy database and schema from the main database to an attached database
1131 * Based on sqlite3RunVacuum from vacuum.c
1133 void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
1134 sqlite3 *db = sqlite3_context_db_handle(context);
1135 const char* targetDb, *sourceDb;
1136 int targetDb_idx = 0;
1137 u64 saved_flags = db->flags; /* Saved value of the db->flags */
1138 u32 saved_mDbFlags = db->mDbFlags; /* Saved value of the db->mDbFlags */
1139 int saved_nChange = db->nChange; /* Saved value of db->nChange */
1140 int saved_nTotalChange = db->nTotalChange; /* Saved value of db->nTotalChange */
1141 u8 saved_mTrace = db->mTrace; /* Saved value of db->mTrace */
1142 int rc = SQLITE_OK; /* Return code from service routines */
1143 char *zSql = NULL; /* SQL statements */
1144 char *pzErrMsg = NULL;
1146 if(argc != 1 && argc != 2) {
1147 rc = SQLITE_ERROR;
1148 pzErrMsg = sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc);
1149 goto end_of_export;
1152 if(sqlite3_value_type(argv[0]) == SQLITE_NULL) {
1153 rc = SQLITE_ERROR;
1154 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1155 goto end_of_export;
1158 targetDb = (const char*) sqlite3_value_text(argv[0]);
1159 sourceDb = "main";
1161 if(argc == 2) {
1162 if(sqlite3_value_type(argv[1]) == SQLITE_NULL) {
1163 rc = SQLITE_ERROR;
1164 pzErrMsg = sqlite3_mprintf("target database can't be NULL");
1165 goto end_of_export;
1167 sourceDb = (char *) sqlite3_value_text(argv[1]);
1171 /* if the name of the target is not main, but the index returned is zero
1172 there is a mismatch and we should not proceed */
1173 targetDb_idx = sqlcipher_find_db_index(db, targetDb);
1174 if(targetDb_idx == 0 && targetDb != NULL && sqlite3_stricmp("main", targetDb) != 0) {
1175 rc = SQLITE_ERROR;
1176 pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb);
1177 goto end_of_export;
1179 db->init.iDb = targetDb_idx;
1181 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
1182 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
1183 db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows);
1184 db->mTrace = 0;
1186 /* Query the schema of the main database. Create a mirror schema
1187 ** in the temporary database.
1189 zSql = sqlite3_mprintf(
1190 "SELECT sql "
1191 " FROM %s.sqlite_schema WHERE type='table' AND name!='sqlite_sequence'"
1192 " AND rootpage>0"
1193 , sourceDb);
1194 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1195 if( rc!=SQLITE_OK ) goto end_of_export;
1196 sqlite3_free(zSql);
1198 zSql = sqlite3_mprintf(
1199 "SELECT sql "
1200 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE INDEX %%' "
1201 , sourceDb);
1202 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1203 if( rc!=SQLITE_OK ) goto end_of_export;
1204 sqlite3_free(zSql);
1206 zSql = sqlite3_mprintf(
1207 "SELECT sql "
1208 " FROM %s.sqlite_schema WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
1209 , sourceDb);
1210 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1211 if( rc!=SQLITE_OK ) goto end_of_export;
1212 sqlite3_free(zSql);
1214 /* Loop through the tables in the main database. For each, do
1215 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
1216 ** the contents to the temporary database.
1218 zSql = sqlite3_mprintf(
1219 "SELECT 'INSERT INTO %s.' || quote(name) "
1220 "|| ' SELECT * FROM %s.' || quote(name) || ';'"
1221 "FROM %s.sqlite_schema "
1222 "WHERE type = 'table' AND name!='sqlite_sequence' "
1223 " AND rootpage>0"
1224 , targetDb, sourceDb, sourceDb);
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 over the contents of the sequence table
1231 zSql = sqlite3_mprintf(
1232 "SELECT 'INSERT INTO %s.' || quote(name) "
1233 "|| ' SELECT * FROM %s.' || quote(name) || ';' "
1234 "FROM %s.sqlite_schema WHERE name=='sqlite_sequence';"
1235 , targetDb, sourceDb, targetDb);
1236 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1237 if( rc!=SQLITE_OK ) goto end_of_export;
1238 sqlite3_free(zSql);
1240 /* Copy the triggers, views, and virtual tables from the main database
1241 ** over to the temporary database. None of these objects has any
1242 ** associated storage, so all we have to do is copy their entries
1243 ** from the SQLITE_MASTER table.
1245 zSql = sqlite3_mprintf(
1246 "INSERT INTO %s.sqlite_schema "
1247 " SELECT type, name, tbl_name, rootpage, sql"
1248 " FROM %s.sqlite_schema"
1249 " WHERE type='view' OR type='trigger'"
1250 " OR (type='table' AND rootpage=0)"
1251 , targetDb, sourceDb);
1252 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
1253 if( rc!=SQLITE_OK ) goto end_of_export;
1254 sqlite3_free(zSql);
1256 zSql = NULL;
1257 end_of_export:
1258 db->init.iDb = 0;
1259 db->flags = saved_flags;
1260 db->mDbFlags = saved_mDbFlags;
1261 db->nChange = saved_nChange;
1262 db->nTotalChange = saved_nTotalChange;
1263 db->mTrace = saved_mTrace;
1265 if(zSql) sqlite3_free(zSql);
1267 if(rc) {
1268 if(pzErrMsg != NULL) {
1269 sqlite3_result_error(context, pzErrMsg, -1);
1270 sqlite3DbFree(db, pzErrMsg);
1271 } else {
1272 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
1276 #endif
1277 /* END SQLCIPHER */