adjust default page size to 4096

This commit is contained in:
Stephen Lombardo 2018-08-30 13:14:18 -04:00
parent 1001b72e9f
commit fee1153e5c
2 changed files with 122 additions and 70 deletions

View File

@ -73,7 +73,7 @@ typedef struct {
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
static int default_kdf_iter = PBKDF2_ITER;
static int default_page_size = 1024;
static int default_page_size = 4096;
static int default_plaintext_header_sz = 0;
static unsigned int sqlcipher_activate_count = 0;
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
@ -1198,29 +1198,22 @@ cleanup:
return rc;
}
static int pager_truncate(Pager *pPager, Pgno nPage);
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
u32 meta;
int rc = 0;
int command_idx = 0;
int password_sz;
int saved_flags;
int saved_nChange;
int saved_nTotalChange;
int i, password_sz, key_sz, saved_flags, saved_nChange, saved_nTotalChange, nRes, user_version = 0, upgrade_from = 0, rc = 0;
u8 saved_mTrace;
int (*saved_xTrace)(u32,void*,void*,void*); /* Saved db->xTrace */
Db *pDb = 0;
sqlite3 *db = ctx->pBt->db;
const char *db_filename = sqlite3_db_filename(db, "main");
char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename);
char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;";
char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;";
char *pragma_1x_and_4k;
char *set_user_version;
char *key;
int key_sz;
int user_version = 0;
int upgrade_1x_format = 0;
int upgrade_4k_format = 0;
char *v1_pragmas = "PRAGMA cipher_use_hmac = OFF; PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024;";
char *v2_pragmas = "PRAGMA kdf_iter = 4000; PRAGMA cipher_page_size = 1024;";
char *v3_pragmas = "PRAGMA kdf_iter = 64000; PRAGMA cipher_page_size = 1024;";
char *set_user_version, *key;
Btree *pDest = NULL, *pSrc = NULL;
static const unsigned char aCopy[] = {
BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
@ -1229,6 +1222,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
BTREE_APPLICATION_ID, 0, /* Preserve the application id */
};
rc = user_version = upgrade_from = 0;
key_sz = ctx->read_ctx->pass_sz + 1;
key = sqlcipher_malloc(key_sz);
@ -1236,7 +1230,7 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
if(db_filename){
const char* commands[5];
const char* commands[4];
char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';",
db_filename, key);
@ -1246,43 +1240,50 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
goto exit;
}
// Version 2 - check for 4k with hmac format
rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_4k_kdf_iter, &user_version);
/* Version 3 - check for 64k with hmac format and 1024 page size */
rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, v3_pragmas, &user_version);
if(rc == SQLITE_OK) {
CODEC_TRACE("Version 3 format found\n");
upgrade_from = 3;
}
/* Version 2 - check for 4k with hmac format and 1024 page size */
rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, v2_pragmas, &user_version);
if(rc == SQLITE_OK) {
CODEC_TRACE("Version 2 format found\n");
upgrade_4k_format = 1;
upgrade_from = 2;
}
// Version 1 - check both no hmac and 4k together
pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off,
pragma_4k_kdf_iter);
rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, pragma_1x_and_4k, &user_version);
sqlite3_free(pragma_1x_and_4k);
/* Version 1 - check no HMAC, 4k KDF, and 1024 page size */
rc = sqlcipher_check_connection(db_filename, key, ctx->read_ctx->pass_sz, v1_pragmas, &user_version);
if(rc == SQLITE_OK) {
CODEC_TRACE("Version 1 format found\n");
upgrade_1x_format = 1;
upgrade_4k_format = 1;
}
if(upgrade_1x_format == 0 && upgrade_4k_format == 0) {
CODEC_TRACE("Upgrade format not determined\n");
goto handle_error;
upgrade_from = 1;
}
set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "";
commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : "";
commands[2] = attach_command;
commands[3] = "SELECT sqlcipher_export('migrate');";
commands[4] = set_user_version;
for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){
const char *command = commands[command_idx];
if(strcmp(command, "") == 0){
continue;
switch(upgrade_from) {
case 1:
commands[0] = v1_pragmas;
break;
case 2:
commands[0] = v2_pragmas;
break;
case 3:
commands[0] = v3_pragmas;
break;
default:
CODEC_TRACE("Upgrade format not determined\n");
goto handle_error;
}
rc = sqlite3_exec(db, command, NULL, NULL, NULL);
commands[1] = attach_command;
commands[2] = "SELECT sqlcipher_export('migrate');";
commands[3] = set_user_version;
for(i = 0; i < ArraySize(commands); i++){
rc = sqlite3_exec(db, commands[i], NULL, NULL, NULL);
if(rc != SQLITE_OK){
CODEC_TRACE("migration step %d failed error code %d\n", i, rc);
break;
}
}
@ -1291,9 +1292,6 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
sqlcipher_free(key, key_sz);
if(rc == SQLITE_OK){
Btree *pDest;
Btree *pSrc;
int i = 0;
if( !db->autoCommit ){
CODEC_TRACE("cannot migrate from within a transaction");
@ -1316,32 +1314,53 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
db->xTrace = 0;
db->mTrace = 0;
pDest = db->aDb[0].pBt;
pDb = &(db->aDb[db->nDb-1]);
pSrc = pDb->pBt;
nRes = sqlite3BtreeGetOptimalReserve(pSrc);
rc = sqlite3BtreeSetPageSize(pDest, default_page_size, nRes, 0);
if( rc!=SQLITE_OK ) goto handle_error;
CODEC_TRACE("set BTree page size to %d res %d rc %d\n", default_page_size, nRes, rc);
rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
if( rc!=SQLITE_OK ) goto handle_error;
pager_truncate(pDest->pBt->pPager, 0);
rc = sqlite3BtreeBeginTrans(pSrc, 2);
if( rc!=SQLITE_OK ) goto handle_error;
rc = sqlite3BtreeBeginTrans(pDest, 2);
if( rc!=SQLITE_OK ) goto handle_error;
assert( 1==sqlite3BtreeIsInTrans(pDest) );
assert( 1==sqlite3BtreeIsInTrans(pSrc) );
CODEC_TRACE("started transactions\n");
sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
sqlite3CodecAttach(db, 0, key, password_sz);
sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
ctx->skip_read_hmac = 1;
for(i=0; i<ArraySize(aCopy); i+=2){
sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
CODEC_TRACE("applied metadata %d %d\n",i, rc);
if( NEVER(rc!=SQLITE_OK) ) goto handle_error;
}
CODEC_TRACE("finished applied metadata\n");
rc = sqlite3BtreeCopyFile(pDest, pSrc);
ctx->skip_read_hmac = 0;
if( rc!=SQLITE_OK ) goto handle_error;
CODEC_TRACE("copied btree %d\n", rc);
rc = sqlite3BtreeCommit(pDest);
if( rc!=SQLITE_OK ) goto handle_error;
CODEC_TRACE("committed destination transaction %d\n", rc);
db->flags = saved_flags;
db->nChange = saved_nChange;
@ -1356,17 +1375,19 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
remove(migrated_db_filename);
sqlite3_free(migrated_db_filename);
} else {
CODEC_TRACE("*** migration failure** \n\n");
CODEC_TRACE("*** migration failure** error code: %d\n", rc);
}
}
goto exit;
handle_error:
handle_error:
if(pDest) sqlite3BtreeRollback(pDest, SQLITE_OK, 0);
CODEC_TRACE("An error occurred attempting to migrate the database\n");
rc = SQLITE_ERROR;
exit:
exit:
return rc;
}

View File

@ -1,4 +1,3 @@
# SQLCipher
# codec.test developed by Stephen Lombardo (Zetetic LLC)
# sjlombardo at zetetic dot net
# http://zetetic.net
@ -878,7 +877,7 @@ do_test custom-pagesize {
execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
CREATE table t1(a,b);
BEGIN;
}
@ -897,7 +896,7 @@ do_test custom-pagesize {
execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
SELECT count(*) FROM t1;
}
@ -1003,6 +1002,7 @@ do_test open-1.1.8-database {
PRAGMA key = 'testkey';
PRAGMA cipher_use_hmac = off;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM t1;
SELECT distinct * FROM t1;
}
@ -1018,6 +1018,7 @@ do_test attach-and-copy-1.1.8 {
PRAGMA key = 'testkey';
PRAGMA cipher_use_hmac = OFF;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac';
CREATE TABLE db2.t1(a,b);
INSERT INTO db2.t1 SELECT * FROM main.t1;
@ -1056,7 +1057,7 @@ do_test attached-database-pragmas {
execsql {
COMMIT;
ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2';
PRAGMA db2.cipher_page_size = 4096;
PRAGMA db2.cipher_page_size = 8192;
PRAGMA db2.cipher = 'aes-128-cbc';
PRAGMA db2.kdf_iter = 1000;
PRAGMA db2.cipher_use_hmac = OFF;
@ -1069,7 +1070,7 @@ do_test attached-database-pragmas {
sqlite_orig db test2.db
execsql {
PRAGMA key = 'testkey2';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
PRAGMA cipher = 'aes-128-cbc';
PRAGMA kdf_iter = 1000;
PRAGMA cipher_use_hmac = OFF;
@ -1135,7 +1136,7 @@ do_test export-database {
COMMIT;
ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2';
PRAGMA db2.cipher_page_size = 4096;
PRAGMA db2.cipher_page_size = 8192;
SELECT sqlcipher_export('db2');
@ -1146,7 +1147,7 @@ do_test export-database {
sqlite_orig db test2.db
execsql {
PRAGMA key = 'testkey2';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
SELECT count(*) FROM t1;
SELECT count(*) FROM v1;
SELECT count(*) FROM sqlite_sequence;
@ -1455,7 +1456,7 @@ do_test cipher-options-before-keys {
execsql {
PRAGMA kdf_iter = 1000;
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
PRAGMA cipher = 'aes-128-cbc';
PRAGMA cipher_use_hmac = OFF;
PRAGMA key = 'testkey';
@ -1486,12 +1487,14 @@ do_test default-hmac-kdf-attach {
execsql {
PRAGMA cipher_default_use_hmac = OFF;
PRAGMA cipher_default_kdf_iter = 4000;
PRAGMA cipher_default_page_size = 1024;
PRAGMA key = 'testkey';
SELECT count(*) FROM t1;
ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
SELECT count(*) from db2.t1;
PRAGMA cipher_default_use_hmac = ON;
PRAGMA cipher_default_kdf_iter = 64000;
PRAGMA cipher_default_kdf_iter = 4096;
}
} {75709 75709}
db close
@ -1535,10 +1538,12 @@ do_test change-default-hmac-kdf-attach {
SELECT count(*) FROM t1;
PRAGMA cipher_default_use_hmac = OFF;
PRAGMA cipher_default_kdf_iter = 4000;
PRAGMA cipher_default_page_size = 1024;
ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
SELECT count(*) from db2.t1;
PRAGMA cipher_default_use_hmac = ON;
PRAGMA cipher_default_kdf_iter = 64000;
PRAGMA cipher_default_page_size = 4096;
}
} {1 75709}
db close
@ -1721,6 +1726,7 @@ do_test open-3.0-le-database {
sqlite_orig db $sampleDir/sqlcipher-3.0-testkey.db
execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM t1;
SELECT distinct * FROM t1;
}
@ -1734,6 +1740,7 @@ do_test open-2.0-le-database {
execsql {
PRAGMA key = 'testkey';
PRAGMA kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM t1;
SELECT distinct * FROM t1;
}
@ -1748,6 +1755,7 @@ do_test open-2.0-be-database {
PRAGMA key = 'testkey';
PRAGMA cipher_hmac_pgno = be;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM t1;
SELECT distinct * FROM t1;
}
@ -1765,6 +1773,7 @@ do_test be-to-le-migration {
PRAGMA key = 'testkey';
PRAGMA cipher_hmac_pgno = be;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
ATTACH DATABASE 'test.db' AS db2 KEY 'testkey';
CREATE TABLE db2.t1(a,b);
INSERT INTO db2.t1 SELECT * FROM main.t1;
@ -1917,7 +1926,7 @@ do_test verify-pragma-cipher-page-size-default {
PRAGMA key = 'test';
PRAGMA cipher_page_size;
}
} {1024}
} {4096}
db close
file delete -force test.db
@ -1927,10 +1936,10 @@ do_test verify-pragma-cipher-page-size-changed {
sqlite_orig db test.db
execsql {
PRAGMA key = 'test';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
PRAGMA cipher_page_size;
}
} {4096}
} {8192}
db close
file delete -force test.db
@ -2033,6 +2042,7 @@ do_test open-2.0-beta-database {
PRAGMA kdf_iter = 4000;
PRAGMA fast_kdf_iter = 4000;
PRAGMA cipher_hmac_salt_mask = "x'00'";
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM t1;
SELECT distinct * FROM t1;
}
@ -2051,6 +2061,7 @@ do_test 2.0-beta-to-2.0-migration {
PRAGMA cipher_hmac_salt_mask = "x'00'";
PRAGMA kdf_iter = 4000;
PRAGMA fast_kdf_iter = 4000;
PRAGMA cipher_page_size = 1024;
SELECT count(*) FROM sqlite_master;
PRAGMA cipher_hmac_salt_mask = "x'3a'";
@ -2089,9 +2100,9 @@ if_built_with_commoncrypto verify-default-cipher {
}
} {aes-256-cbc}
db close
file delete -force test.db
file delete -force test.db test.db-migrated test.db-journal
do_test migrate-1.1.8-database-to-3x-format {
do_test migrate-1.1.8-database-to-current-format {
file copy -force $sampleDir/sqlcipher-1.1.8-testkey.db test.db
sqlite_orig db test.db
execsql {
@ -2107,9 +2118,9 @@ do_test migrate-1.1.8-database-to-3x-format {
}
} {1}
db close
file delete -force test.db
file delete -force test.db test.db-migrated test.db-journal
do_test migrate-2-0-le-database-to-3x-format {
do_test migrate-2-0-le-database-to-current-format {
file copy -force $sampleDir/sqlcipher-2.0-le-testkey.db test.db
sqlite_orig db test.db
execsql {
@ -2125,6 +2136,24 @@ do_test migrate-2-0-le-database-to-3x-format {
}
} {1}
db close
file delete -force test.db test.db-migrated test.db-journal
do_test migrate-3-0-database-to-current-format {
file copy -force $sampleDir/sqlcipher-3.0-testkey.db test.db
sqlite_orig db test.db
execsql {
PRAGMA key = 'testkey';
PRAGMA cipher_migrate;
}
db close
sqlite_orig db test.db
execsql {
PRAGMA key = 'testkey';
SELECT count(*) FROM sqlite_master;
}
} {1}
db close
file delete -force test.db
do_test key-database-by-name {
@ -2233,6 +2262,7 @@ do_test can-migrate-with-keys-longer-than-64-characters {
sqlite_orig db test.db
execsql {
PRAGMA key = "012345678901234567890123456789012345678901234567890123456789012345";
PRAGMA cipher_page_size = 1024;
PRAGMA kdf_iter = 4000;
PRAGMA user_version = 5;
}
@ -2258,6 +2288,7 @@ do_test can-migrate-with-raw-hex-key {
sqlite_orig db test.db
execsql {
PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
PRAGMA cipher_page_size = 1024;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_use_hmac = off;
PRAGMA user_version = 5;
@ -2284,7 +2315,7 @@ do_test attach_database_with_non_default_page_size {
sqlite_orig db test2.db
execsql {
PRAGMA key = 'test';
PRAGMA cipher_page_size = 4096;
PRAGMA cipher_page_size = 8192;
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) values('one for the money', 'two for the show');
INSERT INTO t1(a,b) values('three to get ready', 'now, go cat, go');
@ -2293,7 +2324,7 @@ do_test attach_database_with_non_default_page_size {
sqlite_orig db test.db
execsql {
PRAGMA cipher_default_page_size = 4096;
PRAGMA cipher_default_page_size = 8192;
PRAGMA key = 'test';
ATTACH DATABASE 'test2.db' as test2 KEY 'test';
SELECT count(*) FROM test2.t1;