Skip to content

Commit e4b66d6

Browse files
committed
adds PRAGMA cipher_compatibility and cipher_default_compatibility
1 parent 60b49b6 commit e4b66d6

4 files changed

Lines changed: 224 additions & 44 deletions

File tree

sqlcipher-4.0-testkey.db

956 KB
Binary file not shown.

src/crypto.c

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,6 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
369369
} else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) {
370370
rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
371371
}
372-
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
373372
} else {
374373
int algorithm = sqlcipher_get_default_hmac_algorithm();
375374
if(algorithm == SQLCIPHER_HMAC_SHA1) {
@@ -415,7 +414,6 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
415414
} else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) {
416415
rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
417416
}
418-
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
419417
} else {
420418
int algorithm = sqlcipher_get_default_kdf_algorithm();
421419
if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) {
@@ -427,6 +425,108 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
427425
}
428426
}
429427
}else
428+
if( sqlite3StrICmp(zLeft,"cipher_compatibility")==0 ){
429+
if(ctx) {
430+
if(zRight) {
431+
int version = atoi(zRight);
432+
433+
switch(version) {
434+
case 1:
435+
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
436+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
437+
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
438+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
439+
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
440+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
441+
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
442+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
443+
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 0);
444+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
445+
break;
446+
447+
case 2:
448+
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
449+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
450+
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
451+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
452+
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
453+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
454+
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 4000);
455+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
456+
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
457+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
458+
break;
459+
460+
case 3:
461+
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 1024);
462+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
463+
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1);
464+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
465+
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1);
466+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
467+
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 64000);
468+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
469+
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
470+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
471+
break;
472+
473+
default:
474+
rc = sqlcipher_codec_ctx_set_pagesize(ctx, 4096);
475+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
476+
rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512);
477+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
478+
rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512);
479+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
480+
rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, 256000);
481+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
482+
rc = sqlcipher_codec_ctx_set_use_hmac(ctx, 1);
483+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
484+
break;
485+
}
486+
487+
rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
488+
if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR);
489+
}
490+
}
491+
}else
492+
if( sqlite3StrICmp(zLeft,"cipher_default_compatibility")==0 ){
493+
if(zRight) {
494+
int version = atoi(zRight);
495+
switch(version) {
496+
case 1:
497+
sqlcipher_set_default_pagesize(1024);
498+
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
499+
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
500+
sqlcipher_set_default_kdf_iter(4000);
501+
sqlcipher_set_default_use_hmac(0);
502+
break;
503+
504+
case 2:
505+
sqlcipher_set_default_pagesize(1024);
506+
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1);
507+
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1);
508+
sqlcipher_set_default_kdf_iter(4000);
509+
sqlcipher_set_default_use_hmac(1);
510+
break;
511+
512+
case 3:
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(64000);
517+
sqlcipher_set_default_use_hmac(1);
518+
break;
519+
520+
default:
521+
sqlcipher_set_default_pagesize(4096);
522+
sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512);
523+
sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512);
524+
sqlcipher_set_default_kdf_iter(256000);
525+
sqlcipher_set_default_use_hmac(1);
526+
break;
527+
}
528+
}
529+
}else
430530
if( sqlite3StrICmp(zLeft,"cipher_memory_security")==0 ){
431531
if( zRight ) {
432532
sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1));

src/crypto_impl.c

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,22 +1235,19 @@ static int sqlcipher_check_connection(const char *filename, char *key, int key_s
12351235
}
12361236

12371237
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
1238-
int i, pass_sz, keyspec_sz, nRes, user_version, upgrade_from, rc, oflags;
1238+
int i, pass_sz, keyspec_sz, nRes, user_version, rc, oflags;
12391239
Db *pDb = 0;
12401240
sqlite3 *db = ctx->pBt->db;
12411241
const char *db_filename = sqlite3_db_filename(db, "main");
1242-
char *v1_pragmas = "PRAGMA cipher_use_hmac = OFF; PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
1243-
char *v2_pragmas = "PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
1244-
char *v3_pragmas = "PRAGMA kdf_iter = 64000; PRAGMA cipher_page_size = 1024; PRAGMA cipher_hmac_algorithm = HMAC_SHA1; PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;";
1245-
char *set_user_version = NULL, *pass = NULL, *attach_command = NULL, *migrated_db_filename = NULL, *keyspec = NULL, *temp = NULL, *journal_mode = NULL, *set_journal_mode = NULL;
1242+
char *set_user_version = NULL, *pass = NULL, *attach_command = NULL, *migrated_db_filename = NULL, *keyspec = NULL, *temp = NULL, *journal_mode = NULL, *set_journal_mode = NULL, *pragma_compat = NULL;
12461243
Btree *pDest = NULL, *pSrc = NULL;
12471244
const char* commands[5];
12481245
sqlite3_file *srcfile, *destfile;
12491246
#if defined(_WIN32) || defined(SQLITE_OS_WINRT)
12501247
LPWSTR w_db_filename = NULL, w_migrated_db_filename = NULL;
12511248
int w_db_filename_sz = 0, w_migrated_db_filename_sz = 0;
12521249
#endif
1253-
pass_sz = keyspec_sz = rc = user_version = upgrade_from = 0;
1250+
pass_sz = keyspec_sz = rc = user_version = 0;
12541251

