diff --git a/src/bin/pg_dump/common_cipher.cpp b/src/bin/pg_dump/common_cipher.cpp index e97bc86e8..b65a41da0 100644 --- a/src/bin/pg_dump/common_cipher.cpp +++ b/src/bin/pg_dump/common_cipher.cpp @@ -51,7 +51,6 @@ typedef void (*crypto_ctx_clean_type)(void *ctx); typedef int (*crypto_digest_type)(void *sess, ModuleDigestAlgo algo, unsigned char * data, size_t data_size,unsigned char *result, size_t *result_size); typedef int (*crypto_hmac_init_type)(void *sess, void **ctx, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t key_id_size); typedef void (*crypto_hmac_clean_type)(void *ctx); -typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size); typedef int (*crypto_gen_random_type)(void *sess, char *buffer, size_t size); typedef int (*crypto_deterministic_enc_dec_type)(void *sess, int enc, unsigned char *data, unsigned char *key_id, size_t key_id_size, size_t data_size, unsigned char *result, size_t *result_size); typedef int (*crypto_get_errmsg_type)(void *sess, char *errmsg); @@ -69,7 +68,7 @@ crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use = NULL; static crypto_digest_type crypto_digest_use = NULL; static crypto_hmac_init_type crypto_hmac_init_use = NULL; static crypto_hmac_clean_type crypto_hmac_clean_use = NULL; -static crypto_hmac_type crypto_hmac_use = NULL; +crypto_hmac_type crypto_hmac_use = NULL; static crypto_gen_random_type crypto_gen_random_use = NULL; static crypto_deterministic_enc_dec_type crypto_deterministic_enc_dec_use = NULL; static crypto_get_errmsg_type crypto_get_errmsg_use = NULL; @@ -137,7 +136,7 @@ void unload_crypto_module(int code, void* args) } -static int transform_type(char* type) +static ModuleSymmKeyAlgo transform_type(char* type) { if (strcmp(type, "AES128_CBC") == 0) { return MODULE_AES_128_CBC; @@ -157,7 +156,7 @@ static int transform_type(char* type) return MODULE_SM4_CTR; } - return -1; + return MODULE_ALGO_MAX; } @@ -249,6 +248,57 @@ void symmEncDec(ArchiveHandle* AH, bool isEnc, char* indata, int inlen, char* ou ret = crypto_encrypt_decrypt_use(AH->publicArc.cryptoModlueCtx.key_ctx, isEnc, (unsigned char*)indata, inlen, AH->publicArc.rand, 16, (unsigned char*)outdata, (size_t*)outlen, NULL); if (ret != 1) { crypto_get_errmsg_use(NULL, errmsg); + releaseHmacCtx(0, AH); + releaseCryptoCtx(0, AH); + releaseCryptoSession(0, AH); + unload_crypto_module(0, NULL); + exit_horribly(NULL, "%s\n", errmsg); + } +} + +static ModuleSymmKeyAlgo getHmacType(ModuleSymmKeyAlgo symmAlgoType) +{ + if (symmAlgoType >= MODULE_AES_128_CBC && symmAlgoType <= MODULE_AES_256_GCM) { + return MODULE_HMAC_SHA256; + } else if (symmAlgoType == MODULE_SM4_CBC || symmAlgoType == MODULE_SM4_CTR){ + return MODULE_HMAC_SM3; + } + + return MODULE_ALGO_MAX; +} + +void initHmacCtx(ArchiveHandle* AH) +{ + int ret = 1; + Archive* fort = (Archive*)AH; + char errmsg[MAX_ERRMSG_LEN] = {0}; + + ret = crypto_hmac_init_use(fort->cryptoModlueCtx.moduleSession, &(fort->cryptoModlueCtx.hmac_ctx), getHmacType(transform_type(fort->crypto_type)), fort->Key, fort->keylen); + if (ret != 1) { + crypto_get_errmsg_use(NULL, errmsg); + crypto_module_sess_exit_use(fort->cryptoModlueCtx.moduleSession); + exit_horribly(NULL, "%s\n", errmsg); + } + +} + +void releaseHmacCtx(int code, void* args) +{ + if (libhandle && ((ArchiveHandle*)args)->publicArc.cryptoModlueCtx.hmac_ctx) { + crypto_hmac_clean_use(((ArchiveHandle*)args)->publicArc.cryptoModlueCtx.hmac_ctx); + ((ArchiveHandle*)args)->publicArc.cryptoModlueCtx.hmac_ctx = NULL; + } +} + +void cryptoHmac(ArchiveHandle* AH, char* indata, int inlen, char* outdata, int* outlen) +{ + int ret = 1; + char errmsg[MAX_ERRMSG_LEN] = {0}; + + ret = crypto_hmac_use(AH->publicArc.cryptoModlueCtx.hmac_ctx, (unsigned char*)indata, inlen, (unsigned char*)outdata, (size_t*)outlen); + if (ret != 1) { + crypto_get_errmsg_use(NULL, errmsg); + releaseHmacCtx(0, AH); releaseCryptoCtx(0, AH); releaseCryptoSession(0, AH); unload_crypto_module(0, NULL); @@ -311,6 +361,7 @@ void CryptoModuleParamsCheck(ArchiveHandle* AH, const char* params, const char* } initCryptoKeyCtx((ArchiveHandle*)fout); + initHmacCtx((ArchiveHandle*)fout); fout->encryptfile = true; diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index 94956c384..2d3bf5d4b 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -65,6 +65,7 @@ typedef enum _teSection { typedef struct { void *moduleSession; void *key_ctx; + void *hmac_ctx; }CryptoModuleCtx; /* diff --git a/src/bin/pg_dump/pg_backup_archiver.cpp b/src/bin/pg_dump/pg_backup_archiver.cpp index f762fbf3b..103f5bb43 100644 --- a/src/bin/pg_dump/pg_backup_archiver.cpp +++ b/src/bin/pg_dump/pg_backup_archiver.cpp @@ -1733,7 +1733,9 @@ int ahwrite(const void* ptr, size_t size, size_t nmemb, ArchiveHandle* AH) AH->publicArc.Key, AH->publicArc.rand, AH->publicArc.cryptoModlueCtx.key_ctx, - crypto_encrypt_decrypt_use); + crypto_encrypt_decrypt_use, + AH->publicArc.cryptoModlueCtx.hmac_ctx, + crypto_hmac_use); if (!encrypt_result) exit_horribly(modulename, "Encryption failed: %s\n", strerror(errno)); } else { @@ -3727,6 +3729,7 @@ void on_exit_close_archive(Archive* AHX) { shutdown_info.AHX = AHX; on_exit_nicely(archive_close_connection, &shutdown_info); + on_exit_nicely(releaseHmacCtx, AHX); on_exit_nicely(releaseCryptoCtx, AHX); on_exit_nicely(releaseCryptoSession, AHX); on_exit_nicely(unload_crypto_module, NULL); diff --git a/src/bin/pg_dump/pg_backup_cipher.h b/src/bin/pg_dump/pg_backup_cipher.h index 089cdaa2d..4b165713e 100644 --- a/src/bin/pg_dump/pg_backup_cipher.h +++ b/src/bin/pg_dump/pg_backup_cipher.h @@ -14,10 +14,15 @@ extern "C" { #define MAX_CRYPTO_CACHE_LEN 8192 #define CRYPTO_BLOCK_SIZE 16 -#define MAX_WRITE_CACHE_LEN (MAX_CRYPTO_CACHE_LEN - CRYPTO_BLOCK_SIZE) /*加密算法补pad模式为强补,最多可以补16字节,所以写缓存少16字节,则密文最长8192、保证读取时可以整块密文读入*/ +#define CRYPTO_HMAC_SIZE 32 +/*加密算法补pad模式为强补,最多可以补16字节,所以写缓存少16字节,又因为要带上hmac,需要再少32字节,这样能保证密文最长8192、读取时可以整块密文读入*/ +#define MAX_WRITE_CACHE_LEN (MAX_CRYPTO_CACHE_LEN - CRYPTO_BLOCK_SIZE - CRYPTO_HMAC_SIZE) typedef int (*crypto_encrypt_decrypt_type)(void *ctx, int enc, unsigned char *data, size_t data_size, unsigned char *iv, size_t iv_size, unsigned char *result, size_t *result_size, unsigned char *tag); +typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size); + extern crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use; +extern crypto_hmac_type crypto_hmac_use; extern bool load_crypto_module_lib(); extern void unload_crypto_module(int code, void* args); @@ -28,6 +33,9 @@ extern void initCryptoKeyCtx(ArchiveHandle* AH); extern void releaseCryptoCtx(int code, void* args); extern void symmEncDec(ArchiveHandle* AH, bool isEnc, char* indata, int inlen, char* outdata, int* outlen); extern void symmGenerateKey(ArchiveHandle* AH); +extern void initHmacCtx(ArchiveHandle* AH); +extern void releaseHmacCtx(int code, void* args); +extern void cryptoHmac(ArchiveHandle* AH, char* indata, int inlen, char* outdata, int* outlen); extern void CryptoModuleParamsCheck(ArchiveHandle* AH, const char* params, const char* module_encrypt_mode, const char* module_encrypt_key, const char* module_encrypt_salt, bool is_gen_key); #ifdef __cplusplus diff --git a/src/bin/pg_dump/pg_backup_directory.cpp b/src/bin/pg_dump/pg_backup_directory.cpp index b71ac8169..f0d998684 100644 --- a/src/bin/pg_dump/pg_backup_directory.cpp +++ b/src/bin/pg_dump/pg_backup_directory.cpp @@ -803,8 +803,18 @@ static void encryptAndFlushCache(ArchiveHandle* AH, DFormatCryptoCache* cryptoCa { char flushData[MAX_CRYPTO_CACHE_LEN] = {0}; int flushLen = MAX_CRYPTO_CACHE_LEN; + int hmacLen = 0; - symmEncDec(AH, true, cryptoCache->cryptoCache.wrCryptoCache.writeCache, cryptoCache->cryptoCache.wrCryptoCache.writeCacheLen, flushData, &flushLen); + /*计算明文hmac,填充到密文头*/ + cryptoHmac(AH, cryptoCache->cryptoCache.wrCryptoCache.writeCache, cryptoCache->cryptoCache.wrCryptoCache.writeCacheLen, flushData, &hmacLen); + + /*去掉填充hmac的长度作为输入*/ + flushLen = MAX_CRYPTO_CACHE_LEN - hmacLen; + + symmEncDec(AH, true, cryptoCache->cryptoCache.wrCryptoCache.writeCache, cryptoCache->cryptoCache.wrCryptoCache.writeCacheLen, flushData + hmacLen, &flushLen); + + /*输出密文长度再加上hmac的长度作为最终刷盘长度*/ + flushLen += hmacLen; cfwrite(flushData, flushLen, FH); } @@ -829,12 +839,24 @@ static void fillReadCryptoCache(ArchiveHandle* AH, DFormatCryptoCache* cryptoCac char encData[MAX_CRYPTO_CACHE_LEN] = {0}; int encLen = 0; - /*先读取文件密文,然后解密写入缓存,这里先直接放缓存*/ + /*先读取文件密文,然后解密写入缓存*/ encLen = cfread(encData, MAX_CRYPTO_CACHE_LEN, FH); - if (encLen > 0) { - cryptoCache->cryptoCache.rCryptoCache.readCacheLen = encLen; - symmEncDec(AH, false, encData, encLen, cryptoCache->cryptoCache.rCryptoCache.readCache, &(cryptoCache->cryptoCache.rCryptoCache.readCacheLen)); + if (encLen >= (CRYPTO_BLOCK_SIZE + CRYPTO_HMAC_SIZE)) { + char hmac[CRYPTO_HMAC_SIZE + 1] = {0}; + int hmacLen = 0; + + cryptoCache->cryptoCache.rCryptoCache.readCacheLen = encLen - CRYPTO_HMAC_SIZE; + symmEncDec(AH, false, encData + CRYPTO_HMAC_SIZE, encLen - CRYPTO_HMAC_SIZE, cryptoCache->cryptoCache.rCryptoCache.readCache, &(cryptoCache->cryptoCache.rCryptoCache.readCacheLen)); + + /*对明文做hmac进行校验*/ + cryptoHmac(AH, cryptoCache->cryptoCache.rCryptoCache.readCache, cryptoCache->cryptoCache.rCryptoCache.readCacheLen, hmac, &hmacLen); + + if (hmacLen != CRYPTO_HMAC_SIZE || strncmp(hmac, encData, CRYPTO_HMAC_SIZE) != 0) { + exit_horribly(modulename, "hmac verify failed\n"); + } + } else if (encLen > 0) { + exit_horribly(modulename, "read encrypted data error\n"); } } diff --git a/src/bin/psql/common_cipher.cpp b/src/bin/psql/common_cipher.cpp index 6066246b6..4f75f1a67 100644 --- a/src/bin/psql/common_cipher.cpp +++ b/src/bin/psql/common_cipher.cpp @@ -54,7 +54,6 @@ typedef void (*crypto_ctx_clean_type)(void *ctx); typedef int (*crypto_digest_type)(void *sess, ModuleDigestAlgo algo, unsigned char * data, size_t data_size,unsigned char *result, size_t *result_size); typedef int (*crypto_hmac_init_type)(void *sess, void **ctx, ModuleSymmKeyAlgo algo, unsigned char *key_id, size_t key_id_size); typedef void (*crypto_hmac_clean_type)(void *ctx); -typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size); typedef int (*crypto_gen_random_type)(void *sess, char *buffer, size_t size); typedef int (*crypto_deterministic_enc_dec_type)(void *sess, int enc, unsigned char *data, unsigned char *key_id, size_t key_id_size, size_t data_size, unsigned char *result, size_t *result_size); typedef int (*crypto_get_errmsg_type)(void *sess, char *errmsg); @@ -73,7 +72,7 @@ crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use = NULL; static crypto_digest_type crypto_digest_use = NULL; static crypto_hmac_init_type crypto_hmac_init_use = NULL; static crypto_hmac_clean_type crypto_hmac_clean_use = NULL; -static crypto_hmac_type crypto_hmac_use = NULL; +crypto_hmac_type crypto_hmac_use = NULL; static crypto_gen_random_type crypto_gen_random_use = NULL; static crypto_deterministic_enc_dec_type crypto_deterministic_enc_dec_use = NULL; static crypto_get_errmsg_type crypto_get_errmsg_use = NULL; @@ -143,7 +142,7 @@ void unload_crypto_module(int code, void* args) } } -static int transform_type(char* type) +static ModuleSymmKeyAlgo transform_type(char* type) { if (strcmp(type, "AES128_CBC") == 0) { return MODULE_AES_128_CBC; @@ -163,7 +162,7 @@ static int transform_type(char* type) return MODULE_SM4_CTR; } - return -1; + return MODULE_ALGO_MAX; } @@ -251,6 +250,57 @@ void symmEncDec(DecryptInfo* pDecryptInfo, bool isEnc, char* indata, int inlen, } } +static ModuleSymmKeyAlgo getHmacType(ModuleSymmKeyAlgo symmAlgoType) +{ + if (symmAlgoType >= MODULE_AES_128_CBC && symmAlgoType <= MODULE_AES_256_GCM) { + return MODULE_HMAC_SHA256; + } else if (symmAlgoType == MODULE_SM4_CBC || symmAlgoType == MODULE_SM4_CTR){ + return MODULE_HMAC_SM3; + } + + return MODULE_ALGO_MAX; +} + +void initHmacCtx(DecryptInfo* pDecryptInfo) +{ + int ret = 1; + char errmsg[MAX_ERRMSG_LEN] = {0}; + + ret = crypto_hmac_init_use(pDecryptInfo->moduleSessionCtx, &(pDecryptInfo->moduleHmacCtx), getHmacType(transform_type(pDecryptInfo->crypto_type)), pDecryptInfo->Key, pDecryptInfo->keyLen); + if (ret != 1) { + crypto_get_errmsg_use(NULL, errmsg); + crypto_module_sess_exit_use(pDecryptInfo->moduleSessionCtx); + fprintf(stderr, ("%s\n"), errmsg); + exit(1); + } + +} + +void releaseHmacCtx(int code, void* args) +{ + if (libhandle && ((DecryptInfo*)args)->moduleHmacCtx) { + crypto_hmac_clean_use(((DecryptInfo*)args)->moduleHmacCtx); + ((DecryptInfo*)args)->moduleHmacCtx = NULL; + } +} + +void cryptoHmac(DecryptInfo* pDecryptInfo, char* indata, int inlen, char* outdata, int* outlen) +{ + int ret = 1; + char errmsg[MAX_ERRMSG_LEN] = {0}; + + ret = crypto_hmac_use(pDecryptInfo->moduleHmacCtx, (unsigned char*)indata, inlen, (unsigned char*)outdata, (size_t*)outlen); + if (ret != 1) { + crypto_get_errmsg_use(NULL, errmsg); + releaseHmacCtx(0, pDecryptInfo); + releaseCryptoCtx(0, pDecryptInfo); + releaseCryptoSession(0, pDecryptInfo); + unload_crypto_module(0, NULL); + fprintf(stderr, ("%s\n"), errmsg); + exit(1); + } +} + void CryptoModuleParamsCheck(DecryptInfo* pDecryptInfo, const char* params, const char* module_encrypt_mode, const char* module_encrypt_key, const char* module_encrypt_salt) { errno_t rc = 0; @@ -306,7 +356,9 @@ void CryptoModuleParamsCheck(DecryptInfo* pDecryptInfo, const char* params, cons } initCryptoKeyCtx(pDecryptInfo); + initHmacCtx(pDecryptInfo); pDecryptInfo->encryptInclude = true; pDecryptInfo->clientSymmCryptoFunc = crypto_encrypt_decrypt_use; + pDecryptInfo->clientHmacFunc = crypto_hmac_use; } diff --git a/src/bin/psql/common_cipher.h b/src/bin/psql/common_cipher.h index 0a5d0a56b..3d9bc6879 100644 --- a/src/bin/psql/common_cipher.h +++ b/src/bin/psql/common_cipher.h @@ -17,7 +17,10 @@ extern "C" { #define MAX_WRITE_CACHE_LEN (MAX_CRYPTO_CACHE_LEN - CRYPTO_BLOCK_SIZE) /*加密算法补pad模式为强补,最多可以补16字节,所以写缓存少16字节,则密文最长8192、保证读取时可以整块密文读入*/ typedef int (*crypto_encrypt_decrypt_type)(void *ctx, int enc, unsigned char *data, size_t data_size, unsigned char *iv, size_t iv_size, unsigned char *result, size_t *result_size, unsigned char *tag); +typedef int (*crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size); + extern crypto_encrypt_decrypt_type crypto_encrypt_decrypt_use; +extern crypto_hmac_type crypto_hmac_use; extern bool load_crypto_module_lib(); extern void unload_crypto_module(int code, void* args); @@ -28,6 +31,9 @@ extern void initCryptoKeyCtx(DecryptInfo* pDecryptInfo); extern void releaseCryptoCtx(int code, void* args); extern void symmEncDec(DecryptInfo* pDecryptInfo, bool isEnc, char* indata, int inlen, char* outdata, int* outlen); extern void symmGenerateKey(DecryptInfo* pDecryptInfo); +extern void initHmacCtx(DecryptInfo* pDecryptInfo); +extern void releaseHmacCtx(int code, void* args); +extern void cryptoHmac(DecryptInfo* pDecryptInfo, char* indata, int inlen, char* outdata, int* outlen); extern void CryptoModuleParamsCheck(DecryptInfo* pDecryptInfo, const char* params, const char* module_encrypt_mode, const char* module_encrypt_key, const char* module_encrypt_salt); #ifdef __cplusplus diff --git a/src/gausskernel/cbb/utils/aes/aes.cpp b/src/gausskernel/cbb/utils/aes/aes.cpp index e9c14cdd9..d8f266029 100644 --- a/src/gausskernel/cbb/utils/aes/aes.cpp +++ b/src/gausskernel/cbb/utils/aes/aes.cpp @@ -69,7 +69,7 @@ bool init_aes_vector_random(GS_UCHAR* aes_vector, size_t vector_len) /* inputstrlen must include the terminating '\0' character */ bool writeFileAfterEncryption( - FILE* pf, char* inputstr, int inputstrlen, int writeBufflen, unsigned char Key[], unsigned char* randvalue, void* moduleKeyCtx, kernel_crypto_encrypt_decrypt_type encFunc) + FILE* pf, char* inputstr, int inputstrlen, int writeBufflen, unsigned char Key[], unsigned char* randvalue, void* moduleKeyCtx, kernel_crypto_encrypt_decrypt_type encFunc, void* moduleHmacCtx, kernel_crypto_hmac_type hmacFunc) { void* writeBuff = NULL; int64 writeBuffLen; @@ -79,6 +79,7 @@ bool writeFileAfterEncryption( GS_UINT32 outputlen; bool encryptstatus = false; errno_t errorno = EOK; + int cipherstart = 0; if ((inputstr == NULL) || inputstrlen <= 0) { return false; @@ -92,8 +93,13 @@ bool writeFileAfterEncryption( * cipher text len max is plain text len + RANDOM_LEN(aes128) * writeBufflen equals to ciphertextlen + RANDOM_LEN(rand_vector) + RANDOM_LEN(encrypt_salt). * so writeBufflen equals to inputstrlen(palin text len) + 48. + * if use crypto module,writebuff header after cipherlen add hmac,hmac length is 32. */ writeBuffLen = (int64)inputstrlen + RANDOM_LEN * 3; + if (moduleKeyCtx && encFunc && moduleHmacCtx && hmacFunc) { + writeBuffLen += CRYPTO_MODULE_HMAC_LEN; + } + if (writeBuffLen >= MAX_INT_NUM) { printf("invalid value of inputstrlen!\n"); return false; @@ -139,10 +145,21 @@ bool writeFileAfterEncryption( } /* the real encrypt operation */ - if (moduleKeyCtx && encFunc) { + if (moduleKeyCtx && encFunc && moduleHmacCtx && hmacFunc) { int ret = 1; + size_t hmaclen = 0; cipherlen = outputlen; + /*caculate plaint hmac*/ + ret = hmacFunc(moduleHmacCtx, (unsigned char*)inputstr, inputstrlen, (unsigned char*)writeBuff + RANDOM_LEN, &hmaclen); + if (ret != 1) { + free(writeBuff); + writeBuff = NULL; + free(outputstr); + outputstr = NULL; + return false; + } + ret = encFunc(moduleKeyCtx, 1, (unsigned char*)inputstr, inputstrlen, randvalue, 16, (unsigned char*)outputstr, (size_t*)(&cipherlen), NULL); if (ret != 1) { free(writeBuff); @@ -151,6 +168,9 @@ bool writeFileAfterEncryption( outputstr = NULL; return false; } + + cipherlen += CRYPTO_MODULE_HMAC_LEN; + cipherstart = CRYPTO_MODULE_HMAC_LEN + RANDOM_LEN; } else { encryptstatus = aes128Encrypt((GS_UCHAR*)inputstr, (GS_UINT32)inputstrlen, @@ -166,6 +186,8 @@ bool writeFileAfterEncryption( outputstr = NULL; return false; } + + cipherstart = RANDOM_LEN; } errorno = sprintf_s(encryptleninfo, sizeof(encryptleninfo), "%u", cipherlen); @@ -173,11 +195,16 @@ bool writeFileAfterEncryption( errorno = memcpy_s((void*)((char*)writeBuff), writeBuffLen, encryptleninfo, RANDOM_LEN); securec_check_c(errorno, "\0", "\0"); /* the ciphertext contains the real cipher and salt vector used for encrypt */ - errorno = memcpy_s((void*)((char*)writeBuff + RANDOM_LEN), writeBuffLen - RANDOM_LEN, outputstr, cipherlen); + /*stored cipherlen include hmac,however hmac has been stored in writeBuffer*/ + if (cipherstart == (CRYPTO_MODULE_HMAC_LEN + RANDOM_LEN)) { + cipherlen -= CRYPTO_MODULE_HMAC_LEN; + } + + errorno = memcpy_s((void*)((char*)writeBuff + cipherstart), writeBuffLen - cipherstart, outputstr, cipherlen); securec_check_c(errorno, "\0", "\0"); /* write the cipherlen info and cipher text into encrypt file. */ - if (fwrite(writeBuff, (unsigned long)(cipherlen + RANDOM_LEN), 1, pf) != 1) { + if (fwrite(writeBuff, (unsigned long)(cipherlen + cipherstart), 1, pf) != 1) { printf("write encrypt file failed.\n"); free(writeBuff); free(outputstr); @@ -219,6 +246,7 @@ void initDecryptInfo(DecryptInfo* pDecryptInfo) securec_check_c(errorno, "\0", "\0"); pDecryptInfo->moduleKeyCtx = NULL; + pDecryptInfo->moduleHmacCtx = NULL; pDecryptInfo->moduleSessionCtx = NULL; } static bool decryptFromFile(FILE* source, DecryptInfo* pDecryptInfo) @@ -232,6 +260,7 @@ static bool decryptFromFile(FILE* source, DecryptInfo* pDecryptInfo) bool decryptstatus = false; errno_t errorno = EOK; int moduleRet = 1; + bool hmacverified = false; if (!feof(source) && (false == pDecryptInfo->isCurrLineProcess)) { nread = (int)fread((void*)cipherleninfo, 1, RANDOM_LEN, source); @@ -289,8 +318,17 @@ static bool decryptFromFile(FILE* source, DecryptInfo* pDecryptInfo) nread = (int)fread((void*)ciphertext, 1, cipherlen, source); if (nread) { if (pDecryptInfo->moduleKeyCtx && pDecryptInfo->clientSymmCryptoFunc) { + unsigned char hmac[CRYPTO_MODULE_HMAC_LEN + 1] = {0}; + size_t hmaclen = 0; plainlen = cipherlen; - moduleRet = pDecryptInfo->clientSymmCryptoFunc(pDecryptInfo->moduleKeyCtx, 0, ciphertext, cipherlen, pDecryptInfo->rand, 16, outputstr,(size_t*)(&plainlen), NULL); + moduleRet = pDecryptInfo->clientSymmCryptoFunc(pDecryptInfo->moduleKeyCtx, 0, ciphertext + CRYPTO_MODULE_HMAC_LEN, cipherlen - CRYPTO_MODULE_HMAC_LEN, + pDecryptInfo->rand, 16, outputstr,(size_t*)(&plainlen), NULL); + + /*verify hmac*/ + moduleRet = pDecryptInfo->clientHmacFunc(pDecryptInfo->moduleHmacCtx, outputstr, plainlen, hmac, &hmaclen); + if (strncmp((char*)hmac, (char*)ciphertext, CRYPTO_MODULE_HMAC_LEN) == 0) { + hmacverified = true; + } } else { decryptstatus = aes128Decrypt(ciphertext, (GS_UINT32)cipherlen, @@ -303,7 +341,8 @@ static bool decryptFromFile(FILE* source, DecryptInfo* pDecryptInfo) } if (!nread || (!decryptstatus && (pDecryptInfo->moduleKeyCtx == NULL && pDecryptInfo->clientSymmCryptoFunc == NULL)) - || (moduleRet != 1 && pDecryptInfo->moduleKeyCtx && pDecryptInfo->clientSymmCryptoFunc)) { + || (moduleRet != 1 && pDecryptInfo->moduleKeyCtx && pDecryptInfo->clientSymmCryptoFunc) + || (!hmacverified && pDecryptInfo->moduleHmacCtx && pDecryptInfo->clientHmacFunc)) { errorno = memset_s(ciphertext, cipherlen, '\0', cipherlen); securec_check_c(errorno, "", ""); free(ciphertext); diff --git a/src/include/utils/aes.h b/src/include/utils/aes.h index 5f0aa1740..9f7c1e875 100644 --- a/src/include/utils/aes.h +++ b/src/include/utils/aes.h @@ -43,9 +43,11 @@ ((inputlen % AES_GROUP_LEN) ? ((inputlen / AES_GROUP_LEN) * AES_GROUP_LEN + AES_GROUP_LEN) : inputlen) typedef int (*kernel_crypto_encrypt_decrypt_type)(void *ctx, int enc, unsigned char *data, size_t data_size, unsigned char *iv, size_t iv_size, unsigned char *result, size_t *result_size, unsigned char *tag); +typedef int (*kernel_crypto_hmac_type)(void *ctx, unsigned char * data, size_t data_size, unsigned char *result, size_t *result_size); #define CRYPTO_MODULE_PARAMS_MAX_LEN 1024 #define CRYPTO_MODULE_ENC_TYPE_MAX_LEN 16 +#define CRYPTO_MODULE_HMAC_LEN 32 typedef struct decrypt_struct { unsigned char* decryptBuff; @@ -56,12 +58,14 @@ typedef struct decrypt_struct { bool encryptInclude; kernel_crypto_encrypt_decrypt_type clientSymmCryptoFunc; + kernel_crypto_hmac_type clientHmacFunc; /* Encrypt gs_dump file through OpenSSL function */ bool randget; unsigned char rand[RANDOM_LEN + 1]; void* moduleSessionCtx; void* moduleKeyCtx; + void* moduleHmacCtx; char crypto_modlue_params[CRYPTO_MODULE_PARAMS_MAX_LEN]; char crypto_type[CRYPTO_MODULE_ENC_TYPE_MAX_LEN]; } DecryptInfo; @@ -69,7 +73,9 @@ typedef struct decrypt_struct { extern void initDecryptInfo(DecryptInfo* pDecryptInfo); extern char* getLineFromAesEncryptFile(FILE* source, DecryptInfo* pDecryptInfo); extern bool writeFileAfterEncryption( - FILE* pf, char* inputstr, int inputstrlen, int writeBufflen, unsigned char Key[], unsigned char* rand, void* moduleKeyCtx = NULL, kernel_crypto_encrypt_decrypt_type encFunc = NULL); + FILE* pf, char* inputstr, int inputstrlen, int writeBufflen, unsigned char Key[], unsigned char* rand, + void* moduleKeyCtx = NULL, kernel_crypto_encrypt_decrypt_type encFunc = NULL, + void* moduleHmacCtx = NULL, kernel_crypto_hmac_type hmacFunc = NULL); extern bool check_key(const char* key, int NUM); extern void aesEncrypt(char* inputstr, unsigned long inputstrlen, char* outputstr, unsigned char Key[]); extern void aesDecrypt(char* inputstr, unsigned long inputstrlen, char* outputstr, unsigned char Key[], bool isBinary);