Merge branch 'prerelease'
[sqlcipher.git] / src / crypto.c
blob6ba85ae414fa5a719b2e5d45fab1035baa6de428
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_LICENSE
39 #include "sqlcipher-license.h"
40 #endif
42 /* Generate code to return a string value */
43 static void codec_vdbe_return_string(Parse *pParse, const char *zLabel, const char *value, int value_type){
44 Vdbe *v = sqlite3GetVdbe(pParse);
45 sqlite3VdbeSetNumCols(v, 1);
46 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
47 sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, value_type);
48 sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
51 static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) {
52 int rc, page_sz, reserve_sz;
54 page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
55 reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx);
57 CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz);
59 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entering database mutex %p\n", db->mutex);
60 sqlite3_mutex_enter(db->mutex);
61 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entered database mutex %p\n", db->mutex);
62 db->nextPagesize = page_sz;
64 /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else
65 sqliteBtreeSetPageSize will block the change */
66 pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
67 rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0);
69 CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize returned %d\n", rc);
71 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: leaving database mutex %p\n", db->mutex);
72 sqlite3_mutex_leave(db->mutex);
73 CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: left database mutex %p\n", db->mutex);
75 return rc;
78 static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
79 struct Db *pDb = &db->aDb[nDb];
80 CODEC_TRACE("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char *)zKey, nKey, for_ctx);
81 if(pDb->pBt) {
82 codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
84 if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
86 return SQLITE_ERROR;
89 int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
90 struct Db *pDb = &db->aDb[iDb];
91 codec_ctx *ctx = NULL;
92 int rc;
94 if(pDb->pBt) {
95 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
98 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);
100 #ifdef SQLCIPHER_LICENSE
101 if( sqlite3StrICmp(zLeft, "cipher_license")==0 && zRight ){
102 char *license_result = sqlite3_mprintf("%d", sqlcipher_license_key(zRight));
103 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
104 } else
105 if( sqlite3StrICmp(zLeft, "cipher_license")==0 && !zRight ){
106 if(ctx) {
107 char *license_result = sqlite3_mprintf("%d", ctx
108 ? sqlcipher_license_key_status(ctx)
109 : SQLITE_ERROR);
110 codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC);
112 } else
113 #endif
114 if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
115 if(ctx) {
116 char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
117 codec_vdbe_return_string(pParse, "cipher_fips_status", fips_mode_status, P4_DYNAMIC);
119 } else
120 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
121 if(ctx) {
122 sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
124 } else
125 if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
126 if(ctx){
127 char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
128 codec_vdbe_return_string(pParse, "cipher_store_pass", store_pass_value, P4_DYNAMIC);
131 if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
132 char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
133 codec_vdbe_return_string(pParse, "cipher_profile", profile_status, P4_DYNAMIC);
134 } else
135 if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
136 if(ctx) {
137 char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
138 codec_vdbe_return_string(pParse, "cipher_add_random", add_random_status, P4_DYNAMIC);
140 } else
141 if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
142 if(ctx){
143 char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
144 codec_vdbe_return_string(pParse, "cipher_migrate", migrate_status, P4_DYNAMIC);
146 } else
147 if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
148 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider",
149 sqlcipher_codec_get_cipher_provider(ctx), P4_TRANSIENT);
151 } else
152 if( sqlite3StrICmp(zLeft, "cipher_provider_version")==0 && !zRight){
153 if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider_version",
154 sqlcipher_codec_get_provider_version(ctx), P4_TRANSIENT);
156 } else
157 if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
158 #ifdef CIPHER_VERSION_QUALIFIER
159 char *version = sqlite3_mprintf("%s %s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_QUALIFIER), CIPHER_XSTR(CIPHER_VERSION_BUILD));
160 #else
161 char *version = sqlite3_mprintf("%s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_BUILD));
162 #endif
163 codec_vdbe_return_string(pParse, "cipher_version", version, P4_DYNAMIC);
164 }else
165 if( sqlite3StrICmp(zLeft, "cipher")==0 ){
166 if(ctx) {
167 if( zRight ) {
168 const char* message = "PRAGMA cipher is no longer supported.";
169 codec_vdbe_return_string(pParse, "cipher", message, P4_TRANSIENT);
170 sqlite3_log(SQLITE_WARNING, message);
171 }else {
172 codec_vdbe_return_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx), P4_TRANSIENT);
175 }else
176 if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
177 const char* message = "PRAGMA rekey_cipher is no longer supported.";
178 codec_vdbe_return_string(pParse, "rekey_cipher", message, P4_TRANSIENT);
179 sqlite3_log(SQLITE_WARNING, message);
180 }else
181 if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
182 if( zRight ) {
183 sqlcipher_set_default_kdf_iter(atoi(zRight)); /* change default KDF iterations */
184 } else {
185 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
186 codec_vdbe_return_string(pParse, "cipher_default_kdf_iter", kdf_iter, P4_DYNAMIC);
188 }else
189 if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
190 if(ctx) {
191 if( zRight ) {
192 sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
193 } else {
194 char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx));
195 codec_vdbe_return_string(pParse, "kdf_iter", kdf_iter, P4_DYNAMIC);
198 }else
199 if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
200 if(ctx) {
201 if( zRight ) {
202 char *deprecation = "PRAGMA fast_kdf_iter is deprecated, please remove from use";
203 sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */
204 codec_vdbe_return_string(pParse, "fast_kdf_iter", deprecation, P4_TRANSIENT);
205 sqlite3_log(SQLITE_WARNING, deprecation);
206 } else {
207 char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx));
208 codec_vdbe_return_string(pParse, "fast_kdf_iter", fast_kdf_iter, P4_DYNAMIC);
211 }else
212 if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
213 const char* message = "PRAGMA rekey_kdf_iter is no longer supported.";
214 codec_vdbe_return_string(pParse, "rekey_kdf_iter", message, P4_TRANSIENT);
215 sqlite3_log(SQLITE_WARNING, message);
216 }else
217 if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
218 if(ctx) {
219 if( zRight ) {
220 int size = atoi(zRight);
221 rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
222 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
223 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
224 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
225 } else {
226 char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
227 codec_vdbe_return_string(pParse, "cipher_page_size", page_size, P4_DYNAMIC);
230 }else
231 if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
232 if( zRight ) {
233 sqlcipher_set_default_pagesize(atoi(zRight));
234 } else {
235 char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
236 codec_vdbe_return_string(pParse, "cipher_default_page_size", default_page_size, P4_DYNAMIC);
238 }else
239 if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
240 if( zRight ) {
241 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
242 } else {
243 char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
244 codec_vdbe_return_string(pParse, "cipher_default_use_hmac", default_use_hmac, P4_DYNAMIC);
246 }else
247 if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
248 if(ctx) {
249 if( zRight ) {
250 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
251 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
252 /* since the use of hmac has changed, the page size may also change */
253 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
254 if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
255 } else {
256 char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx));
257 codec_vdbe_return_string(pParse, "cipher_use_hmac", hmac_flag, P4_DYNAMIC);
260 }else
261 if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
262 if(ctx) {
263 if(zRight) {
264 char *deprecation = "PRAGMA cipher_hmac_pgno is deprecated, please remove from use";
265 /* clear both pgno endian flags */
266 if(sqlite3StrICmp(zRight, "le") == 0) {
267 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
268 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
269 } else if(sqlite3StrICmp(zRight, "be") == 0) {
270 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
271 sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
272 } else if(sqlite3StrICmp(zRight, "native") == 0) {
273 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
274 sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
276 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", deprecation, P4_TRANSIENT);
277 sqlite3_log(SQLITE_WARNING, deprecation);
279 } else {
280 if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO)) {
281 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "le", P4_TRANSIENT);
282 } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO)) {
283 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "be", P4_TRANSIENT);
284 } else {
285 codec_vdbe_return_string(pParse, "cipher_hmac_pgno", "native", P4_TRANSIENT);
289 }else
290 if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
291 if(ctx) {
292 if(zRight) {
293 char *deprecation = "PRAGMA cipher_hmac_salt_mask is deprecated, please remove from use";
294 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
295 unsigned char mask = 0;
296 const unsigned char *hex = (const unsigned char *)zRight+2;
297 cipher_hex2bin(hex,2,&mask);
298 sqlcipher_set_hmac_salt_mask(mask);
300 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", deprecation, P4_TRANSIENT);
301 sqlite3_log(SQLITE_WARNING, deprecation);
302 } else {
303 char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
304 codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask, P4_DYNAMIC);
307 }else
308 if( sqlite3StrICmp(zLeft,"cipher_plaintext_header_size")==0 ){
309 if(ctx) {
310 if( zRight ) {
311 int size = atoi(zRight);
312 if((rc = sqlcipher_codec_ctx_set_plaintext_header_size(ctx, size)) != SQLITE_OK)
313 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
314 } else {
315 char *size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
316 codec_vdbe_return_string(pParse, "cipher_plaintext_header_size", size, P4_DYNAMIC);
319 }else
320 if( sqlite3StrICmp(zLeft,"cipher_default_plaintext_header_size")==0 ){
321 if( zRight ) {
322 sqlcipher_set_default_plaintext_header_size(atoi(zRight));
323 } else {
324 char *size = sqlite3_mprintf("%d", sqlcipher_get_default_plaintext_header_size());
325 codec_vdbe_return_string(pParse, "cipher_default_plaintext_header_size", size, P4_DYNAMIC);
326 sqlite3_free(size);
328 }else
329 if( sqlite3StrICmp(zLeft,"cipher_salt")==0 ){
330 if(ctx) {
331 if(zRight) {
332 if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == (FILE_HEADER_SZ*2)+3) {
333 unsigned char *salt = (unsigned char*) sqlite3_malloc(FILE_HEADER_SZ);
334 const unsigned char *hex = (const unsigned char *)zRight+2;
335 cipher_hex2bin(hex,FILE_HEADER_SZ*2,salt);
336 sqlcipher_codec_ctx_set_kdf_salt(ctx, salt, FILE_HEADER_SZ);
337 sqlite3_free(salt);
339 } else {
340 void *salt;
341 char *hexsalt = (char*) sqlite3_malloc((FILE_HEADER_SZ*2)+1);
342 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &salt)) == SQLITE_OK) {
343 cipher_bin2hex(salt, FILE_HEADER_SZ, hexsalt);
344 codec_vdbe_return_string(pParse, "cipher_salt", hexsalt, P4_DYNAMIC);
345 } else {
346 sqlite3_free(hexsalt);
347 sqlcipher_codec_ctx_set_error(ctx, rc);
351 }else
352 if( sqlite3StrICmp(zLeft,"cipher_hmac_algorithm")==0 ){
353 if(ctx) {
354 if(zRight) {
355 rc = SQLITE_ERROR;
356 if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
357 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
358 } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
359 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA256);
360 } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
361 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
363 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
364 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
365 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
366 } else {
367 int algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
368 if(algorithm == SQLCIPHER_HMAC_SHA1) {
369 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
370 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
371 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
372 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
373 codec_vdbe_return_string(pParse, "cipher_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
377 }else
378 if( sqlite3StrICmp(zLeft,"cipher_default_hmac_algorithm")==0 ){
379 if(zRight) {
380 rc = SQLITE_ERROR;
381 if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) {
382 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
383 } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) {
384 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA256);
385 } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
386 rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
388 } else {
389 int algorithm = sqlcipher_get_default_hmac_algorithm();
390 if(algorithm == SQLCIPHER_HMAC_SHA1) {
391 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA1_LABEL, P4_TRANSIENT);
392 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
393 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA256_LABEL, P4_TRANSIENT);
394 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
395 codec_vdbe_return_string(pParse, "cipher_default_hmac_algorithm", SQLCIPHER_HMAC_SHA512_LABEL, P4_TRANSIENT);
398 }else
399 if( sqlite3StrICmp(zLeft,"cipher_kdf_algorithm")==0 ){
400 if(ctx) {
401 if(zRight) {
402 rc = SQLITE_ERROR;
403 if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
404 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
405 } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
406 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA256);
407 } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
408 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
410 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
411 } else {
412 int algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
413 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
414 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
415 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
416 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
417 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
418 codec_vdbe_return_string(pParse, "cipher_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
422 }else
423 if( sqlite3StrICmp(zLeft,"cipher_default_kdf_algorithm")==0 ){
424 if(zRight) {
425 rc = SQLITE_ERROR;
426 if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) {
427 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
428 } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) {
429 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA256);
430 } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
431 rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
433 } else {
434 int algorithm = sqlcipher_get_default_kdf_algorithm();
435 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
436 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL, P4_TRANSIENT);
437 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
438 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL, P4_TRANSIENT);
439 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
440 codec_vdbe_return_string(pParse, "cipher_default_kdf_algorithm", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL, P4_TRANSIENT);
443 }else
444 if( sqlite3StrICmp(zLeft,"cipher_compatibility")==0 ){
445 if(ctx) {
446 if(zRight) {
447 int version = atoi(zRight);
449 switch(version) {
450 case 1:
451 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
452 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
453 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
454 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
455 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
456 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
457 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
458 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
459 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 0);
460 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
461 break;
463 case 2:
464 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
465 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
466 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
467 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
468 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
469 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
470 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
471 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
472 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
473 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
474 break;
476 case 3:
477 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
478 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
479 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
480 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
481 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
482 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
483 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 64000);
484 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
485 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
486 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
487 break;
489 default:
490 rc = sqlcipher_codec_ctx_set_pagesize(ctx, 4096);
491 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
492 rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
493 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
494 rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
495 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
496 rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 256000);
497 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
498 rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
499 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
500 break;
503 rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
504 if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
507 }else
508 if( sqlite3StrICmp(zLeft,"cipher_default_compatibility")==0 ){
509 if(zRight) {
510 int version = atoi(zRight);
511 switch(version) {
512 case 1:
513 sqlcipher_set_default_pagesize(1024);
514 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
515 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
516 sqlcipher_set_default_kdf_iter(4000);
517 sqlcipher_set_default_use_hmac(0);
518 break;
520 case 2:
521 sqlcipher_set_default_pagesize(1024);
522 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
523 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
524 sqlcipher_set_default_kdf_iter(4000);
525 sqlcipher_set_default_use_hmac(1);
526 break;
528 case 3:
529 sqlcipher_set_default_pagesize(1024);
530 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
531 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
532 sqlcipher_set_default_kdf_iter(64000);
533 sqlcipher_set_default_use_hmac(1);
534 break;
536 default:
537 sqlcipher_set_default_pagesize(4096);
538 sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
539 sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
540 sqlcipher_set_default_kdf_iter(256000);
541 sqlcipher_set_default_use_hmac(1);
542 break;
545 }else
546 if( sqlite3StrICmp(zLeft,"cipher_memory_security")==0 ){
547 if( zRight ) {
548 sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1));
549 } else {
550 char *on = sqlite3_mprintf("%d", sqlcipher_get_mem_security());
551 codec_vdbe_return_string(pParse, "cipher_memory_security", on, P4_DYNAMIC);
553 }else
554 if( sqlite3StrICmp(zLeft,"cipher_settings")==0 ){
555 if(ctx) {
556 int algorithm;
557 char *pragma;
559 pragma = sqlite3_mprintf("PRAGMA kdf_iter = %d;", sqlcipher_codec_ctx_get_kdf_iter(ctx));
560 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
562 pragma = sqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx));
563 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
565 pragma = sqlite3_mprintf("PRAGMA cipher_use_hmac = %d;", sqlcipher_codec_ctx_get_use_hmac(ctx));
566 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
568 pragma = sqlite3_mprintf("PRAGMA cipher_plaintext_header_size = %d;", sqlcipher_codec_ctx_get_plaintext_header_size(ctx));
569 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
571 algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx);
572 pragma = NULL;
573 if(algorithm == SQLCIPHER_HMAC_SHA1) {
574 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
575 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
576 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
577 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
578 pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
580 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
582 algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx);
583 pragma = NULL;
584 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
585 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
586 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
587 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
588 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
589 pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
591 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
594 }else
595 if( sqlite3StrICmp(zLeft,"cipher_default_settings")==0 ){
596 int algorithm;
597 char *pragma;
599 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_iter = %d;", sqlcipher_get_default_kdf_iter());
600 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
602 pragma = sqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize());
603 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
605 pragma = sqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac());
606 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
608 pragma = sqlite3_mprintf("PRAGMA cipher_default_plaintext_header_size = %d;", sqlcipher_get_default_plaintext_header_size());
609 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
611 algorithm = sqlcipher_get_default_hmac_algorithm();
612 pragma = NULL;
613 if(algorithm == SQLCIPHER_HMAC_SHA1) {
614 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL);
615 } else if(algorithm == SQLCIPHER_HMAC_SHA256) {
616 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL);
617 } else if(algorithm == SQLCIPHER_HMAC_SHA512) {
618 pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL);
620 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
622 algorithm = sqlcipher_get_default_kdf_algorithm();
623 pragma = NULL;
624 if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
625 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL);
626 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) {
627 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL);
628 } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) {
629 pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL);
631 codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC);
632 }else {
633 return 0;
635 return 1;
638 /* these constants are used internally within SQLite's pager.c to differentiate between
639 operations on the main database or journal pages. This is important in the context
640 of a rekey operations, where the journal must be written using the original key
641 material (to allow a transactional rollback), while the new database pages are being
642 written with the new key material*/
643 #define CODEC_READ_OP 3
644 #define CODEC_WRITE_OP 6
645 #define CODEC_JOURNAL_OP 7
648 * sqlite3Codec can be called in multiple modes.
649 * encrypt mode - expected to return a pointer to the
650 * encrypted data without altering pData.
651 * decrypt mode - expected to return a pointer to pData, with
652 * the data decrypted in the input buffer
654 static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
655 codec_ctx *ctx = (codec_ctx *) iCtx;
656 int offset = 0, rc = 0;
657 int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx);
658 unsigned char *pData = (unsigned char *) data;
659 void *buffer = sqlcipher_codec_ctx_get_data(ctx);
660 int plaintext_header_sz = sqlcipher_codec_ctx_get_plaintext_header_size(ctx);
661 int cctx = CIPHER_READ_CTX;
663 CODEC_TRACE("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz);
665 #ifdef SQLCIPHER_LICENSE
666 if(sqlcipher_license_check(ctx) != SQLITE_OK) return NULL;
667 #endif
669 /* call to derive keys if not present yet */
670 if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) {
671 sqlcipher_codec_ctx_set_error(ctx, rc);
672 return NULL;
675 if(pgno == 1) /* adjust starting pointers in data page for header offset on first page*/
676 offset = plaintext_header_sz ? plaintext_header_sz : FILE_HEADER_SZ;
679 CODEC_TRACE("sqlite3Codec: switch mode=%d offset=%d\n", mode, offset);
680 switch(mode) {
681 case CODEC_READ_OP: /* decrypt */
682 if(pgno == 1) /* copy initial part of file header or SQLite magic to buffer */
683 memcpy(buffer, plaintext_header_sz ? pData : (void *) SQLITE_FILE_HEADER, offset);
685 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_DECRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
686 if(rc != SQLITE_OK) { /* clear results of failed cipher operation and set error */
687 sqlcipher_memset((unsigned char*) buffer+offset, 0, page_sz-offset);
688 sqlcipher_codec_ctx_set_error(ctx, rc);
690 memcpy(pData, buffer, page_sz); /* copy buffer data back to pData and return */
691 return pData;
692 break;
694 case CODEC_WRITE_OP: /* encrypt database page, operate on write context and fall through to case 7, so the write context is used*/
695 cctx = CIPHER_WRITE_CTX;
697 case CODEC_JOURNAL_OP: /* encrypt journal page, operate on read context use to get the original page data from the database */
698 if(pgno == 1) { /* copy initial part of file header or salt to buffer */
699 void *kdf_salt = NULL;
700 /* retrieve the kdf salt */
701 if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &kdf_salt)) != SQLITE_OK) {
702 sqlcipher_codec_ctx_set_error(ctx, rc);
703 return NULL;
705 memcpy(buffer, plaintext_header_sz ? pData : kdf_salt, offset);
707 rc = sqlcipher_page_cipher(ctx, cctx, pgno, CIPHER_ENCRYPT, page_sz - offset, pData + offset, (unsigned char*)buffer + offset);
708 if(rc != SQLITE_OK) { /* clear results of failed cipher operation and set error */
709 sqlcipher_memset((unsigned char*)buffer+offset, 0, page_sz-offset);
710 sqlcipher_codec_ctx_set_error(ctx, rc);
712 return buffer; /* return persistent buffer data, pData remains intact */
713 break;
715 default:
716 sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); /* unsupported mode, set error */
717 return pData;
718 break;
722 static void sqlite3FreeCodecArg(void *pCodecArg) {
723 codec_ctx *ctx = (codec_ctx *) pCodecArg;
724 if(pCodecArg == NULL) return;
725 sqlcipher_codec_ctx_free(&ctx); /* wipe and free allocated memory for the context */
726 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
729 int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
730 struct Db *pDb = &db->aDb[nDb];
732 CODEC_TRACE("sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%s, nKey=%d\n", db, nDb, (char *)zKey, nKey);
735 if(nKey && zKey && pDb->pBt) {
736 int rc;
737 Pager *pPager = pDb->pBt->pBt->pPager;
738 sqlite3_file *fd;
739 codec_ctx *ctx;
741 /* check if the sqlite3_file is open, and if not force handle to NULL */
742 if((fd = sqlite3PagerFile(pPager))->pMethods == 0) fd = NULL;
744 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_activate()\n");
745 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
747 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entering database mutex %p\n", db->mutex);
748 sqlite3_mutex_enter(db->mutex);
749 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entered database mutex %p\n", db->mutex);
751 #ifdef SQLCIPHER_LICENSE
752 if((rc = sqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) {
753 sqlite3_mutex_leave(db->mutex);
754 return rc;
756 #endif
758 /* point the internal codec argument against the contet to be prepared */
759 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()\n");
760 rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, zKey, nKey);
762 if(rc != SQLITE_OK) {
763 /* initialization failed, do not attach potentially corrupted context */
764 CODEC_TRACE("sqlite3CodecAttach: context initialization failed with rc=%d\n", rc);
765 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)\n", db->mutex, rc);
766 sqlite3_mutex_leave(db->mutex);
767 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p (early return on rc=%d)\n", db->mutex, rc);
768 return rc;
771 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3PagerSetCodec()\n");
772 sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);
774 CODEC_TRACE("sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()\n");
775 codec_set_btree_to_codec_pagesize(db, pDb, ctx);
777 /* force secure delete. This has the benefit of wiping internal data when deleted
778 and also ensures that all pages are written to disk (i.e. not skipped by
779 sqlite3PagerDontWrite optimizations) */
780 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()\n");
781 sqlite3BtreeSecureDelete(pDb->pBt, 1);
783 /* if fd is null, then this is an in-memory database and
784 we dont' want to overwrite the AutoVacuum settings
785 if not null, then set to the default */
786 if(fd != NULL) {
787 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()\n");
788 sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
790 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p\n", db->mutex);
791 sqlite3_mutex_leave(db->mutex);
792 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p\n", db->mutex);
794 return SQLITE_OK;
797 int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
798 int db_index;
799 if(zDb == NULL){
800 return 0;
802 for(db_index = 0; db_index < db->nDb; db_index++) {
803 struct Db *pDb = &db->aDb[db_index];
804 if(strcmp(pDb->zDbSName, zDb) == 0) {
805 return db_index;
808 return 0;
811 void sqlite3_activate_see(const char* in) {
812 /* do nothing, security enhancements are always active */
815 int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
816 CODEC_TRACE("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey);
817 return sqlite3_key_v2(db, "main", pKey, nKey);
820 int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
821 CODEC_TRACE("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey);
822 /* attach key if db and pKey are not null and nKey is > 0 */
823 if(db && pKey && nKey) {
824 int db_index = sqlcipher_find_db_index(db, zDb);
825 return sqlite3CodecAttach(db, db_index, pKey, nKey);
827 return SQLITE_ERROR;
830 int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
831 CODEC_TRACE("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey);
832 return sqlite3_rekey_v2(db, "main", pKey, nKey);
835 /* sqlite3_rekey_v2
836 ** Given a database, this will reencrypt the database using a new key.
837 ** There is only one possible modes of operation - to encrypt a database
838 ** that is already encrpyted. If the database is not already encrypted
839 ** this should do nothing
840 ** The proposed logic for this function follows:
841 ** 1. Determine if the database is already encryptped
842 ** 2. If there is NOT already a key present do nothing
843 ** 3. If there is a key present, re-encrypt the database with the new key
845 int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
846 CODEC_TRACE("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey);
847 if(db && pKey && nKey) {
848 int db_index = sqlcipher_find_db_index(db, zDb);
849 struct Db *pDb = &db->aDb[db_index];
850 CODEC_TRACE("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index);
851 if(pDb->pBt) {
852 codec_ctx *ctx;
853 int rc, page_count;
854 Pgno pgno;
855 PgHdr *page;
856 Pager *pPager = pDb->pBt->pBt->pPager;
858 ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
860 if(ctx == NULL) {
861 /* there was no codec attached to this database, so this should do nothing! */
862 CODEC_TRACE("sqlite3_rekey_v2: no codec attached to db, exiting\n");
863 return SQLITE_OK;
866 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entering database mutex %p\n", db->mutex);
867 sqlite3_mutex_enter(db->mutex);
868 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entered database mutex %p\n", db->mutex);
870 codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
872 /* do stuff here to rewrite the database
873 ** 1. Create a transaction on the database
874 ** 2. Iterate through each page, reading it and then writing it.
875 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
876 ** note: don't deallocate rekey since it may be used in a subsequent iteration
878 rc = sqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */
879 sqlite3PagerPagecount(pPager, &page_count);
880 for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */
881 if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
882 rc = sqlite3PagerGet(pPager, pgno, &page, 0);
883 if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
884 rc = sqlite3PagerWrite(page);
885 if(rc == SQLITE_OK) {
886 sqlite3PagerUnref(page);
887 } else {
888 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno);
890 } else {
891 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno);
896 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
897 if(rc == SQLITE_OK) {
898 CODEC_TRACE("sqlite3_rekey_v2: committing\n");
899 rc = sqlite3BtreeCommit(pDb->pBt);
900 sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
901 } else {
902 CODEC_TRACE("sqlite3_rekey_v2: rollback\n");
903 sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
906 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: leaving database mutex %p\n", db->mutex);
907 sqlite3_mutex_leave(db->mutex);
908 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: left database mutex %p\n", db->mutex);
910 return SQLITE_OK;
912 return SQLITE_ERROR;
915 void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
916 struct Db *pDb = &db->aDb[nDb];
917 CODEC_TRACE("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb);
918 if( pDb->pBt ) {
919 codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager);
921 if(ctx) {
922 /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass
923 is set or keyspec has not yet been derived, in which case pass
924 back the password key material */
925 sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
926 if(sqlcipher_codec_get_store_pass(ctx) == 1 || *zKey == NULL) {
927 sqlcipher_codec_get_pass(ctx, zKey, nKey);
929 } else {
930 *zKey = NULL;
931 *nKey = 0;
936 #ifndef OMIT_EXPORT
939 * Implementation of an "export" function that allows a caller
940 * to duplicate the main database to an attached database. This is intended
941 * as a conveneince for users who need to:
943 * 1. migrate from an non-encrypted database to an encrypted database
944 * 2. move from an encrypted database to a non-encrypted database
945 * 3. convert beween the various flavors of encrypted databases.
947 * This implementation is based heavily on the procedure and code used
948 * in vacuum.c, but is exposed as a function that allows export to any
949 * named attached database.
953 ** Finalize a prepared statement. If there was an error, store the
954 ** text of the error message in *pzErrMsg. Return the result code.
956 ** Based on vacuumFinalize from vacuum.c
958 static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
959 int rc;
960 rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
961 if( rc ){
962 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
964 return rc;
968 ** Execute zSql on database db. Return an error code.
970 ** Based on execSql from vacuum.c
972 static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
973 sqlite3_stmt *pStmt;
974 VVA_ONLY( int rc; )
975 if( !zSql ){
976 return SQLITE_NOMEM;
978 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
979 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
980 return sqlite3_errcode(db);
982 VVA_ONLY( rc = ) sqlite3_step(pStmt);
983 assert( rc!=SQLITE_ROW );
984 return sqlcipher_finalize(db, pStmt, pzErrMsg);
988 ** Execute zSql on database db. The statement returns exactly
989 ** one column. Execute this as SQL on the same database.
991 ** Based on execExecSql from vacuum.c
993 static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
994 sqlite3_stmt *pStmt;
995 int rc;
997 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
998 if( rc!=SQLITE_OK ) return rc;
1000 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1001 rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
1002 if( rc!=SQLITE_OK ){
1003 sqlcipher_finalize(db, pStmt, pzErrMsg);
1004 return rc;
1008 return sqlcipher_finalize(db, pStmt, pzErrMsg);
1012 * copy database and schema from the main database to an attached database
1014 * Based on sqlite3RunVacuum from vacuum.c
1016 void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
1017 sqlite3 *db = sqlite3_context_db_handle(context);
1018 const char* targetDb, *sourceDb;
1019 int targetDb_idx = 0;
1020 u64 saved_flags = db->flags; /* Saved value of the db->flags */
1021 u32 saved_mDbFlags = db->mDbFlags; /* Saved value of the db->mDbFlags */
1022 int saved_nChange = db->nChange; /* Saved value of db->nChange */
1023 int saved_nTotalChange = db->nTotalChange; /* Saved value of db->nTotalChange */
1024 u8 saved_mTrace = db->mTrace; /* Saved value of db->mTrace */
1025 int (*saved_xTrace)(u32,void*,void*,void*) = db->xTrace; /* Saved db->xTrace */
1026 int rc = SQLITE_OK; /* Return code from service routines */
1027 char *zSql = NULL; /* SQL statements */
1028 char *pzErrMsg = NULL;
1030 if(argc != 1 && argc != 2) {
1031 rc = SQLITE_ERROR;
1032 pzErrMsg = sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc);
1033 goto end_of_export;
1036 targetDb = (const char*) sqlite3_value_text(argv[0]);
1037 sourceDb = (argc == 2) ? (char *) sqlite3_value_text(argv[1]) : "main";
1039 /* if the name of the target is not main, but the index returned is zero
1040 there is a mismatch and we should not proceed */
1041 targetDb_idx = sqlcipher_find_db_index(db, targetDb);
1042 if(targetDb_idx == 0 && sqlite3StrICmp("main", targetDb) != 0) {
1043 rc = SQLITE_ERROR;
1044 pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb);
1045 goto end_of_export;
1047 db->init.iDb = targetDb_idx;
1049 db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
1050 db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
1051 db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows);
1052 db->xTrace = 0;
1053 db->mTrace = 0;
1055 /* Query the schema of the main database. Create a mirror schema
1056 ** in the temporary database.
1058 zSql = sqlite3_mprintf(
1059 "SELECT sql "
1060 " FROM %s.sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
1061 " AND rootpage>0"
1062 , sourceDb);
1063 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1064 if( rc!=SQLITE_OK ) goto end_of_export;
1065 sqlite3_free(zSql);
1067 zSql = sqlite3_mprintf(
1068 "SELECT sql "
1069 " FROM %s.sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
1070 , sourceDb);
1071 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1072 if( rc!=SQLITE_OK ) goto end_of_export;
1073 sqlite3_free(zSql);
1075 zSql = sqlite3_mprintf(
1076 "SELECT sql "
1077 " FROM %s.sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
1078 , sourceDb);
1079 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1080 if( rc!=SQLITE_OK ) goto end_of_export;
1081 sqlite3_free(zSql);
1083 /* Loop through the tables in the main database. For each, do
1084 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
1085 ** the contents to the temporary database.
1087 zSql = sqlite3_mprintf(
1088 "SELECT 'INSERT INTO %s.' || quote(name) "
1089 "|| ' SELECT * FROM %s.' || quote(name) || ';'"
1090 "FROM %s.sqlite_master "
1091 "WHERE type = 'table' AND name!='sqlite_sequence' "
1092 " AND rootpage>0"
1093 , targetDb, sourceDb, sourceDb);
1094 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1095 if( rc!=SQLITE_OK ) goto end_of_export;
1096 sqlite3_free(zSql);
1098 /* Copy over the contents of the sequence table
1100 zSql = sqlite3_mprintf(
1101 "SELECT 'INSERT INTO %s.' || quote(name) "
1102 "|| ' SELECT * FROM %s.' || quote(name) || ';' "
1103 "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
1104 , targetDb, sourceDb, targetDb);
1105 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql);
1106 if( rc!=SQLITE_OK ) goto end_of_export;
1107 sqlite3_free(zSql);
1109 /* Copy the triggers, views, and virtual tables from the main database
1110 ** over to the temporary database. None of these objects has any
1111 ** associated storage, so all we have to do is copy their entries
1112 ** from the SQLITE_MASTER table.
1114 zSql = sqlite3_mprintf(
1115 "INSERT INTO %s.sqlite_master "
1116 " SELECT type, name, tbl_name, rootpage, sql"
1117 " FROM %s.sqlite_master"
1118 " WHERE type='view' OR type='trigger'"
1119 " OR (type='table' AND rootpage=0)"
1120 , targetDb, sourceDb);
1121 rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql);
1122 if( rc!=SQLITE_OK ) goto end_of_export;
1123 sqlite3_free(zSql);
1125 zSql = NULL;
1126 end_of_export:
1127 db->init.iDb = 0;
1128 db->flags = saved_flags;
1129 db->mDbFlags = saved_mDbFlags;
1130 db->nChange = saved_nChange;
1131 db->nTotalChange = saved_nTotalChange;
1132 db->xTrace = saved_xTrace;
1133 db->mTrace = saved_mTrace;
1135 if(zSql) sqlite3_free(zSql);
1137 if(rc) {
1138 if(pzErrMsg != NULL) {
1139 sqlite3_result_error(context, pzErrMsg, -1);
1140 sqlite3DbFree(db, pzErrMsg);
1141 } else {
1142 sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
1147 #endif
1149 /* END SQLCIPHER */
1150 #endif