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