Skip to content

Commit 8f061f1

Browse files
committed
add pragma cipher_default_use_hmac to toggle global HMAC setting
1 parent ff9a340 commit 8f061f1

5 files changed

Lines changed: 79 additions & 6 deletions

File tree

src/crypto.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ct
7777
return rc;
7878
}
7979

80+
void codec_set_default_use_hmac(int use) {
81+
sqlcipher_set_default_use_hmac(use);
82+
}
83+
8084
int codec_set_use_hmac(sqlite3* db, int nDb, int use) {
8185
struct Db *pDb = &db->aDb[nDb];
8286

src/crypto.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *);
149149

150150
void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **);
151151

152+
void sqlcipher_set_default_use_hmac(int use);
153+
152154
int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use);
153155
/* end extensions defined in crypto_impl.c */
154156

src/crypto_impl.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *, cipher_ctx *);
7979
/* prototype for pager HMAC function */
8080
int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char *);
8181

82+
static int default_use_hmac = DEFAULT_USE_HMAC;
83+
8284
struct codec_ctx {
8385
int kdf_salt_sz;
8486
int page_sz;
@@ -325,7 +327,12 @@ int sqlcipher_codec_ctx_set_fast_kdf_iter(codec_ctx *ctx, int fast_kdf_iter, int
325327
return SQLITE_OK;
326328
}
327329

330+
/* set the global default flag for HMAC */
331+
void sqlcipher_set_default_use_hmac(int use) {
332+
default_use_hmac = use;
333+
}
328334

335+
/* set the codec flag for whether this individual database should be using hmac */
329336
int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
330337
int reserve = EVP_MAX_IV_LENGTH; /* base reserve size will be IV only */
331338

@@ -432,7 +439,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
432439

433440
/* Use HMAC signatures by default. Note that codec_set_use_hmac will implicity call
434441
codec_set_page_size to set the default */
435-
if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, DEFAULT_USE_HMAC)) != SQLITE_OK) return rc;
442+
if((rc = sqlcipher_codec_ctx_set_use_hmac(ctx, default_use_hmac)) != SQLITE_OK) return rc;
436443

437444
if((rc = sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx)) != SQLITE_OK) return rc;
438445

src/pragma.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,13 +1515,13 @@ void sqlite3Pragma(
15151515
extern int codec_set_page_size(sqlite3*, int, int);
15161516
codec_set_page_size(db, iDb, atoi(zRight)); // change page size
15171517
}else
1518+
if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
1519+
extern void codec_set_default_use_hmac(int);
1520+
codec_set_default_use_hmac(sqlite3GetBoolean(zRight));
1521+
}else
15181522
if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
15191523
extern int codec_set_use_hmac(sqlite3*, int, int);
1520-
if(sqlite3GetBoolean(zRight)) {
1521-
codec_set_use_hmac(db, iDb, 1);
1522-
} else {
1523-
codec_set_use_hmac(db, iDb, 0);
1524-
}
1524+
codec_set_use_hmac(db, iDb, sqlite3GetBoolean(zRight));
15251525
}else
15261526
/** END CRYPTO **/
15271527
#endif

test/crypto.test

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,4 +1145,64 @@ do_test cipher-options-before-keys {
11451145
db close
11461146
file delete -force test.db
11471147

1148+
# open a 1.1.8 database (no HMAC), then
1149+
# try to open another 1.1.8 database. The
1150+
# attached database should have the same hmac
1151+
# setting as the original
1152+
do_test default-use-hmac-attach {
1153+
file copy -force sqlcipher-1.1.8-testkey.db test.db
1154+
sqlite_orig db test.db
1155+
execsql {
1156+
PRAGMA cipher_default_use_hmac = OFF;
1157+
PRAGMA key = 'testkey';
1158+
SELECT count(*) FROM t1;
1159+
ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
1160+
SELECT count(*) from db2.t1;
1161+
PRAGMA cipher_default_use_hmac = ON;
1162+
}
1163+
} {4 4}
1164+
db close
1165+
file delete -force test.db
1166+
1167+
# open a 2.0 database (with HMAC), then
1168+
# try to a 1.1.8 database. this should
1169+
# fail because the hmac setting for the
1170+
# attached database is not compatible
1171+
do_test attach-1.1.8-database-from-2.0-fails {
1172+
sqlite_orig db test.db
1173+
catchsql {
1174+
PRAGMA key = 'testkey';
1175+
CREATE table t1(a,b);
1176+
ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
1177+
}
1178+
} {1 {file is encrypted or is not a database}}
1179+
db close
1180+
file delete -force test.db
1181+
1182+
# open a 2.0 database (with HMAC), then
1183+
# set the default hmac setting to OFF.
1184+
# try to a 1.1.8 database. this should
1185+
# succeed now that hmac is off by default
1186+
# before the attach
1187+
do_test change-default-use-hmac-attach {
1188+
sqlite_orig db test.db
1189+
execsql {
1190+
PRAGMA key = 'testkey';
1191+
CREATE table t1(a,b);
1192+
INSERT INTO t1(a,b) VALUES (1,2);
1193+
}
1194+
db close
1195+
sqlite_orig db test.db
1196+
execsql {
1197+
PRAGMA key = 'testkey';
1198+
SELECT count(*) FROM t1;
1199+
PRAGMA cipher_default_use_hmac = OFF;
1200+
ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2;
1201+
SELECT count(*) from db2.t1;
1202+
PRAGMA cipher_default_use_hmac = ON;
1203+
}
1204+
} {1 4}
1205+
db close
1206+
file delete -force test.db
1207+
11481208
finish_test

0 commit comments

Comments
 (0)