12551252
if(!db_filename || sqlite3Strlen30(db_filename) < 1)
12561253
goto cleanup; /* exit immediately if this is an in memory database */
@@ -1268,29 +1265,19 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
12681265
goto cleanup;
12691266
}
12701267

1271-
/* Version 3 - check for 64k with hmac format and 1024 page size */
1272-
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v3_pragmas, &user_version, &journal_mode);
1273-
if(rc == SQLITE_OK) {
1274-
CODEC_TRACE("Version 3 format found\n");
1275-
upgrade_from = 3;
1276-
goto migrate;
1277-
}
1278-
1279-
/* Version 2 - check for 4k with hmac format and 1024 page size */
1280-
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v2_pragmas, &user_version, &journal_mode);
1281-
if(rc == SQLITE_OK) {
1282-
CODEC_TRACE("Version 2 format found\n");
1283-
upgrade_from = 2;
1284-
goto migrate;
1285-
}
1286-
1287-
/* Version 1 - check no HMAC, 4k KDF, and 1024 page size */
1288-
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, v1_pragmas, &user_version, &journal_mode);
1289-
if(rc == SQLITE_OK) {
1290-
CODEC_TRACE("Version 1 format found\n");
1291-
upgrade_from = 1;
1292-
goto migrate;
1268+
for(int i = 3; i > 0; i--) {
1269+
pragma_compat = sqlite3_mprintf("PRAGMA cipher_compatibility = %d;", i);
1270+
rc = sqlcipher_check_connection(db_filename, pass, pass_sz, pragma_compat, &user_version, &journal_mode);
1271+
if(rc == SQLITE_OK) {
1272+
CODEC_TRACE("Version %d format found\n", i);
1273+
goto migrate;
1274+
}
1275+
if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat));
1276+
pragma_compat = NULL;
12931277
}
1278+
/* if we exit the loop normally we failed to determine the version, this is an error */
1279+
CODEC_TRACE("Upgrade format not determined\n");
1280+
goto handle_error;
12941281

12951282
migrate:
12961283

@@ -1303,20 +1290,8 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
13031290

13041291
attach_command = sqlite3_mprintf("ATTACH DATABASE '%s' as migrate KEY '%q';", migrated_db_filename, pass);
13051292
set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
1306-
switch(upgrade_from) {
1307-
case 1:
1308-
commands[0] = v1_pragmas;
1309-
break;
1310-
case 2:
1311-
commands[0] = v2_pragmas;
1312-
break;
1313-
case 3:
1314-
commands[0] = v3_pragmas;
1315-
break;
1316-
default:
1317-
CODEC_TRACE("Upgrade format not determined\n");
1318-
goto handle_error;
1319-
}
1293+
1294+
commands[0] = pragma_compat;
13201295
commands[1] = "PRAGMA journal_mode = delete;"; /* force journal mode to DELETE, we will set it back later if different */
13211296
commands[2] = attach_command;
13221297
commands[3] = "SELECT sqlcipher_export('migrate');";
@@ -1423,6 +1398,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
14231398
if(set_user_version) sqlcipher_free(set_user_version, sqlite3Strlen30(set_user_version));
14241399
if(set_journal_mode) sqlcipher_free(set_journal_mode, sqlite3Strlen30(set_journal_mode));
14251400
if(journal_mode) sqlcipher_free(journal_mode, sqlite3Strlen30(journal_mode));
1401+
if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat));
14261402
#if defined(_WIN32) || defined(SQLITE_OS_WINRT)
14271403
if(w_db_filename) sqlcipher_free(w_db_filename, w_db_filename_sz);
14281404
if(w_migrated_db_filename) sqlcipher_free(w_migrated_db_filename, w_migrated_db_filename_sz);

test/sqlcipher-compatibility.test

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ db2 close
107107
file delete -force test.db
108108
file delete -force test2.db
109109

