From 9b13d75ab59ca018c3c95b860ec5de15aa5df736 Mon Sep 17 00:00:00 2001 From: lidw Date: Thu, 18 Aug 2022 21:54:45 +0800 Subject: [PATCH 1/2] Add pragma hmac algorithm. Signed-off-by: lidwchn --- src/sqlite3.c | 115 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 23 deletions(-) diff --git a/src/sqlite3.c b/src/sqlite3.c index 127d868..f9e0469 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -88571,7 +88571,7 @@ case OP_ResultRow: { assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 || CORRUPT_DB ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - + #ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION if( p->pSharedBlock!=NULL ){ void *pCtx = p->pSharedBlock->pContext; @@ -238190,6 +238190,7 @@ typedef struct{ int initVectorSize; int hmacSize; int reserveSize; + int hmacAlgo; }CodecConstant; typedef struct{ @@ -238290,8 +238291,28 @@ CODEC_STATIC int opensslGetInitVectorSize(void *cipher){ return EVP_CIPHER_iv_length((EVP_CIPHER *)cipher); } -CODEC_STATIC int opensslGetHmacSize(void *cipher){ - return EVP_MD_size(EVP_sha1()); +#define CIPHER_HMAC_ALGORITHM_SHA1 0 +#define CIPHER_HMAC_ALGORITHM_SHA256 1 +#define CIPHER_HMAC_ALGORITHM_SHA512 2 + +#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" + +CODEC_STATIC int opensslGetHmacSize(KeyContext *keyCtx){ + if (keyCtx == NULL){ + return 0; + } + if(keyCtx->codecConst.hmacAlgo == CIPHER_HMAC_ALGORITHM_SHA1){ + 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; } CODEC_STATIC int opensslGetBlockSize(void *cipher){ @@ -238328,12 +238349,19 @@ CODEC_STATIC void opensslFreeCtx(void *ctx){ EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)ctx); } -CODEC_STATIC int opensslHmac(Buffer *key, Buffer *input1, Buffer *input2, Buffer *output){ +CODEC_STATIC int opensslHmac(Buffer *key, Buffer *input1, Buffer *input2, Buffer *output, int hmacAlgo){ HMAC_CTX *ctx = HMAC_CTX_new(); if(ctx == NULL){ return SQLITE_ERROR; } - HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha1(), NULL); + + if(hmacAlgo == CIPHER_HMAC_ALGORITHM_SHA1){ + 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); HMAC_Final(ctx, output->buffer, (unsigned int *)(&output->bufferSize)); @@ -238342,9 +238370,17 @@ 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){ - PKCS5_PBKDF2_HMAC_SHA1((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, - workfactor, key->bufferSize, key->buffer); +CODEC_STATIC void opensslKdf(Buffer *password, Buffer *salt, int workfactor, Buffer *key, int hmacAlgo){ + if(hmacAlgo == CIPHER_HMAC_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){ + PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, + workfactor, EVP_sha256(), key->bufferSize, key->buffer); + }else if(hmacAlgo == CIPHER_HMAC_ALGORITHM_SHA512){ + PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize, + workfactor, EVP_sha512(), key->bufferSize, key->buffer); + } } /************** End file hw_codec_openssl.c *********************************/ @@ -238578,7 +238614,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); + opensslKdf(&password, &salt, keyCtx->iter, &key, keyCtx->codecConst.hmacAlgo); keyCtx->keyInfo[0] = 'x'; keyCtx->keyInfo[1] = '\''; sqlite3CodecBin2Hex(keyCtx->key, keyCtx->codecConst.keySize, keyCtx->keyInfo + 2); @@ -238598,7 +238634,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); + opensslKdf(&hmacPassword, &hmacSalt, HMAC_ITER, &hmacKey, keyCtx->codecConst.hmacAlgo); keyCtx->deriveFlag = 1; if(sqlite3CodecKeyCtxCmp(keyCtx, secondKeyCtx)){ sqlite3CodecClearDeriveKey(secondKeyCtx); @@ -238635,18 +238671,6 @@ CODEC_STATIC int sqlite3CodecSetCodecConstant(KeyContext *keyCtx, const char *ci keyCtx->codecConst.keySize = opensslGetKeySize(keyCtx->codecConst.cipher); keyCtx->codecConst.keyInfoSize = (keyCtx->codecConst.keySize + SALT_SIZE) * 2 + 3; keyCtx->codecConst.initVectorSize = opensslGetInitVectorSize(keyCtx->codecConst.cipher); - keyCtx->codecConst.hmacSize = opensslGetHmacSize(keyCtx->codecConst.cipher); - int cipherBlockSize = opensslGetBlockSize(keyCtx->codecConst.cipher); - int blockSize = cipherBlockSize; - while(blockSize < MIN_BLOCK_SIZE){ - blockSize += cipherBlockSize; - } - int reserveSize = MAX_INIT_VECTOR_SIZE + keyCtx->codecConst.hmacSize; - if(reserveSize % blockSize == 0){ - keyCtx->codecConst.reserveSize = reserveSize; - }else{ - keyCtx->codecConst.reserveSize = (reserveSize / blockSize + 1) * blockSize; - } return SQLITE_OK; } @@ -238733,6 +238757,24 @@ CODEC_STATIC int sqlite3CodecSetPassword(KeyContext *keyCtx, const void *zKey, i return SQLITE_OK; } +// You should clear key derive infos and password infos before you call this function +CODEC_STATIC int sqlite3CodecSetHmacAlgorithm(KeyContext *keyCtx, int hmacAlgo){ + keyCtx->codecConst.hmacAlgo = hmacAlgo; + keyCtx->codecConst.hmacSize = opensslGetHmacSize(keyCtx); + int cipherBlockSize = opensslGetBlockSize(keyCtx->codecConst.cipher); + int blockSize = cipherBlockSize; + while(blockSize < MIN_BLOCK_SIZE){ + blockSize += cipherBlockSize; + } + int reserveSize = MAX_INIT_VECTOR_SIZE + keyCtx->codecConst.hmacSize; + if(reserveSize % blockSize == 0){ + keyCtx->codecConst.reserveSize = reserveSize; + }else{ + keyCtx->codecConst.reserveSize = (reserveSize / blockSize + 1) * blockSize; + } + 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); @@ -238773,6 +238815,7 @@ CODEC_STATIC int sqlite3CodecInitKeyContext(KeyContext *keyCtx, const void *zKey rc = sqlite3CodecSetCodecConstant(keyCtx, DEFAULT_CIPHER); rc += sqlite3CodecSetIter(keyCtx, DEFAULT_ITER); #endif + rc += sqlite3CodecSetHmacAlgorithm(keyCtx, DEFAULT_HMAC_ALGORITHM); rc += sqlite3CodecSetPassword(keyCtx, zKey, nKey); if(rc != SQLITE_OK){ sqlite3CodecFreeKeyContext(keyCtx); @@ -238890,7 +238933,7 @@ CODEC_STATIC int sqlite3CodecHmac(KeyContext *ctx, Pgno pgno, int bufferSize, un Buffer outputBuffer; outputBuffer.buffer = output; outputBuffer.bufferSize = 0; - int rc = opensslHmac(&key, &input1, &input2, &outputBuffer); + int rc = opensslHmac(&key, &input1, &input2, &outputBuffer, ctx->codecConst.hmacAlgo); if(rc != SQLITE_OK || outputBuffer.bufferSize != ctx->codecConst.hmacSize){ return SQLITE_ERROR; } @@ -239026,6 +239069,7 @@ CODEC_STATIC int sqlite3CodecDecryptData(CodecContext *ctx, OperateContext which void* sqlite3Codec(void *ctx, void *data, Pgno pgno, int mode){ CodecContext *pCtx = (CodecContext *)ctx; unsigned char *pData = (unsigned char *)data; + int offset = 0; int rc = SQLITE_OK; errno_t memcpyRc = EOK; @@ -239270,6 +239314,7 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co if(zRight){ sqlite3_mutex_enter(db->mutex); (void)sqlite3CodecSetCodecConstant(ctx->readCtx, zRight); + (void)sqlite3CodecSetHmacAlgorithm(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); @@ -239288,6 +239333,30 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co sqlite3_free(iter); } } + }else if(sqlite3StrICmp(zLeft, "codec_hmac_algo") == 0){ + if(zRight){ + 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); + }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); + }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); + }else{ + return 0; + } + sqlite3BtreeSetPageSize(p, DEFAULT_PAGE_SIZE, ctx->readCtx->codecConst.reserveSize, 0); + }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{ return 0; } -- Gitee From 595f95f061e917e06b30e8794d96d91f3b136889 Mon Sep 17 00:00:00 2001 From: lidwchn Date: Thu, 25 Aug 2022 11:27:21 +0800 Subject: [PATCH 2/2] Fix issue. Signed-off-by: lidwchn --- src/sqlite3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sqlite3.c b/src/sqlite3.c index f9e0469..11bb39b 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -239335,6 +239335,7 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co } }else if(sqlite3StrICmp(zLeft, "codec_hmac_algo") == 0){ 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); @@ -239345,9 +239346,11 @@ int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, co (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA512); (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA512); }else{ + sqlite3_mutex_leave(db->mutex); return 0; } sqlite3BtreeSetPageSize(p, DEFAULT_PAGE_SIZE, 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); -- Gitee