Skip to content

Commit a80065d

Browse files
committed
Fix SQLCipher incompatibility
Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour.
1 parent 8d84f87 commit a80065d

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour.
13+
1014
## [1.8.7] - 2024-08-14
1115

1216
### Changed

src/cipher_sqlcipher.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#define SQLCIPHER_HMAC_ALGORITHM_SHA256 1
4040
#define SQLCIPHER_HMAC_ALGORITHM_SHA512 2
4141

42+
#define SQLCIPHER_HMAC_ALGO_COMPAT 1
43+
4244
#define SQLCIPHER_VERSION_1 1
4345
#define SQLCIPHER_VERSION_2 2
4446
#define SQLCIPHER_VERSION_3 3
@@ -78,6 +80,7 @@ SQLITE_PRIVATE CipherParams mcSQLCipherParams[] =
7880
{ "hmac_salt_mask", SQLCIPHER_HMAC_SALT_MASK, SQLCIPHER_HMAC_SALT_MASK, 0x00, 0xff },
7981
{ "kdf_algorithm", SQLCIPHER_KDF_ALGORITHM, SQLCIPHER_KDF_ALGORITHM, 0, 2 },
8082
{ "hmac_algorithm", SQLCIPHER_HMAC_ALGORITHM, SQLCIPHER_HMAC_ALGORITHM, 0, 2 },
83+
{ "hmac_algorithm_compat", SQLCIPHER_HMAC_ALGO_COMPAT, SQLCIPHER_HMAC_ALGO_COMPAT, 0, 1 },
8184
{ "plaintext_header_size", 0, 0, 0, 100 /* restrict to db header size */ },
8285
CIPHER_PARAMS_SENTINEL
8386
};
@@ -98,6 +101,7 @@ typedef struct _sqlCipherCipher
98101
int m_hmacSaltMask;
99102
int m_kdfAlgorithm;
100103
int m_hmacAlgorithm;
104+
int m_hmacAlgorithmCompat;
101105
int m_plaintextHeaderSize;
102106
int m_keyLength;
103107
uint8_t m_key[KEYLENGTH_SQLCIPHER];
@@ -139,6 +143,7 @@ AllocateSQLCipherCipher(sqlite3* db)
139143
sqlCipherCipher->m_hmacSaltMask = sqlite3mcGetCipherParameter(cipherParams, "hmac_salt_mask");
140144
sqlCipherCipher->m_kdfAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "kdf_algorithm");
141145
sqlCipherCipher->m_hmacAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm");
146+
sqlCipherCipher->m_hmacAlgorithmCompat = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm_compat");
142147
if (sqlCipherCipher->m_legacy >= SQLCIPHER_VERSION_4)
143148
{
144149
int plaintextHeaderSize = sqlite3mcGetCipherParameter(cipherParams, "plaintext_header_size");
@@ -176,6 +181,7 @@ CloneSQLCipherCipher(void* cipherTo, void* cipherFrom)
176181
sqlCipherCipherTo->m_hmacSaltMask = sqlCipherCipherFrom->m_hmacSaltMask;
177182
sqlCipherCipherTo->m_kdfAlgorithm = sqlCipherCipherFrom->m_kdfAlgorithm;
178183
sqlCipherCipherTo->m_hmacAlgorithm = sqlCipherCipherFrom->m_hmacAlgorithm;
184+
sqlCipherCipherTo->m_hmacAlgorithmCompat = sqlCipherCipherFrom->m_hmacAlgorithmCompat;
179185
sqlCipherCipherTo->m_plaintextHeaderSize = sqlCipherCipherFrom->m_plaintextHeaderSize;
180186
sqlCipherCipherTo->m_keyLength = sqlCipherCipherFrom->m_keyLength;
181187
memcpy(sqlCipherCipherTo->m_key, sqlCipherCipherFrom->m_key, KEYLENGTH_SQLCIPHER);
@@ -296,27 +302,31 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int
296302
if (sqlCipherCipher->m_hmacUse != 0)
297303
{
298304
int j;
305+
int algorithm = (sqlCipherCipher->m_hmacAlgorithmCompat) ? sqlCipherCipher->m_kdfAlgorithm : sqlCipherCipher->m_hmacAlgorithm;
299306
unsigned char hmacSaltMask = sqlCipherCipher->m_hmacSaltMask;
300307
unsigned char hmacSalt[SALTLENGTH_SQLCIPHER];
301308
memcpy(hmacSalt, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER);
302309
for (j = 0; j < SALTLENGTH_SQLCIPHER; ++j)
303310
{
304311
hmacSalt[j] ^= hmacSaltMask;
305312
}
306-
switch (sqlCipherCipher->m_hmacAlgorithm)
313+
switch (algorithm)
307314
{
315+
case SQLCIPHER_KDF_ALGORITHM_SHA1:
308316
case SQLCIPHER_HMAC_ALGORITHM_SHA1:
309317
fastpbkdf2_hmac_sha1(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER,
310318
hmacSalt, SALTLENGTH_SQLCIPHER,
311319
sqlCipherCipher->m_fastKdfIter,
312320
sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER);
313321
break;
322+
case SQLCIPHER_KDF_ALGORITHM_SHA256:
314323
case SQLCIPHER_HMAC_ALGORITHM_SHA256:
315324
fastpbkdf2_hmac_sha256(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER,
316325
hmacSalt, SALTLENGTH_SQLCIPHER,
317326
sqlCipherCipher->m_fastKdfIter,
318327
sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER);
319328
break;
329+
case SQLCIPHER_KDF_ALGORITHM_SHA512:
320330
case SQLCIPHER_HMAC_ALGORITHM_SHA512:
321331
default:
322332
fastpbkdf2_hmac_sha512(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER,

0 commit comments

Comments
 (0)