3 ** http://sqlcipher.net
5 ** Copyright (c) 2008 - 2013, ZETETIC LLC
6 ** All rights reserved.
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.
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.
32 #ifdef SQLITE_HAS_CODEC
35 #include "sqlcipher.h"
39 #include "sqlcipher_ext.h"
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
);
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
);
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
);
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
;
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
);
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
);
105 if( sqlite3StrICmp(zLeft
, "cipher_license")==0 && !zRight
){
107 char *license_result
= sqlite3_mprintf("%d", ctx
108 ? sqlcipher_license_key_status(ctx
->provider
)
110 codec_vdbe_return_string(pParse
, "cipher_license", license_result
, P4_DYNAMIC
);
114 if( sqlite3StrICmp(zLeft
, "cipher_fips_status")== 0 && !zRight
){
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
);
120 if( sqlite3StrICmp(zLeft
, "cipher_store_pass")==0 && zRight
) {
122 sqlcipher_codec_set_store_pass(ctx
, sqlite3GetBoolean(zRight
, 1));
125 if( sqlite3StrICmp(zLeft
, "cipher_store_pass")==0 && !zRight
) {
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
);
135 if( sqlite3StrICmp(zLeft
, "cipher_add_random")==0 && zRight
){
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
);
141 if( sqlite3StrICmp(zLeft
, "cipher_migrate")==0 && !zRight
){
143 char *migrate_status
= sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx
));
144 codec_vdbe_return_string(pParse
, "cipher_migrate", migrate_status
, P4_DYNAMIC
);
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
);
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
);
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
));
161 char *version
= sqlite3_mprintf("%s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER
), CIPHER_XSTR(CIPHER_VERSION_BUILD
));
163 codec_vdbe_return_string(pParse
, "cipher_version", version
, P4_DYNAMIC
);
165 if( sqlite3StrICmp(zLeft
, "cipher")==0 ){
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
);
172 codec_vdbe_return_string(pParse
, "cipher", sqlcipher_codec_ctx_get_cipher(ctx
), P4_TRANSIENT
);
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
);
181 if( sqlite3StrICmp(zLeft
,"cipher_default_kdf_iter")==0 ){
183 sqlcipher_set_default_kdf_iter(atoi(zRight
)); /* change default KDF iterations */
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
);
189 if( sqlite3StrICmp(zLeft
, "kdf_iter")==0 ){
192 sqlcipher_codec_ctx_set_kdf_iter(ctx
, atoi(zRight
)); /* change of RW PBKDF2 iteration */
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
);
199 if( sqlite3StrICmp(zLeft
, "fast_kdf_iter")==0){
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
);
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
);
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
);
217 if( sqlite3StrICmp(zLeft
,"cipher_page_size")==0 ){
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
);
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
);
231 if( sqlite3StrICmp(zLeft
,"cipher_default_page_size")==0 ){
233 sqlcipher_set_default_pagesize(atoi(zRight
));
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
);
239 if( sqlite3StrICmp(zLeft
,"cipher_default_use_hmac")==0 ){
241 sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight
,1));
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
);
247 if( sqlite3StrICmp(zLeft
,"cipher_use_hmac")==0 ){
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
);
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
);
261 if( sqlite3StrICmp(zLeft
,"cipher_hmac_pgno")==0 ){
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
);
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
);
285 codec_vdbe_return_string(pParse
, "cipher_hmac_pgno", "native", P4_TRANSIENT
);
290 if( sqlite3StrICmp(zLeft
,"cipher_hmac_salt_mask")==0 ){
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
);
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
);
308 if( sqlite3StrICmp(zLeft
,"cipher_plaintext_header_size")==0 ){
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
);
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
);
320 if( sqlite3StrICmp(zLeft
,"cipher_default_plaintext_header_size")==0 ){
322 sqlcipher_set_default_plaintext_header_size(atoi(zRight
));
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
);
329 if( sqlite3StrICmp(zLeft
,"cipher_salt")==0 ){
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
);
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
);
346 sqlite3_free(hexsalt
);
347 sqlcipher_codec_ctx_set_error(ctx
, rc
);
352 if( sqlite3StrICmp(zLeft
,"cipher_hmac_algorithm")==0 ){
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
);
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
);
378 if( sqlite3StrICmp(zLeft
,"cipher_default_hmac_algorithm")==0 ){
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
);
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
);
399 if( sqlite3StrICmp(zLeft
,"cipher_kdf_algorithm")==0 ){
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
);
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
);
423 if( sqlite3StrICmp(zLeft
,"cipher_default_kdf_algorithm")==0 ){
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
);
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
);
444 if( sqlite3StrICmp(zLeft
,"cipher_compatibility")==0 ){
447 int version
= atoi(zRight
);
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
);
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
);
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
);
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
);
503 rc
= codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
504 if (rc
!= SQLITE_OK
) sqlcipher_codec_ctx_set_error(ctx
, SQLITE_ERROR
);
508 if( sqlite3StrICmp(zLeft
,"cipher_default_compatibility")==0 ){
510 int version
= atoi(zRight
);
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);
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);
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);
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);
546 if( sqlite3StrICmp(zLeft
,"cipher_memory_security")==0 ){
548 sqlcipher_set_mem_security(sqlite3GetBoolean(zRight
,1));
550 char *on
= sqlite3_mprintf("%d", sqlcipher_get_mem_security());
551 codec_vdbe_return_string(pParse
, "cipher_memory_security", on
, P4_DYNAMIC
);
554 if( sqlite3StrICmp(zLeft
,"cipher_settings")==0 ){
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
);
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
);
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
);
595 if( sqlite3StrICmp(zLeft
,"cipher_default_settings")==0 ){
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();
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();
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
);
633 if( sqlite3StrICmp(zLeft
,"cipher_integrity_check")==0 ){
635 sqlcipher_codec_ctx_integrity_check(ctx
, pParse
, "cipher_integrity_check");
643 /* these constants are used internally within SQLite's pager.c to differentiate between
644 operations on the main database or journal pages. This is important in the context
645 of a rekey operations, where the journal must be written using the original key
646 material (to allow a transactional rollback), while the new database pages are being
647 written with the new key material*/
648 #define CODEC_READ_OP 3
649 #define CODEC_WRITE_OP 6
650 #define CODEC_JOURNAL_OP 7
653 * sqlite3Codec can be called in multiple modes.
654 * encrypt mode - expected to return a pointer to the
655 * encrypted data without altering pData.
656 * decrypt mode - expected to return a pointer to pData, with
657 * the data decrypted in the input buffer
659 static void* sqlite3Codec(void *iCtx
, void *data
, Pgno pgno
, int mode
) {
660 codec_ctx
*ctx
= (codec_ctx
*) iCtx
;
661 int offset
= 0, rc
= 0;
662 int page_sz
= sqlcipher_codec_ctx_get_pagesize(ctx
);
663 unsigned char *pData
= (unsigned char *) data
;
664 void *buffer
= sqlcipher_codec_ctx_get_data(ctx
);
665 int plaintext_header_sz
= sqlcipher_codec_ctx_get_plaintext_header_size(ctx
);
666 int cctx
= CIPHER_READ_CTX
;
668 CODEC_TRACE("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno
, mode
, page_sz
);
671 if(sqlcipher_license_check(ctx
) != SQLITE_OK
) return NULL
;
674 /* call to derive keys if not present yet */
675 if((rc
= sqlcipher_codec_key_derive(ctx
)) != SQLITE_OK
) {
676 sqlcipher_codec_ctx_set_error(ctx
, rc
);
680 if(pgno
== 1) /* adjust starting pointers in data page for header offset on first page*/
681 offset
= plaintext_header_sz
? plaintext_header_sz
: FILE_HEADER_SZ
;
684 CODEC_TRACE("sqlite3Codec: switch mode=%d offset=%d\n", mode
, offset
);
686 case CODEC_READ_OP
: /* decrypt */
687 if(pgno
== 1) /* copy initial part of file header or SQLite magic to buffer */
688 memcpy(buffer
, plaintext_header_sz
? pData
: (void *) SQLITE_FILE_HEADER
, offset
);
690 rc
= sqlcipher_page_cipher(ctx
, cctx
, pgno
, CIPHER_DECRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
691 if(rc
!= SQLITE_OK
) { /* clear results of failed cipher operation and set error */
692 sqlcipher_memset((unsigned char*) buffer
+offset
, 0, page_sz
-offset
);
693 sqlcipher_codec_ctx_set_error(ctx
, rc
);
695 memcpy(pData
, buffer
, page_sz
); /* copy buffer data back to pData and return */
699 case CODEC_WRITE_OP
: /* encrypt database page, operate on write context and fall through to case 7, so the write context is used*/
700 cctx
= CIPHER_WRITE_CTX
;
702 case CODEC_JOURNAL_OP
: /* encrypt journal page, operate on read context use to get the original page data from the database */
703 if(pgno
== 1) { /* copy initial part of file header or salt to buffer */
704 void *kdf_salt
= NULL
;
705 /* retrieve the kdf salt */
706 if((rc
= sqlcipher_codec_ctx_get_kdf_salt(ctx
, &kdf_salt
)) != SQLITE_OK
) {
707 sqlcipher_codec_ctx_set_error(ctx
, rc
);
710 memcpy(buffer
, plaintext_header_sz
? pData
: kdf_salt
, offset
);
712 rc
= sqlcipher_page_cipher(ctx
, cctx
, pgno
, CIPHER_ENCRYPT
, page_sz
- offset
, pData
+ offset
, (unsigned char*)buffer
+ offset
);
713 if(rc
!= SQLITE_OK
) { /* clear results of failed cipher operation and set error */
714 sqlcipher_memset((unsigned char*)buffer
+offset
, 0, page_sz
-offset
);
715 sqlcipher_codec_ctx_set_error(ctx
, rc
);
717 return buffer
; /* return persistent buffer data, pData remains intact */
721 sqlcipher_codec_ctx_set_error(ctx
, SQLITE_ERROR
); /* unsupported mode, set error */
727 static void sqlite3FreeCodecArg(void *pCodecArg
) {
728 codec_ctx
*ctx
= (codec_ctx
*) pCodecArg
;
729 if(pCodecArg
== NULL
) return;
730 sqlcipher_codec_ctx_free(&ctx
); /* wipe and free allocated memory for the context */
731 sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */
734 int sqlite3CodecAttach(sqlite3
* db
, int nDb
, const void *zKey
, int nKey
) {
735 struct Db
*pDb
= &db
->aDb
[nDb
];
737 CODEC_TRACE("sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%s, nKey=%d\n", db
, nDb
, (char *)zKey
, nKey
);
740 if(nKey
&& zKey
&& pDb
->pBt
) {
742 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
746 /* check if the sqlite3_file is open, and if not force handle to NULL */
747 if((fd
= sqlite3PagerFile(pPager
))->pMethods
== 0) fd
= NULL
;
749 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_activate()\n");
750 sqlcipher_activate(); /* perform internal initialization for sqlcipher */
752 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entering database mutex %p\n", db
->mutex
);
753 sqlite3_mutex_enter(db
->mutex
);
754 CODEC_TRACE_MUTEX("sqlite3CodecAttach: entered database mutex %p\n", db
->mutex
);
757 if((rc
= sqlite3_set_authorizer(db
, sqlcipher_license_authorizer
, db
)) != SQLITE_OK
) {
758 sqlite3_mutex_leave(db
->mutex
);
763 /* point the internal codec argument against the contet to be prepared */
764 CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()\n");
765 rc
= sqlcipher_codec_ctx_init(&ctx
, pDb
, pDb
->pBt
->pBt
->pPager
, zKey
, nKey
);
767 if(rc
!= SQLITE_OK
) {
768 /* initialization failed, do not attach potentially corrupted context */
769 CODEC_TRACE("sqlite3CodecAttach: context initialization failed with rc=%d\n", rc
);
770 /* force an error at the pager level, such that even the upstream caller ignores the return code
771 the pager will be in an error state and will process no further operations */
772 sqlite3pager_error(pPager
, rc
);
773 pDb
->pBt
->pBt
->db
->errCode
= rc
;
774 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)\n", db
->mutex
, rc
);
775 sqlite3_mutex_leave(db
->mutex
);
776 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p (early return on rc=%d)\n", db
->mutex
, rc
);
780 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3PagerSetCodec()\n");
781 sqlite3PagerSetCodec(sqlite3BtreePager(pDb
->pBt
), sqlite3Codec
, NULL
, sqlite3FreeCodecArg
, (void *) ctx
);
783 CODEC_TRACE("sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()\n");
784 codec_set_btree_to_codec_pagesize(db
, pDb
, ctx
);
786 /* force secure delete. This has the benefit of wiping internal data when deleted
787 and also ensures that all pages are written to disk (i.e. not skipped by
788 sqlite3PagerDontWrite optimizations) */
789 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()\n");
790 sqlite3BtreeSecureDelete(pDb
->pBt
, 1);
792 /* if fd is null, then this is an in-memory database and
793 we dont' want to overwrite the AutoVacuum settings
794 if not null, then set to the default */
796 CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()\n");
797 sqlite3BtreeSetAutoVacuum(pDb
->pBt
, SQLITE_DEFAULT_AUTOVACUUM
);
799 CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p\n", db
->mutex
);
800 sqlite3_mutex_leave(db
->mutex
);
801 CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p\n", db
->mutex
);
806 int sqlcipher_find_db_index(sqlite3
*db
, const char *zDb
) {
811 for(db_index
= 0; db_index
< db
->nDb
; db_index
++) {
812 struct Db
*pDb
= &db
->aDb
[db_index
];
813 if(strcmp(pDb
->zDbSName
, zDb
) == 0) {
820 void sqlite3_activate_see(const char* in
) {
821 /* do nothing, security enhancements are always active */
824 int sqlite3_key(sqlite3
*db
, const void *pKey
, int nKey
) {
825 CODEC_TRACE("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db
, (char *)pKey
, nKey
);
826 return sqlite3_key_v2(db
, "main", pKey
, nKey
);
829 int sqlite3_key_v2(sqlite3
*db
, const char *zDb
, const void *pKey
, int nKey
) {
830 CODEC_TRACE("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db
, zDb
, (char *)pKey
, nKey
);
831 /* attach key if db and pKey are not null and nKey is > 0 */
832 if(db
&& pKey
&& nKey
) {
833 int db_index
= sqlcipher_find_db_index(db
, zDb
);
834 return sqlite3CodecAttach(db
, db_index
, pKey
, nKey
);
839 int sqlite3_rekey(sqlite3
*db
, const void *pKey
, int nKey
) {
840 CODEC_TRACE("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db
, (char *)pKey
, nKey
);
841 return sqlite3_rekey_v2(db
, "main", pKey
, nKey
);
845 ** Given a database, this will reencrypt the database using a new key.
846 ** There is only one possible modes of operation - to encrypt a database
847 ** that is already encrpyted. If the database is not already encrypted
848 ** this should do nothing
849 ** The proposed logic for this function follows:
850 ** 1. Determine if the database is already encryptped
851 ** 2. If there is NOT already a key present do nothing
852 ** 3. If there is a key present, re-encrypt the database with the new key
854 int sqlite3_rekey_v2(sqlite3
*db
, const char *zDb
, const void *pKey
, int nKey
) {
855 CODEC_TRACE("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db
, zDb
, (char *)pKey
, nKey
);
856 if(db
&& pKey
&& nKey
) {
857 int db_index
= sqlcipher_find_db_index(db
, zDb
);
858 struct Db
*pDb
= &db
->aDb
[db_index
];
859 CODEC_TRACE("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb
, db_index
);
865 Pager
*pPager
= pDb
->pBt
->pBt
->pPager
;
867 ctx
= (codec_ctx
*) sqlite3PagerGetCodec(pDb
->pBt
->pBt
->pPager
);
870 /* there was no codec attached to this database, so this should do nothing! */
871 CODEC_TRACE("sqlite3_rekey_v2: no codec attached to db, exiting\n");
875 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entering database mutex %p\n", db
->mutex
);
876 sqlite3_mutex_enter(db
->mutex
);
877 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entered database mutex %p\n", db
->mutex
);
879 codec_set_pass_key(db
, db_index
, pKey
, nKey
, CIPHER_WRITE_CTX
);
881 /* do stuff here to rewrite the database
882 ** 1. Create a transaction on the database
883 ** 2. Iterate through each page, reading it and then writing it.
884 ** 3. If that goes ok then commit and put ctx->rekey into ctx->key
885 ** note: don't deallocate rekey since it may be used in a subsequent iteration
887 rc
= sqlite3BtreeBeginTrans(pDb
->pBt
, 1, 0); /* begin write transaction */
888 sqlite3PagerPagecount(pPager
, &page_count
);
889 for(pgno
= 1; rc
== SQLITE_OK
&& pgno
<= (unsigned int)page_count
; pgno
++) { /* pgno's start at 1 see pager.c:pagerAcquire */
890 if(!sqlite3pager_is_mj_pgno(pPager
, pgno
)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */
891 rc
= sqlite3PagerGet(pPager
, pgno
, &page
, 0);
892 if(rc
== SQLITE_OK
) { /* write page see pager_incr_changecounter for example */
893 rc
= sqlite3PagerWrite(page
);
894 if(rc
== SQLITE_OK
) {
895 sqlite3PagerUnref(page
);
897 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc
, pgno
);
900 CODEC_TRACE("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc
, pgno
);
905 /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */
906 if(rc
== SQLITE_OK
) {
907 CODEC_TRACE("sqlite3_rekey_v2: committing\n");
908 rc
= sqlite3BtreeCommit(pDb
->pBt
);
909 sqlcipher_codec_key_copy(ctx
, CIPHER_WRITE_CTX
);
911 CODEC_TRACE("sqlite3_rekey_v2: rollback\n");
912 sqlite3BtreeRollback(pDb
->pBt
, SQLITE_ABORT_ROLLBACK
, 0);
915 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: leaving database mutex %p\n", db
->mutex
);
916 sqlite3_mutex_leave(db
->mutex
);
917 CODEC_TRACE_MUTEX("sqlite3_rekey_v2: left database mutex %p\n", db
->mutex
);
924 void sqlite3CodecGetKey(sqlite3
* db
, int nDb
, void **zKey
, int *nKey
) {
925 struct Db
*pDb
= &db
->aDb
[nDb
];
926 CODEC_TRACE("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db
, nDb
);
928 codec_ctx
*ctx
= (codec_ctx
*) sqlite3PagerGetCodec(pDb
->pBt
->pBt
->pPager
);
931 /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass
932 is set or keyspec has not yet been derived, in which case pass
933 back the password key material */
934 sqlcipher_codec_get_keyspec(ctx
, zKey
, nKey
);
935 if(sqlcipher_codec_get_store_pass(ctx
) == 1 || *zKey
== NULL
) {
936 sqlcipher_codec_get_pass(ctx
, zKey
, nKey
);
948 * Implementation of an "export" function that allows a caller
949 * to duplicate the main database to an attached database. This is intended
950 * as a conveneince for users who need to:
952 * 1. migrate from an non-encrypted database to an encrypted database
953 * 2. move from an encrypted database to a non-encrypted database
954 * 3. convert beween the various flavors of encrypted databases.
956 * This implementation is based heavily on the procedure and code used
957 * in vacuum.c, but is exposed as a function that allows export to any
958 * named attached database.
962 ** Finalize a prepared statement. If there was an error, store the
963 ** text of the error message in *pzErrMsg. Return the result code.
965 ** Based on vacuumFinalize from vacuum.c
967 static int sqlcipher_finalize(sqlite3
*db
, sqlite3_stmt
*pStmt
, char **pzErrMsg
){
969 rc
= sqlite3VdbeFinalize((Vdbe
*)pStmt
);
971 sqlite3SetString(pzErrMsg
, db
, sqlite3_errmsg(db
));
977 ** Execute zSql on database db. Return an error code.
979 ** Based on execSql from vacuum.c
981 static int sqlcipher_execSql(sqlite3
*db
, char **pzErrMsg
, const char *zSql
){
987 if( SQLITE_OK
!=sqlite3_prepare(db
, zSql
, -1, &pStmt
, 0) ){
988 sqlite3SetString(pzErrMsg
, db
, sqlite3_errmsg(db
));
989 return sqlite3_errcode(db
);
991 VVA_ONLY( rc
= ) sqlite3_step(pStmt
);
992 assert( rc
!=SQLITE_ROW
);
993 return sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
997 ** Execute zSql on database db. The statement returns exactly
998 ** one column. Execute this as SQL on the same database.
1000 ** Based on execExecSql from vacuum.c
1002 static int sqlcipher_execExecSql(sqlite3
*db
, char **pzErrMsg
, const char *zSql
){
1003 sqlite3_stmt
*pStmt
;
1006 rc
= sqlite3_prepare(db
, zSql
, -1, &pStmt
, 0);
1007 if( rc
!=SQLITE_OK
) return rc
;
1009 while( SQLITE_ROW
==sqlite3_step(pStmt
) ){
1010 rc
= sqlcipher_execSql(db
, pzErrMsg
, (char*)sqlite3_column_text(pStmt
, 0));
1011 if( rc
!=SQLITE_OK
){
1012 sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
1017 return sqlcipher_finalize(db
, pStmt
, pzErrMsg
);
1021 * copy database and schema from the main database to an attached database
1023 * Based on sqlite3RunVacuum from vacuum.c
1025 void sqlcipher_exportFunc(sqlite3_context
*context
, int argc
, sqlite3_value
**argv
) {
1026 sqlite3
*db
= sqlite3_context_db_handle(context
);
1027 const char* targetDb
, *sourceDb
;
1028 int targetDb_idx
= 0;
1029 u64 saved_flags
= db
->flags
; /* Saved value of the db->flags */
1030 u32 saved_mDbFlags
= db
->mDbFlags
; /* Saved value of the db->mDbFlags */
1031 int saved_nChange
= db
->nChange
; /* Saved value of db->nChange */
1032 int saved_nTotalChange
= db
->nTotalChange
; /* Saved value of db->nTotalChange */
1033 u8 saved_mTrace
= db
->mTrace
; /* Saved value of db->mTrace */
1034 int (*saved_xTrace
)(u32
,void*,void*,void*) = db
->xTrace
; /* Saved db->xTrace */
1035 int rc
= SQLITE_OK
; /* Return code from service routines */
1036 char *zSql
= NULL
; /* SQL statements */
1037 char *pzErrMsg
= NULL
;
1039 if(argc
!= 1 && argc
!= 2) {
1041 pzErrMsg
= sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc
);
1045 targetDb
= (const char*) sqlite3_value_text(argv
[0]);
1046 sourceDb
= (argc
== 2) ? (char *) sqlite3_value_text(argv
[1]) : "main";
1048 /* if the name of the target is not main, but the index returned is zero
1049 there is a mismatch and we should not proceed */
1050 targetDb_idx
= sqlcipher_find_db_index(db
, targetDb
);
1051 if(targetDb_idx
== 0 && sqlite3StrICmp("main", targetDb
) != 0) {
1053 pzErrMsg
= sqlite3_mprintf("unknown database %s", targetDb
);
1056 db
->init
.iDb
= targetDb_idx
;
1058 db
->flags
|= SQLITE_WriteSchema
| SQLITE_IgnoreChecks
;
1059 db
->mDbFlags
|= DBFLAG_PreferBuiltin
| DBFLAG_Vacuum
;
1060 db
->flags
&= ~(u64
)(SQLITE_ForeignKeys
| SQLITE_ReverseOrder
| SQLITE_Defensive
| SQLITE_CountRows
);
1064 /* Query the schema of the main database. Create a mirror schema
1065 ** in the temporary database.
1067 zSql
= sqlite3_mprintf(
1069 " FROM %s.sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
1072 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
1073 if( rc
!=SQLITE_OK
) goto end_of_export
;
1076 zSql
= sqlite3_mprintf(
1078 " FROM %s.sqlite_master WHERE sql LIKE 'CREATE INDEX %%' "
1080 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
1081 if( rc
!=SQLITE_OK
) goto end_of_export
;
1084 zSql
= sqlite3_mprintf(
1086 " FROM %s.sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'"
1088 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
1089 if( rc
!=SQLITE_OK
) goto end_of_export
;
1092 /* Loop through the tables in the main database. For each, do
1093 ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy
1094 ** the contents to the temporary database.
1096 zSql
= sqlite3_mprintf(
1097 "SELECT 'INSERT INTO %s.' || quote(name) "
1098 "|| ' SELECT * FROM %s.' || quote(name) || ';'"
1099 "FROM %s.sqlite_master "
1100 "WHERE type = 'table' AND name!='sqlite_sequence' "
1102 , targetDb
, sourceDb
, sourceDb
);
1103 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
1104 if( rc
!=SQLITE_OK
) goto end_of_export
;
1107 /* Copy over the contents of the sequence table
1109 zSql
= sqlite3_mprintf(
1110 "SELECT 'INSERT INTO %s.' || quote(name) "
1111 "|| ' SELECT * FROM %s.' || quote(name) || ';' "
1112 "FROM %s.sqlite_master WHERE name=='sqlite_sequence';"
1113 , targetDb
, sourceDb
, targetDb
);
1114 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execExecSql(db
, &pzErrMsg
, zSql
);
1115 if( rc
!=SQLITE_OK
) goto end_of_export
;
1118 /* Copy the triggers, views, and virtual tables from the main database
1119 ** over to the temporary database. None of these objects has any
1120 ** associated storage, so all we have to do is copy their entries
1121 ** from the SQLITE_MASTER table.
1123 zSql
= sqlite3_mprintf(
1124 "INSERT INTO %s.sqlite_master "
1125 " SELECT type, name, tbl_name, rootpage, sql"
1126 " FROM %s.sqlite_master"
1127 " WHERE type='view' OR type='trigger'"
1128 " OR (type='table' AND rootpage=0)"
1129 , targetDb
, sourceDb
);
1130 rc
= (zSql
== NULL
) ? SQLITE_NOMEM
: sqlcipher_execSql(db
, &pzErrMsg
, zSql
);
1131 if( rc
!=SQLITE_OK
) goto end_of_export
;
1137 db
->flags
= saved_flags
;
1138 db
->mDbFlags
= saved_mDbFlags
;
1139 db
->nChange
= saved_nChange
;
1140 db
->nTotalChange
= saved_nTotalChange
;
1141 db
->xTrace
= saved_xTrace
;
1142 db
->mTrace
= saved_mTrace
;
1144 if(zSql
) sqlite3_free(zSql
);
1147 if(pzErrMsg
!= NULL
) {
1148 sqlite3_result_error(context
, pzErrMsg
, -1);
1149 sqlite3DbFree(db
, pzErrMsg
);
1151 sqlite3_result_error(context
, sqlite3ErrStr(rc
), -1);