110+
# open a 4.0 database
111+
do_test compat-open-4.0-database {
112+
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
113+
execsql {
114+
PRAGMA key = 'testkey';
115+
PRAGMA integrity_check;
116+
SELECT count(*) FROM t1;
117+
}
118+
} {ok 78536}
119+
db close
120+
110121
# create an encrypted database, attach an default-key encrypted volume
111122
# copy data between, verify the second database
112123
do_test encrypted-attach-default-key {
@@ -1228,6 +1239,99 @@ db close
12281239
file delete -force plain.db
12291240
file delete -force encrypted.db
12301241

1242+
# open a 1.1.8 database using cipher_compatibility
1243+
do_test compat-open-1.1.8-database {
1244+
sqlite_orig db $sampleDir/sqlcipher-1.1.8-testkey.db
1245+
execsql {
1246+
PRAGMA key = 'testkey';
1247+
PRAGMA cipher_compatibility = 1;
1248+
PRAGMA integrity_check;
1249+
SELECT count(*) FROM t1;
1250+
}
1251+
} {ok 75709}
1252+
db close
1253+
1254+
# open a 2.0 database using cipher_compatibility
1255+
do_test compat-open-2.0-database {
1256+
sqlite_orig db $sampleDir/sqlcipher-2.0-le-testkey.db
1257+
execsql {
1258+
PRAGMA key = 'testkey';
1259+
PRAGMA cipher_compatibility = 2;
1260+
PRAGMA integrity_check;
1261+
SELECT count(*) FROM t1;
1262+
}
1263+
} {ok 78536}
1264+
db close
1265+
1266+
# open a 3.0 database using cipher_compatibility
1267+
do_test compat-open-3.0-database {
1268+
sqlite_orig db $sampleDir/sqlcipher-3.0-testkey.db
1269+
execsql {
1270+
PRAGMA key = 'testkey';
1271+
PRAGMA cipher_compatibility = 3;
1272+
PRAGMA integrity_check;
1273+
SELECT count(*) FROM t1;
1274+
}
1275+
} {ok 78536}
1276+
db close
1277+
1278+
# open a 4.0 database using cipher_compatibility
1279+
do_test compat-open-4.0-database {
1280+
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
1281+
execsql {
1282+
PRAGMA key = 'testkey';
1283+
PRAGMA cipher_compatibility = 4;
1284+
PRAGMA integrity_check;
1285+
SELECT count(*) FROM t1;
1286+
}
1287+
} {ok 78536}
1288+
db close
1289+
1290+
# open a 1.1.8 database using cipher_default_compatibility
1291+
do_test default-compat-open-1.1.8-database {
1292+
sqlite_orig db $sampleDir/sqlcipher-1.1.8-testkey.db
1293+
execsql {
1294+
PRAGMA cipher_default_compatibility = 1;
1295+
PRAGMA key = 'testkey';
1296+
PRAGMA integrity_check;
1297+
SELECT count(*) FROM t1;
1298+
}
1299+
} {ok 75709}
1300+
db close
1301+
1302+
# open a 2.0 database using cipher_default_compatibility
1303+
do_test default-compat-open-2.0-database {
1304+
sqlite_orig db $sampleDir/sqlcipher-2.0-le-testkey.db
1305+
execsql {
1306+
PRAGMA cipher_default_compatibility = 2;
1307+
PRAGMA key = 'testkey';
1308+
PRAGMA integrity_check;
1309+
SELECT count(*) FROM t1;
1310+
}
1311+
} {ok 78536}
1312+
1313+
# open a 3.0 database using cipher_default_compatibility
1314+
do_test default-compat-open-3.0-database {
1315+
sqlite_orig db $sampleDir/sqlcipher-3.0-testkey.db
1316+
execsql {
1317+
PRAGMA cipher_default_compatibility = 3;
1318+
PRAGMA key = 'testkey';
1319+
PRAGMA integrity_check;
1320+
SELECT count(*) FROM t1;
1321+
}
1322+
} {ok 78536}
1323+
1324+
# re-open a 4.0 database using cipher_default_compatibility
1325+
do_test default-compat-open-4.0-database {
1326+
sqlite_orig db $sampleDir/sqlcipher-4.0-testkey.db
1327+
execsql {
1328+
PRAGMA cipher_default_compatibility = 4;
1329+
PRAGMA key = 'testkey';
1330+
PRAGMA integrity_check;
1331+
SELECT count(*) FROM t1;
1332+
}
1333+
} {ok 78536}
1334+
12311335
sqlite3_test_control_pending_byte $old_pending_byte
12321336

12331337
finish_test

0 commit comments

Comments
 (0)