diff --git a/src/sqlite3.c b/src/sqlite3.c index 3d089e5147297d2c4929159d7e2ede2600b01aca..a723eac2aa1d2cb9fb029b07e23846414e9ae8c6 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -244640,10 +244640,12 @@ typedef struct{ void *cipher; int keySize; int keyInfoSize; + int cipherPageSize; int initVectorSize; int hmacSize; int reserveSize; int hmacAlgo; + int kdfAlgo; int rekeyHmacAlgo; }CodecConstant; @@ -244747,11 +244749,24 @@ CODEC_STATIC int opensslGetInitVectorSize(void *cipher){ #define CIPHER_HMAC_ALGORITHM_SHA1 1 #define CIPHER_HMAC_ALGORITHM_SHA256 2 +#define CIPHER_HMAC_ALGORITHM_SHA512 3 #define DEFAULT_HMAC_ALGORITHM CIPHER_HMAC_ALGORITHM_SHA1 #define CIPHER_HMAC_ALGORITHM_NAME_SHA1 "SHA1" #define CIPHER_HMAC_ALGORITHM_NAME_SHA256 "SHA256" +#define CIPHER_HMAC_ALGORITHM_NAME_SHA512 "SHA512" + +#define CIPHER_KDF_ALGORITHM_SHA1 1 +#define CIPHER_KDF_ALGORITHM_SHA256 2 +#define CIPHER_KDF_ALGORITHM_SHA512 3 + +#define DEFAULT_KDF_ALGORITHM CIPHER_KDF_ALGORITHM_SHA1 + +#define CIPHER_KDF_ALGORITHM_NAME_SHA1 "KDF_SHA1" +#define CIPHER_KDF_ALGORITHM_NAME_SHA256 "KDF_SHA256" +#define CIPHER_KDF_ALGORITHM_NAME_SHA512 "KDF_SHA512" + CODEC_STATIC int opensslGetHmacSize(KeyContext *keyCtx){ if( keyCtx==NULL ){ @@ -244761,6 +244776,8 @@ CODEC_STATIC int opensslGetHmacSize(KeyContext *keyCtx){ return EVP_MD_size(EVP_sha1()); }else if( keyCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){ return EVP_MD_size(EVP_sha256()); + }else if( keyCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){ + return EVP_MD_size(EVP_sha512()); } return 0; } @@ -244808,6 +244825,8 @@ CODEC_STATIC int opensslHmac(Buffer *key, Buffer *input1, Buffer *input2, Buffer HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha1(), NULL); }else if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){ HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha256(), NULL); + }else if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){ + HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha512(), NULL); } HMAC_Update(ctx, input1->buffer, input1->bufferSize); HMAC_Update(ctx, input2->buffer, input2->bufferSize); @@ -244817,13 +244836,16 @@ CODEC_STATIC int opensslHmac(Buffer *key, Buffer *input1, Buffer *input2, Buffer return SQLITE_OK; } -CODEC_STATIC void opensslKdf(Buffer *password, Buffer *salt, int workfactor, Buffer *key, int hmacAlgo){ - if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){ +CODEC_STATIC void opensslKdf(Buffer *password, Buffer *salt, int workfactor, Buffer *key, int kdfAlgo){ + if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA1 ){ PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, workfactor, EVP_sha1(), key->bufferSize, key->buffer); - }else if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){ + }else if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA256 ){ PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, workfactor, EVP_sha256(), key->bufferSize, key->buffer); + }else if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA512 ){ + PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, + workfactor, EVP_sha512(), key->bufferSize, key->buffer); } } @@ -245068,7 +245090,7 @@ CODEC_STATIC int sqlite3CodecDeriveKey(CodecContext *ctx, OperateContext whichKe salt.bufferSize = SALT_SIZE; key.buffer = keyCtx->key; key.bufferSize = keyCtx->codecConst.keySize; - opensslKdf(&password, &salt, keyCtx->iter, &key, keyCtx->codecConst.hmacAlgo); + opensslKdf(&password, &salt, keyCtx->iter, &key, keyCtx->codecConst.kdfAlgo); keyCtx->keyInfo[0] = 'x'; keyCtx->keyInfo[1] = '\''; sqlite3CodecBin2Hex(keyCtx->key, keyCtx->codecConst.keySize, keyCtx->keyInfo + 2); @@ -245088,7 +245110,7 @@ CODEC_STATIC int sqlite3CodecDeriveKey(CodecContext *ctx, OperateContext whichKe hmacSalt.bufferSize = SALT_SIZE; hmacKey.buffer = keyCtx->hmacKey; hmacKey.bufferSize = keyCtx->codecConst.keySize; - opensslKdf(&hmacPassword, &hmacSalt, HMAC_ITER, &hmacKey, keyCtx->codecConst.hmacAlgo); + opensslKdf(&hmacPassword, &hmacSalt, HMAC_ITER, &hmacKey, keyCtx->codecConst.kdfAlgo); keyCtx->deriveFlag = 1; if(sqlite3CodecKeyCtxCmp(keyCtx, secondKeyCtx)){ sqlite3CodecClearDeriveKey(secondKeyCtx); @@ -245146,6 +245168,8 @@ CODEC_STATIC int sqlite3CodecSetIter(KeyContext *keyCtx, int iter){ static int g_defaultAttachKdfIter = 10000; static int g_defaultAttachCipher = CIPHER_ID_AES_256_GCM; static int g_defaultAttachHmacAlgo = DEFAULT_HMAC_ALGORITHM; +static int g_defaultAttachKdfAlgo = DEFAULT_KDF_ALGORITHM; +static int g_defaultAttachPageSize = DEFAULT_PAGE_SIZE; struct CodecCipherNameId { int cipherId; @@ -245209,6 +245233,32 @@ CODEC_STATIC int sqlite3CodecGetDefaultAttachHmacAlgo(){ return hmacAlgo; } +CODEC_STATIC void sqlite3CodecSetDefaultAttachKdfAlgo(int kdfAlgo){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + g_defaultAttachKdfAlgo = kdfAlgo; + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +CODEC_STATIC int sqlite3CodecGetDefaultAttachKdfAlgo(){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + int kdfAlgo = g_defaultAttachKdfAlgo; + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + return kdfAlgo; +} + +CODEC_STATIC void sqlite3CodecSetDefaultAttachPageSize(int pageSize){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + g_defaultAttachPageSize = pageSize; + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); +} + +CODEC_STATIC int sqlite3CodecGetDefaultAttachPageSize(){ + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + int pageSize = g_defaultAttachPageSize; + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + return pageSize; +} + #endif // You should clear key derive infos and password infos before you call this function @@ -245244,6 +245294,30 @@ CODEC_STATIC int sqlite3CodecSetHmacAlgorithm(KeyContext *keyCtx, int hmacAlgo){ return SQLITE_OK; } +CODEC_STATIC int sqlite3CodecSetKdfAlgorithm(KeyContext *keyCtx, int kdfAlgo){ + keyCtx->codecConst.kdfAlgo = kdfAlgo; + return SQLITE_OK; +} + +CODEC_STATIC int sqlite3CodecSetCipherPageSize(CodecContext *ctx, int size){ + if(!((size != 0) && ((size & (size - 1)) == 0)) || size < 512 || size > 65536) { + sqlite3_log(SQLITE_ERROR, "codec: cipher_page_size not a power of 2 and between 512 and 65536 inclusive(%d).", size); + return SQLITE_ERROR; + } + int cipherPageSize = ctx->readCtx->codecConst.cipherPageSize; + (void)memset_s(ctx->buffer, cipherPageSize, 0, cipherPageSize); + sqlite3_free(ctx->buffer); + ctx->readCtx->codecConst.cipherPageSize = size; + ctx->writeCtx->codecConst.cipherPageSize = size; + + ctx->buffer = (unsigned char *)sqlite3Malloc(size); + if (ctx->buffer == NULL) { + sqlite3_log(SQLITE_NOMEM, "codec: alloc mem failed when set cipher page size(%d).", size); + return SQLITE_NOMEM; + } + return SQLITE_OK; +} + // You should clear output before you call this function CODEC_STATIC int sqlite3CodecCopyKeyContext(KeyContext *input, KeyContext *output){ errno_t rc = memcpy_s(output, sizeof(KeyContext), input, KEY_CONTEXT_HEAD_SIZE); @@ -245267,12 +245341,13 @@ CODEC_STATIC int sqlite3CodecCopyKeyContext(KeyContext *input, KeyContext *outpu // You should clear key context before you call this function #ifdef SQLITE_CODEC_ATTACH_CHANGED -CODEC_STATIC int sqlite3CodecInitKeyContext(KeyContext *keyCtx, const void *zKey, int nKey, int attachFlag, +CODEC_STATIC int sqlite3CodecInitKeyContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey, int attachFlag, int hmacAlgo){ #else -CODEC_STATIC int sqlite3CodecInitKeyContext(KeyContext *keyCtx, const void *zKey, int nKey){ +CODEC_STATIC int sqlite3CodecInitKeyContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey){ #endif int rc = SQLITE_OK; + KeyContext *keyCtx = ctx->readCtx; #ifdef SQLITE_CODEC_ATTACH_CHANGED if( attachFlag!=0 ){ rc = sqlite3CodecSetCodecConstant(keyCtx, sqlite3CodecGetDefaultAttachCipher()); @@ -245280,15 +245355,30 @@ CODEC_STATIC int sqlite3CodecInitKeyContext(KeyContext *keyCtx, const void *zKey if( hmacAlgo!=0 ){ rc += sqlite3CodecSetHmacAlgorithm(keyCtx, hmacAlgo); } + int attachKdfAlgo = sqlite3CodecGetDefaultAttachKdfAlgo(); + if( attachKdfAlgo!=0 ){ + rc += sqlite3CodecSetKdfAlgorithm(keyCtx, attachKdfAlgo); + } + int cipherPageSize = sqlite3CodecGetDefaultAttachPageSize(); + if( cipherPageSize!=0 ){ + rc += sqlite3CodecSetCipherPageSize(ctx, cipherPageSize); + if ( rc != SQLITE_OK ) { + sqlite3CodecFreeKeyContext(keyCtx); + return SQLITE_ERROR; + } + rc += sqlite3BtreeSetPageSize(p, cipherPageSize, keyCtx->codecConst.reserveSize, 0); + } }else{ rc = sqlite3CodecSetCodecConstant(keyCtx, DEFAULT_CIPHER); rc += sqlite3CodecSetIter(keyCtx, DEFAULT_ITER); rc += sqlite3CodecSetHmacAlgorithm(keyCtx, DEFAULT_HMAC_ALGORITHM); + rc += sqlite3CodecSetKdfAlgorithm(keyCtx, DEFAULT_KDF_ALGORITHM); } #else rc = sqlite3CodecSetCodecConstant(keyCtx, DEFAULT_CIPHER); rc += sqlite3CodecSetIter(keyCtx, DEFAULT_ITER); rc += sqlite3CodecSetHmacAlgorithm(keyCtx, DEFAULT_HMAC_ALGORITHM); + rc += sqlite3CodecSetKdfAlgorithm(keyCtx, DEFAULT_KDF_ALGORITHM); #endif keyCtx->codecConst.rekeyHmacAlgo = DEFAULT_HMAC_ALGORITHM; rc += sqlite3CodecSetPassword(keyCtx, zKey, nKey); @@ -245302,7 +245392,8 @@ CODEC_STATIC int sqlite3CodecInitKeyContext(KeyContext *keyCtx, const void *zKey // This function will free all resources of codec context, except it self. CODEC_STATIC void sqlite3CodecFreeContext(CodecContext *ctx){ if(ctx->buffer){ - (void)memset_s(ctx->buffer, DEFAULT_PAGE_SIZE, 0, DEFAULT_PAGE_SIZE); + int cipherPageSize = ctx->readCtx->codecConst.cipherPageSize; + (void)memset_s(ctx->buffer, cipherPageSize, 0, cipherPageSize); sqlite3_free(ctx->buffer); ctx->buffer = NULL; } @@ -245342,11 +245433,13 @@ CODEC_STATIC int sqlite3CodecInitContext(CodecContext *ctx, Btree *p, const void sqlite3CodecFreeContext(ctx); return SQLITE_ERROR; } + ctx->readCtx->codecConst.cipherPageSize = DEFAULT_PAGE_SIZE; + ctx->writeCtx->codecConst.cipherPageSize = DEFAULT_PAGE_SIZE; #ifdef SQLITE_CODEC_ATTACH_CHANGED int attachHmacAlgo = sqlite3CodecGetDefaultAttachHmacAlgo(); - int rc = sqlite3CodecInitKeyContext(ctx->readCtx, zKey, nKey, attachFlag, attachHmacAlgo); + int rc = sqlite3CodecInitKeyContext(ctx, p, zKey, nKey, attachFlag, attachHmacAlgo); #else - int rc = sqlite3CodecInitKeyContext(ctx->readCtx, zKey, nKey); + int rc = sqlite3CodecInitKeyContext(ctx, p, zKey, nKey); #endif if(rc != SQLITE_OK){ sqlite3CodecFreeContext(ctx); @@ -245526,7 +245619,8 @@ CODEC_STATIC int sqlite3CodecDecryptData(CodecContext *ctx, OperateContext which inputBuffer.buffer = input; inputBuffer.bufferSize = bufferSize - keyCtx->codecConst.reserveSize; if(sqlite3CodecCheckHmac(keyCtx, pgno, inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize, input, input + inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize)){ - sqlite3_log(SQLITE_WARNING, "codec: check hmac error at page %d when decrypt data.", pgno); + sqlite3_log(SQLITE_ERROR, "codec: check hmac error at page %d, hmac %d, kdf %d, pageSize %d.", + pgno, keyCtx->codecConst.hmacAlgo, keyCtx->codecConst.kdfAlgo, keyCtx->codecConst.cipherPageSize); return SQLITE_ERROR; } unsigned char *initVector = input + inputBuffer.bufferSize; @@ -245555,33 +245649,34 @@ void* sqlite3Codec(void *ctx, void *data, Pgno pgno, int mode){ if(pgno == 1){ offset = FILE_HEADER_SIZE; } + int cipherPageSize = pCtx->readCtx->codecConst.cipherPageSize; switch(mode){ case 0: case 2: case 3: if(pgno == 1){ - memcpyRc = memcpy_s(pCtx->buffer, DEFAULT_PAGE_SIZE, SQLITE_FILE_HEADER, FILE_HEADER_SIZE); + memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, SQLITE_FILE_HEADER, FILE_HEADER_SIZE); if(memcpyRc != EOK){ sqlite3CodecSetError(pCtx, SQLITE_ERROR); return pData; } } - rc = sqlite3CodecDecryptData(pCtx, OPERATE_CONTEXT_READ, pgno, DEFAULT_PAGE_SIZE - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); + rc = sqlite3CodecDecryptData(pCtx, OPERATE_CONTEXT_READ, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); if(rc != SQLITE_OK){ sqlite3CodecSetError(pCtx, rc); } - (void)memcpy_s(pData, DEFAULT_PAGE_SIZE, pCtx->buffer, DEFAULT_PAGE_SIZE); + (void)memcpy_s(pData, cipherPageSize, pCtx->buffer, cipherPageSize); return pData; break; case 6: if(pgno == 1){ - memcpyRc = memcpy_s(pCtx->buffer, DEFAULT_PAGE_SIZE, pCtx->salt, FILE_HEADER_SIZE); + memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, pCtx->salt, FILE_HEADER_SIZE); if(memcpyRc != EOK){ sqlite3CodecSetError(pCtx, SQLITE_ERROR); return pData; } } - rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_WRITE, pgno, DEFAULT_PAGE_SIZE - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); + rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_WRITE, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); if(rc != SQLITE_OK){ sqlite3CodecSetError(pCtx, rc); return pData; @@ -245590,13 +245685,13 @@ void* sqlite3Codec(void *ctx, void *data, Pgno pgno, int mode){ break; case 7: if(pgno == 1){ - memcpyRc = memcpy_s(pCtx->buffer, DEFAULT_PAGE_SIZE, pCtx->salt, FILE_HEADER_SIZE); + memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, pCtx->salt, FILE_HEADER_SIZE); if(memcpyRc != EOK){ sqlite3CodecSetError(pCtx, SQLITE_ERROR); return pData; } } - rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_READ, pgno, DEFAULT_PAGE_SIZE - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); + rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_READ, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset); if(rc != SQLITE_OK){ sqlite3CodecSetError(pCtx, rc); return pData; @@ -245648,9 +245743,9 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ } sqlite3PagerSetCodec(sqlite3BtreePager(p), sqlite3Codec, NULL, sqlite3CodecDetach, (void *)ctx); - db->nextPagesize = DEFAULT_PAGE_SIZE; + db->nextPagesize = ctx->readCtx->codecConst.cipherPageSize; p->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; - sqlite3BtreeSetPageSize(p, DEFAULT_PAGE_SIZE, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); sqlite3BtreeSecureDelete(p, 1); if(isOpen(p->pBt->pPager->fd)){ sqlite3BtreeSetAutoVacuum(p, SQLITE_DEFAULT_AUTOVACUUM); @@ -245729,6 +245824,7 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){ int oldHmacAlgo = ctx->writeCtx->codecConst.hmacAlgo; if( ctx->writeCtx->codecConst.rekeyHmacAlgo!=ctx->writeCtx->codecConst.hmacAlgo ){ sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, ctx->writeCtx->codecConst.rekeyHmacAlgo); + sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, ctx->writeCtx->codecConst.rekeyHmacAlgo); } for(pgno = 1; pgno <= (unsigned int)pageCount; pgno++){ @@ -245753,6 +245849,7 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){ }else{ if( ctx->writeCtx->codecConst.rekeyHmacAlgo!=oldHmacAlgo ){ sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, oldHmacAlgo); + sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, oldHmacAlgo); } (void)sqlite3BtreeRollback(p, SQLITE_ABORT_ROLLBACK, 0); } @@ -245789,14 +245886,37 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co (void)sqlite3CodecSetDefaultAttachKdfIter(atoi(zRight)); return 1; }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_hmac_algo")==0 && zRight!=NULL ){ + /* + ** Make sure to set the Kdf algorithm after setting the Hmac algorithm, or it will not take effect. + ** This behavior is to ensure backward compatible. + */ if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA1)==0 ){ sqlite3CodecSetDefaultAttachHmacAlgo(CIPHER_HMAC_ALGORITHM_SHA1); + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA1); }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){ sqlite3CodecSetDefaultAttachHmacAlgo(CIPHER_HMAC_ALGORITHM_SHA256); + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA256); + }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){ + sqlite3CodecSetDefaultAttachHmacAlgo(CIPHER_HMAC_ALGORITHM_SHA512); + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA512); }else{ return 0; } return 1; + }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_kdf_algo")==0 && zRight!=NULL ){ + if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA1)==0 ){ + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA1); + }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA256)==0 ){ + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA256); + }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA512)==0 ){ + sqlite3CodecSetDefaultAttachKdfAlgo(CIPHER_KDF_ALGORITHM_SHA512); + }else{ + return 0; + } + return 1; + }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_page_size")==0 && zRight!=NULL ){ + (void)sqlite3CodecSetDefaultAttachPageSize(atoi(zRight)); + return 1; } #endif if(ctx == NULL){ @@ -245807,9 +245927,10 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co sqlite3_mutex_enter(db->mutex); (void)sqlite3CodecSetCodecConstant(ctx->readCtx, zRight); (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, ctx->readCtx->codecConst.hmacAlgo); + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, ctx->readCtx->codecConst.hmacAlgo); sqlite3CodecFreeKeyContext(ctx->writeCtx); (void)sqlite3CodecCopyKeyContext(ctx->readCtx, ctx->writeCtx); - sqlite3BtreeSetPageSize(p, DEFAULT_PAGE_SIZE, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); sqlite3_mutex_leave(db->mutex); }else{ sqlite3CodecReturnPragmaResult(parse, "codec_cipher", opensslGetCipherName(ctx->writeCtx->codecConst.cipher)); @@ -245826,25 +245947,84 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co } } }else if( sqlite3StrICmp(zLeft, "codec_hmac_algo")==0 ){ + /* + ** Make sure to set the Kdf algorithm after setting the Hmac algorithm, or it will not take effect. + ** This behavior is to ensure backward compatible. + */ if(zRight){ sqlite3_mutex_enter(db->mutex); if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA1)==0 ){ (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA1); (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA1); + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA1); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA1); }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){ (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA256); (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA256); + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA256); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA256); + }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){ + (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA512); + (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA512); + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA512); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA512); }else{ sqlite3_mutex_leave(db->mutex); return 0; } - sqlite3BtreeSetPageSize(p, DEFAULT_PAGE_SIZE, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); sqlite3_mutex_leave(db->mutex); }else{ if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){ sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA1); }else if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){ sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA256); + }else if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){ + sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA512); + } + } + }else if( sqlite3StrICmp(zLeft, "codec_kdf_algo")==0 ){ + if(zRight){ + sqlite3_mutex_enter(db->mutex); + if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA1)==0 ){ + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA1); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA1); + }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA256)==0 ){ + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA256); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA256); + }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA512)==0 ){ + (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA512); + (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA512); + }else{ + sqlite3_mutex_leave(db->mutex); + return 0; + } + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3_mutex_leave(db->mutex); + }else{ + if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA1 ){ + sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA1); + }else if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA256 ){ + sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA256); + }else if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA512 ){ + sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA512); + } + } + }else if( sqlite3StrICmp(zLeft, "codec_page_size")==0 ){ + if(zRight){ + sqlite3_mutex_enter(db->mutex); + int rc = sqlite3CodecSetCipherPageSize(ctx, atoi(zRight)); + if (rc != SQLITE_OK){ + sqlite3_mutex_leave(db->mutex); + return 0; + } + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3_mutex_leave(db->mutex); + } else { + char *pageSize = sqlite3_mprintf("%d", ctx->readCtx->codecConst.cipherPageSize); + if (pageSize != NULL) { + sqlite3CodecReturnPragmaResult(parse, "codec_page_size", pageSize); + sqlite3_free(pageSize); } } }else if(sqlite3StrICmp(zLeft, "codec_rekey_hmac_algo") == 0){ @@ -245854,6 +246034,8 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA1; }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){ ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA256; + }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){ + ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA512; }else{ sqlite3_mutex_leave(db->mutex); return 0; @@ -245864,6 +246046,8 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA1); }else if( ctx->writeCtx->codecConst.rekeyHmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){ sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA256); + }else if( ctx->writeCtx->codecConst.rekeyHmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){ + sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA512); } } }else{