From 346ad76ed8bd03fdc87c8fc1e76667489f7d94b0 Mon Sep 17 00:00:00 2001 From: lcc Date: Mon, 13 May 2024 15:36:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E8=A7=A3=E5=AF=86SM4=E7=AE=97?= =?UTF-8?q?=E6=B3=95=E6=94=AF=E6=8C=81GCM=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lcc --- .../common/inc/openssl_adapter.h | 2 + .../common/src/openssl_adapter.c | 10 + .../cipher/src/cipher_sm4_openssl.c | 403 ++++++-- .../hcfciphercreate_fuzzer.cpp | 165 ++++ test/unittest/BUILD.gn | 1 + test/unittest/include/sm4_common.h | 4 - .../src/crypto_sm4_cfb_cipher_test.cpp | 1 + test/unittest/src/crypto_sm4_cipher_test.cpp | 1 + .../src/crypto_sm4_ecb_cipher_test.cpp | 1 + .../src/crypto_sm4_gcm_cipher_test.cpp | 929 ++++++++++++++++++ test/unittest/src/sm4_common.cpp | 1 + 11 files changed, 1452 insertions(+), 66 deletions(-) create mode 100644 test/unittest/src/crypto_sm4_gcm_cipher_test.cpp diff --git a/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index f2aa706..1e69a50 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -292,6 +292,8 @@ const EVP_CIPHER *OpensslEvpDesEde3Ofb(void); const EVP_CIPHER *OpensslEvpDesEde3Cfb64(void); const EVP_CIPHER *OpensslEvpDesEde3Cfb1(void); const EVP_CIPHER *OpensslEvpDesEde3Cfb8(void); +EVP_CIPHER *OpensslEvpCipherFetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); +void OpensslEvpCipherFree(EVP_CIPHER *cipher); EVP_CIPHER_CTX *OpensslEvpCipherCtxNew(void); int OpensslEvpCipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index 85a7e89..3c832ec 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -1155,6 +1155,16 @@ const EVP_CIPHER *OpensslEvpSm4Ofb(void) return EVP_sm4_ofb(); } +EVP_CIPHER *OpensslEvpCipherFetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) +{ + return EVP_CIPHER_fetch(ctx, algorithm, properties); +} + +void OpensslEvpCipherFree(EVP_CIPHER *cipher) +{ + return EVP_CIPHER_free(cipher); +} + EVP_CIPHER_CTX *OpensslEvpCipherCtxNew(void) { return EVP_CIPHER_CTX_new(); diff --git a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c index d7dfb40..9a75442 100644 --- a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c @@ -28,6 +28,10 @@ #define MAX_AAD_LEN 2048 #define SM4_BLOCK_SIZE 16 #define SM4_SIZE_128 16 +#define GCM_IV_MIN_LEN 1 +#define GCM_IV_MAX_LEN 128 +#define GCM_TAG_SIZE 16 +#define CBC_CTR_OFB_CFB_IV_LEN 16 typedef struct { HcfCipherGeneratorSpi base; @@ -106,6 +110,12 @@ static const EVP_CIPHER *CipherCfb128Type(SymKeyImpl *symKey) return NULL; } +static const EVP_CIPHER *CipherGcmType(SymKeyImpl *symKey) +{ + (void)symKey; + return (const EVP_CIPHER *)OpensslEvpCipherFetch(NULL, "SM4-GCM", NULL); +} + static const EVP_CIPHER *DefaultCipherType(SymKeyImpl *symKey) { return CipherEcbType(symKey); @@ -126,36 +136,125 @@ static const EVP_CIPHER *GetCipherType(HcfCipherSm4GeneratorSpiOpensslImpl *impl return CipherCfbType(symKey); case HCF_ALG_MODE_CFB128: return CipherCfb128Type(symKey); + case HCF_ALG_MODE_GCM: + return CipherGcmType(symKey); default: break; } return DefaultCipherType(symKey); } -static HcfResult InitCipherData(enum HcfCryptoMode opMode, CipherData **cipherData) +static HcfResult IsIvParamsValid(HcfIvParamsSpec *params) { - HcfResult ret = HCF_ERR_MALLOC; - if (cipherData == NULL) { - LOGE("invalid cipher data"); + if (params == NULL) { + LOGE("params is null!"); + return HCF_INVALID_PARAMS; + } + if ((params->iv.data == NULL) || (params->iv.len != CBC_CTR_OFB_CFB_IV_LEN)) { + LOGE("iv is invalid!"); return HCF_INVALID_PARAMS; } + return HCF_SUCCESS; +} - CipherData *data = (CipherData *)HcfMalloc(sizeof(CipherData), 0); - if (data == NULL) { - LOGE("malloc failed."); - return HCF_ERR_MALLOC; +static bool IsGcmParamsValid(HcfGcmParamsSpec *params) +{ + if (params == NULL) { + LOGE("params is null!"); + return false; } + if ((params->iv.data == NULL) || (params->iv.len < GCM_IV_MIN_LEN) || (params->iv.len > GCM_IV_MAX_LEN)) { + LOGE("iv is invalid!"); + return false; + } + if ((params->tag.data == NULL) || (params->tag.len == 0)) { + LOGE("tag is invalid!"); + return false; + } + return true; +} - data->enc = opMode; - data->ctx = OpensslEvpCipherCtxNew(); - if (data->ctx != NULL) { - *cipherData = data; - ret = HCF_SUCCESS; +static HcfResult InitAadAndTagFromGcmParams(enum HcfCryptoMode opMode, HcfGcmParamsSpec *params, CipherData *data) +{ + if (!IsGcmParamsValid(params)) { + LOGE("gcm params is invalid!"); + return HCF_INVALID_PARAMS; + } + + if (params->aad.data != NULL && params->aad.len != 0) { + data->aad = (uint8_t *)HcfMalloc(params->aad.len, 0); + if (data->aad == NULL) { + LOGE("aad malloc failed!"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(data->aad, params->aad.len, params->aad.data, params->aad.len); + data->aadLen = params->aad.len; + data->aead = true; } else { + data->aad = NULL; + data->aadLen = 0; + data->aead = false; + } + data->tagLen = params->tag.len; + if (opMode == ENCRYPT_MODE) { + return HCF_SUCCESS; + } + data->tag = (uint8_t *)HcfMalloc(params->tag.len, 0); + if (data->tag == NULL) { + HcfFree(data->aad); + data->aad = NULL; + LOGE("tag malloc failed!"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(data->tag, params->tag.len, params->tag.data, params->tag.len); + return HCF_SUCCESS; +} + +static HcfResult InitCipherData(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode, + HcfParamsSpec* params, CipherData **cipherData) +{ + HcfResult ret = HCF_ERR_MALLOC; + *cipherData = (CipherData *)HcfMalloc(sizeof(CipherData), 0); + if (*cipherData == NULL) { + LOGE("malloc is failed!"); + return ret; + } + HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self; + HcfAlgParaValue mode = cipherImpl->attr.mode; + + (*cipherData)->enc = opMode; + (*cipherData)->ctx = OpensslEvpCipherCtxNew(); + if ((*cipherData)->ctx == NULL) { HcfPrintOpensslError(); - HcfFree(data); - LOGD("[error] Failed to allocate ctx memroy."); + LOGE("Failed to allocate ctx memory!"); + goto clearup; } + + ret = HCF_SUCCESS; + switch (mode) { + case HCF_ALG_MODE_CBC: + case HCF_ALG_MODE_CTR: + case HCF_ALG_MODE_OFB: + case HCF_ALG_MODE_CFB: + case HCF_ALG_MODE_CFB128: + (void)IsIvParamsValid((HcfIvParamsSpec *)params); + break; + case HCF_ALG_MODE_GCM: + ret = InitAadAndTagFromGcmParams(opMode, (HcfGcmParamsSpec *)params, *cipherData); + break; + case HCF_ALG_MODE_CCM: + ret = HCF_NOT_SUPPORT; + break; + default: + break; + } + if (ret != HCF_SUCCESS) { + LOGE("init cipher data failed!"); + goto clearup; + } + return ret; +clearup: + FreeCipherData(cipherData); return ret; } @@ -207,6 +306,48 @@ static HcfResult CheckParam(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMo return HCF_SUCCESS; } +static bool SetCipherAttribute(HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl, SymKeyImpl *keyImpl, + int enc, HcfParamsSpec *params) +{ + CipherData *data = cipherImpl->cipherData; + HcfAlgParaValue mode = cipherImpl->attr.mode; + const EVP_CIPHER *cipher = GetCipherType(cipherImpl, keyImpl); + if (cipher == NULL) { + HcfPrintOpensslError(); + LOGE("fetch cipher failed!"); + return false; + } + if (mode != HCF_ALG_MODE_GCM) { + if (OpensslEvpCipherInit(data->ctx, cipher, keyImpl->keyMaterial.data, + GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_CipherInit failed!"); + return false; + } + return true; + } + if (OpensslEvpCipherInit(data->ctx, cipher, NULL, NULL, enc) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_CipherInit failed!"); + OpensslEvpCipherFree((EVP_CIPHER *)cipher); + return false; + } + OpensslEvpCipherFree((EVP_CIPHER *)cipher); + if (OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_IVLEN, + GetIvLen(params), NULL) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_Cipher set iv len failed!"); + return false; + } + if (OpensslEvpCipherInit(data->ctx, NULL, keyImpl->keyMaterial.data, + GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_CipherInit failed!"); + return false; + } + return true; +} + static HcfResult EngineCipherInit(HcfCipherGeneratorSpi* self, enum HcfCryptoMode opMode, HcfKey* key, HcfParamsSpec* params) { @@ -214,36 +355,37 @@ static HcfResult EngineCipherInit(HcfCipherGeneratorSpi* self, enum HcfCryptoMod return HCF_INVALID_PARAMS; } HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self; - CipherData* data = NULL; - if (InitCipherData(opMode, &data) != HCF_SUCCESS) { + SymKeyImpl* keyImpl = (SymKeyImpl*)key; + int32_t enc = (opMode == ENCRYPT_MODE) ? 1 : 0; + cipherImpl->attr.keySize = keyImpl->keyMaterial.len; + HcfResult res = InitCipherData(self, opMode, params, &(cipherImpl->cipherData)); + if (res != HCF_SUCCESS) { LOGE("InitCipherData failed"); - return HCF_INVALID_PARAMS; + return res; } + CipherData *data = cipherImpl->cipherData; HcfResult ret = HCF_ERR_CRYPTO_OPERATION; - int32_t enc = (opMode == ENCRYPT_MODE) ? 1 : 0; - SymKeyImpl* keyImpl = (SymKeyImpl*)key; - if (OpensslEvpCipherInit(data->ctx, GetCipherType(cipherImpl, keyImpl), keyImpl->keyMaterial.data, - GetIv(params), enc) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - LOGD("[error] Cipher init key and iv failed."); - FreeCipherData(&data); - return ret; + if (!SetCipherAttribute(cipherImpl, keyImpl, enc, params)) { + LOGE("Set cipher attribute failed!"); + goto clearup; } if (OpensslEvpCipherCtxSetPadding(data->ctx, GetPaddingMode(cipherImpl)) != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGD("[error] Set padding failed."); - FreeCipherData(&data); - return ret; + LOGE("Set padding failed."); + goto clearup; } - cipherImpl->cipherData = data; return HCF_SUCCESS; +clearup: + FreeCipherData(&(cipherImpl->cipherData)); + return ret; } -static HcfResult AllocateOutput(HcfBlob* input, HcfBlob* output) +static HcfResult AllocateOutput(HcfBlob* input, HcfBlob* output, bool *isUpdateInput) { - uint32_t outLen = SM4_BLOCK_SIZE; + uint32_t outLen = SM4_BLOCK_SIZE + SM4_BLOCK_SIZE; if (IsBlobValid(input)) { outLen += input->len; + *isUpdateInput = true; } output->data = (uint8_t*)HcfMalloc(outLen, 0); if (output->data == NULL) { @@ -254,6 +396,35 @@ static HcfResult AllocateOutput(HcfBlob* input, HcfBlob* output) return HCF_SUCCESS; } +static HcfResult CommonUpdate(CipherData *data, HcfBlob *input, HcfBlob *output) +{ + int32_t ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len, + input->data, input->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("cipher update failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult AeadUpdate(CipherData *data, HcfAlgParaValue mode, HcfBlob *input, HcfBlob *output) +{ + int32_t ret = OpensslEvpCipherUpdate(data->ctx, NULL, (int *)&output->len, data->aad, data->aadLen); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("aad cipher update failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int *)&output->len, input->data, input->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("gcm cipher update failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBlob *output) { if ((self == NULL) || (input == NULL) || (output == NULL)) { @@ -271,44 +442,150 @@ static HcfResult EngineUpdate(HcfCipherGeneratorSpi *self, HcfBlob *input, HcfBl LOGE("cipherData is null!"); return HCF_INVALID_PARAMS; } - HcfResult ret = HCF_ERR_CRYPTO_OPERATION; - if (AllocateOutput(input, output) == HCF_SUCCESS) { - if (OpensslEvpCipherUpdate(data->ctx, output->data, (int*)&output->len, - input->data, input->len) != HCF_OPENSSL_SUCCESS) { - HcfPrintOpensslError(); - LOGD("[error] Cipher update failed."); - } else { - ret = HCF_SUCCESS; - } + bool isUpdateInput = false; + HcfResult ret = AllocateOutput(input, output, &isUpdateInput); + if (ret != HCF_SUCCESS) { + LOGE("AllocateOutput failed!"); + return ret; + } + + if (!data->aead) { + ret = CommonUpdate(data, input, output); + } else { + ret = AeadUpdate(data, cipherImpl->attr.mode, input, output); } if (ret != HCF_SUCCESS) { HcfBlobDataFree(output); FreeCipherData(&(cipherImpl->cipherData)); - } else { - FreeRedundantOutput(output); } + data->aead = false; + FreeRedundantOutput(output); return ret; } -static HcfResult SM4DoFinal(CipherData* data, HcfBlob* input, HcfBlob* output) +static HcfResult AllocateGcmOutput(CipherData *data, HcfBlob *input, HcfBlob *output, bool *isUpdateInput) +{ + uint32_t outLen = 0; + if (IsBlobValid(input)) { + outLen += input->len; + *isUpdateInput = true; + } + int32_t authTagLen = data->enc == ENCRYPT_MODE ? GCM_TAG_SIZE : 0; + outLen += data->updateLen + authTagLen + SM4_BLOCK_SIZE; + if (outLen == 0) { + LOGE("output size is invaild!"); + return HCF_INVALID_PARAMS; + } + output->data = (uint8_t *)HcfMalloc(outLen, 0); + if (output->data == NULL) { + LOGE("malloc output failed!"); + return HCF_ERR_MALLOC; + } + output->len = outLen; + return HCF_SUCCESS; +} + +static HcfResult GcmDecryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len) +{ + if (data->tag == NULL) { + LOGE("gcm decrypt has not AuthTag!"); + return HCF_INVALID_PARAMS; + } + int32_t ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_SET_TAG, data->tagLen, (void *)data->tag); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("gcm decrypt set AuthTag failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_CipherFinal_ex failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + output->len = output->len + len; + return HCF_SUCCESS; +} + +static HcfResult GcmEncryptDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output, uint32_t len) +{ + int32_t ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("EVP_CipherFinal_ex failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + output->len += len; + ret = OpensslEvpCipherCtxCtrl(data->ctx, EVP_CTRL_AEAD_GET_TAG, data->tagLen, + output->data + output->len); + if (ret != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + LOGE("get AuthTag failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + output->len += data->tagLen; + return HCF_SUCCESS; +} + +static HcfResult GcmDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output) { - int32_t ret; uint32_t len = 0; + bool isUpdateInput = false; + HcfResult res = AllocateGcmOutput(data, input, output, &isUpdateInput); + if (res != HCF_SUCCESS) { + LOGE("AllocateGcmOutput failed!"); + return res; + } - if (IsBlobValid(input)) { + if (isUpdateInput) { + if (data->aad != NULL && data->aadLen != 0) { + HcfResult result = AeadUpdate(data, HCF_ALG_MODE_GCM, input, output); + if (result != HCF_SUCCESS) { + LOGE("AeadUpdate failed!"); + return result; + } + } else { + HcfResult result = CommonUpdate(data, input, output); + if (result != HCF_SUCCESS) { + LOGE("No aad update failed!"); + return result; + } + } + len = output->len; + } + if (data->enc == ENCRYPT_MODE) { + return GcmEncryptDoFinal(data, input, output, len); + } else if (data->enc == DECRYPT_MODE) { + return GcmDecryptDoFinal(data, input, output, len); + } else { + return HCF_INVALID_PARAMS; + } +} + +static HcfResult CommonDoFinal(CipherData *data, HcfBlob *input, HcfBlob *output) +{ + int32_t ret; + uint32_t len = 0; + bool isUpdateInput = false; + HcfResult res = AllocateOutput(input, output, &isUpdateInput); + if (res != HCF_SUCCESS) { + LOGE("AllocateOutput failed!"); + return res; + } + if (isUpdateInput) { ret = OpensslEvpCipherUpdate(data->ctx, output->data, (int*)&output->len, input->data, input->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGD("[error] Cipher update failed."); + LOGE("EVP_CipherUpdate failed!"); return HCF_ERR_CRYPTO_OPERATION; } len += output->len; } - ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int*)&output->len); + ret = OpensslEvpCipherFinalEx(data->ctx, output->data + len, (int *)&output->len); if (ret != HCF_OPENSSL_SUCCESS) { HcfPrintOpensslError(); - LOGD("[error] Cipher final filed."); + LOGE("EVP_CipherFinal_ex failed!"); return HCF_ERR_CRYPTO_OPERATION; } output->len += len; @@ -325,25 +602,27 @@ static HcfResult EngineDoFinal(HcfCipherGeneratorSpi* self, HcfBlob* input, HcfB LOGE("Class is not match."); return HCF_INVALID_PARAMS; } - HcfCipherSm4GeneratorSpiOpensslImpl* cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl*)self; - if (cipherImpl->cipherData == NULL) { - LOGE("CipherData is null."); - return HCF_INVALID_PARAMS; - } HcfResult ret = HCF_ERR_CRYPTO_OPERATION; - if (AllocateOutput(input, output) == HCF_SUCCESS) { - ret = SM4DoFinal(cipherImpl->cipherData, input, output); - if (ret != HCF_SUCCESS) { - LOGD("[error] DesDoFinal failed."); - } + HcfCipherSm4GeneratorSpiOpensslImpl *cipherImpl = (HcfCipherSm4GeneratorSpiOpensslImpl *)self; + CipherData *data = cipherImpl->cipherData; + if (data == NULL) { + LOGE("cipherData is null!"); + return HCF_INVALID_PARAMS; + } + + HcfAlgParaValue mode = cipherImpl->attr.mode; + if (mode == HCF_ALG_MODE_GCM) { + ret = GcmDoFinal(data, input, output); + } else { /* only ECB CBC CTR CFB OFB support */ + ret = CommonDoFinal(data, input, output); } + + FreeCipherData(&(cipherImpl->cipherData)); if (ret != HCF_SUCCESS) { HcfBlobDataFree(output); - } else { - FreeRedundantOutput(output); } - FreeCipherData(&(cipherImpl->cipherData)); + FreeRedundantOutput(output); return ret; } diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp index f37d85a..2eac440 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/hcfciphercreate_fuzzer.cpp @@ -112,6 +112,96 @@ namespace OHOS { return ret; } + static Sm4Encrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params, + uint8_t *cipherText, int *cipherTextLen) + { + uint8_t plainText[] = "this is test!"; + HcfBlob input = {.data = reinterpret_cast(plainText), .len = 13}; + HcfBlob output = {}; + int32_t maxLen = *cipherTextLen; + int32_t ret = cipher->init(cipher, ENCRYPT_MODE, reinterpret_cast(key), params); + if (ret != 0) { + LOGE("init failed! "); + return ret; + } + + ret = cipher->update(cipher, &input, &output); + if (ret != 0) { + LOGE("update failed!"); + return ret; + } + *cipherTextLen = output.len; + if (output.data != nullptr) { + if (memcpy_s(cipherText, maxLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + HcfBlobDataFree(&output); + } + + ret = cipher->doFinal(cipher, nullptr, &output); + if (ret != 0) { + LOGE("doFinal failed!"); + return ret; + } + if (output.data != nullptr) { + if (memcpy_s(cipherText + *cipherTextLen, maxLen - *cipherTextLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + *cipherTextLen += output.len; + HcfBlobDataFree(&output); + } + return 0; + } + + static Sm4Decrypt(HcfCipher *cipher, HcfSymKey *key, HcfParamsSpec *params, + uint8_t *cipherText, int cipherTextLen) + { + uint8_t plainText[] = "this is test!"; + HcfBlob input = {.data = reinterpret_cast(cipherText), .len = cipherTextLen}; + HcfBlob output = {}; + int32_t maxLen = cipherTextLen; + int32_t ret = cipher->init(cipher, DECRYPT_MODE, reinterpret_cast(key), params); + if (ret != 0) { + LOGE("init failed! "); + return ret; + } + + ret = cipher->update(cipher, &input, &output); + if (ret != 0) { + LOGE("update failed!"); + return ret; + } + cipherTextLen = output.len; + if (output.data != nullptr) { + if (memcpy_s(cipherText, maxLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + HcfBlobDataFree(&output); + } + + ret = cipher->doFinal(cipher, nullptr, &output); + if (ret != 0) { + LOGE("doFinal failed!"); + return ret; + } + if (output.data != nullptr) { + if (memcpy_s(cipherText + cipherTextLen, maxLen - cipherTextLen, output.data, output.len) != EOK) { + HcfBlobDataFree(&output); + return -1; + } + cipherTextLen += output.len; + HcfBlobDataFree(&output); + } + + if (cipherTextLen != sizeof(plainText) - 1) { + return -1; + } + return memcmp(cipherText, plainText, cipherTextLen); + } + static void TestAesCipher(void) { int ret = 0; @@ -143,6 +233,79 @@ namespace OHOS { HcfObjDestroy(cipher); } + static void TestSm4Cipher(void) + { + int ret = 0; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + ret = HcfSymKeyGeneratorCreate("SM4_128", &generator); + if (ret != HCF_SUCCESS) { + return; + } + ret = generator->generateSymKey(generator, &key); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(generator); + return; + } + ret = HcfCipherCreate("SM4_128|ECB|PKCS5", &cipher); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(generator); + HcfObjDestroy(key); + return; + } + + (void)Sm4Encrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + (void)SM4Decrypt(cipher, key, nullptr, cipherText, cipherTextLen); + HcfObjDestroy(generator); + HcfObjDestroy(key); + HcfObjDestroy(cipher); + } + + static void TestSm4GcmCipher(void) + { + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + HcfSymKeyGenerator *generator = nullptr; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + ret = HcfSymKeyGeneratorCreate("SM4_128", &generator); + if (ret != HCF_SUCCESS) { + return; + } + ret = generator->generateSymKey(generator, &key); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(generator); + return; + } + ret = HcfCipherCreate("SM4_128|GCM|PKCS5", &cipher); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(generator); + HcfObjDestroy(key); + return; + } + + (void)Sm4Encrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + (void)SM4Decrypt(cipher, key, nullptr, cipherText, cipherTextLen); + HcfObjDestroy(generator); + HcfObjDestroy(key); + HcfObjDestroy(cipher); + } + static void TestRsaCipher(void) { HcfResult res = HCF_SUCCESS; @@ -195,6 +358,8 @@ namespace OHOS { if (g_testFlag) { TestRsaCipher(); TestAesCipher(); + TestSm4Cipher(); + TestSm4GcmCipher(); g_testFlag = false; } HcfCipher *cipher = nullptr; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index d5152f9..add2867 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -94,6 +94,7 @@ ohos_unittest("crypto_framework_test") { "src/crypto_sm4_cfb_cipher_test.cpp", "src/crypto_sm4_cipher_test.cpp", "src/crypto_sm4_ecb_cipher_test.cpp", + "src/crypto_sm4_gcm_cipher_test.cpp", "src/crypto_sm4_generator_test.cpp", "src/crypto_x25519_asy_key_generator_by_spec_test.cpp", "src/crypto_x25519_asy_key_generator_test.cpp", diff --git a/test/unittest/include/sm4_common.h b/test/unittest/include/sm4_common.h index e3609bf..a7d1b88 100644 --- a/test/unittest/include/sm4_common.h +++ b/test/unittest/include/sm4_common.h @@ -25,10 +25,6 @@ extern "C" { #endif -static constexpr int32_t PLAINTEXT_LEN = 13; -static constexpr int32_t CIPHER_TEXT_LEN = 128; -static constexpr int32_t AES_IV_LEN = 16; // iv for CBC|CTR|OFB|CFB mode - HcfResult GenerateSm4SymKey(HcfSymKey **key); int32_t GenerateSymKeyForSm4(const char *algoName, HcfSymKey **key); diff --git a/test/unittest/src/crypto_sm4_cfb_cipher_test.cpp b/test/unittest/src/crypto_sm4_cfb_cipher_test.cpp index 70018ea..d674789 100644 --- a/test/unittest/src/crypto_sm4_cfb_cipher_test.cpp +++ b/test/unittest/src/crypto_sm4_cfb_cipher_test.cpp @@ -18,6 +18,7 @@ #include #include "securec.h" #include "aes_openssl.h" +#include "aes_common.h" #include "blob.h" #include "cipher.h" #include "detailed_iv_params.h" diff --git a/test/unittest/src/crypto_sm4_cipher_test.cpp b/test/unittest/src/crypto_sm4_cipher_test.cpp index 60d9c55..51a7751 100644 --- a/test/unittest/src/crypto_sm4_cipher_test.cpp +++ b/test/unittest/src/crypto_sm4_cipher_test.cpp @@ -18,6 +18,7 @@ #include #include "securec.h" #include "aes_openssl.h" +#include "aes_common.h" #include "blob.h" #include "cipher.h" #include "detailed_iv_params.h" diff --git a/test/unittest/src/crypto_sm4_ecb_cipher_test.cpp b/test/unittest/src/crypto_sm4_ecb_cipher_test.cpp index 6bee464..09f5399 100644 --- a/test/unittest/src/crypto_sm4_ecb_cipher_test.cpp +++ b/test/unittest/src/crypto_sm4_ecb_cipher_test.cpp @@ -18,6 +18,7 @@ #include #include "securec.h" #include "aes_openssl.h" +#include "aes_common.h" #include "blob.h" #include "cipher.h" #include "detailed_iv_params.h" diff --git a/test/unittest/src/crypto_sm4_gcm_cipher_test.cpp b/test/unittest/src/crypto_sm4_gcm_cipher_test.cpp new file mode 100644 index 0000000..f58cef6 --- /dev/null +++ b/test/unittest/src/crypto_sm4_gcm_cipher_test.cpp @@ -0,0 +1,929 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "securec.h" + +#include "sm4_common.h" +#include "sm4_openssl.h" +#include "aes_common.h" +#include "aes_openssl.h" +#include "blob.h" +#include "cipher.h" +#include "detailed_iv_params.h" +#include "detailed_gcm_params.h" +#include "detailed_ccm_params.h" +#include "log.h" +#include "memory.h" +#include "sym_common_defines.h" +#include "sym_key_generator.h" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoSM4GcmCipherTest : public testing::Test { +public: + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; + void SetUp() {}; + void TearDown() {}; +}; + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest001, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest002, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest003, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest004, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4NoUpdateEncrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateEncrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4NoUpdateDecrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateDecrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest005, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4NoUpdateEncrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateEncrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4NoUpdateDecrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateDecrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest006, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[12] = {0}; // openssl only support nonce 12 bytes, tag 16bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|PKCS7", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4NoUpdateEncrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateEncrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4NoUpdateDecrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4NoUpdateDecrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest009, TestSize.Level0) +{ + int ret = 0; + HcfCipher *cipher = nullptr; + + ret = HcfCipherCreate("RSA128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed! Should not select RSA for GCM generator."); + } + + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest010, TestSize.Level0) +{ + int ret = 0; + HcfCipher *cipher = nullptr; + + // not allow '|' without content, because findAbility will fail for "" input + ret = HcfCipherCreate("SM4_128|GCM|", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed! Should select padding mode for SM4_128 generator."); + } + + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest011, TestSize.Level0) +{ + int ret = 0; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("GenerateSymKey failed!"); + goto CLEAR_UP; + } + + // CBC, CTR, OFB, CFB enc/dec success, + // GCM, CCM enc/dec failed with params set to nullptr. + ret = HcfCipherCreate("SM4_128|GCM|PKCS5", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, nullptr, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed! %d", ret); + goto CLEAR_UP; + } + + ret = Sm4Decrypt(cipher, key, nullptr, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed! %d", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest012, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = { 0 }; + uint8_t iv[GCM_IV_LEN] = { 0 }; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = nullptr; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, &(spec.base), cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + } + +// now support gcm no aad. +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest013, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = { 0 }; + uint8_t iv[GCM_IV_LEN] = { 0 }; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = nullptr; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, &(spec.base), cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest014, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = { 0 }; + uint8_t iv[GCM_IV_LEN] = { 0 }; + uint8_t cipherText[CIPHER_TEXT_LEN] = { 0 }; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = nullptr; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, &(spec.base), cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + } + +CLEAR_UP: + HcfObjDestroy(key); + HcfObjDestroy(cipher); + EXPECT_NE(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest015, TestSize.Level0) +{ + int ret = 0; + uint8_t tag[GCM_TAG_LEN] = {0}; + uint8_t iv[GCM_IV_LEN] = {0}; + uint8_t cipherText[CIPHER_TEXT_LEN] = {0}; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = nullptr; + spec.aad.len = 0; + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, GCM_TAG_LEN, cipherText + cipherTextLen - GCM_TAG_LEN, GCM_TAG_LEN); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= GCM_TAG_LEN; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest016, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_LONG_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = {0}; + uint8_t iv[GCM_IV_LEN] = {0}; + uint8_t cipherText[CIPHER_TEXT_LEN] = {0}; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, GCM_TAG_LEN, cipherText + cipherTextLen - GCM_TAG_LEN, GCM_TAG_LEN); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= GCM_TAG_LEN; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest017, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_LONG_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = {0}; + uint8_t iv[GCM_IV_LONG_LEN] = {0}; + uint8_t cipherText[CIPHER_TEXT_LEN] = {0}; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, GCM_TAG_LEN, cipherText + cipherTextLen - GCM_TAG_LEN, GCM_TAG_LEN); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= GCM_TAG_LEN; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest018, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[GCM_AAD_SHORT_LEN] = { 0 }; + uint8_t tag[GCM_TAG_LEN] = {0}; + // openssl only support ivLen [9, 16]; + uint8_t iv[GCM_IV_SHORT_LEN] = {0}; + uint8_t cipherText[CIPHER_TEXT_LEN] = {0}; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, GCM_TAG_LEN, cipherText + cipherTextLen - GCM_TAG_LEN, GCM_TAG_LEN); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= GCM_TAG_LEN; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest019, TestSize.Level0) +{ + int ret = 0; + uint8_t tag[GCM_TAG_LEN] = {0}; + uint8_t iv[GCM_IV_LONG_LEN] = {0}; + uint8_t cipherText[CIPHER_TEXT_LEN] = {0}; + int cipherTextLen = CIPHER_TEXT_LEN; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = nullptr; + spec.aad.len = 0; + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + goto CLEAR_UP; + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + goto CLEAR_UP; + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + if (ret != 0) { + LOGE("Sm4Encrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + + (void)memcpy_s(spec.tag.data, GCM_TAG_LEN, cipherText + cipherTextLen - GCM_TAG_LEN, GCM_TAG_LEN); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= GCM_TAG_LEN; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + if (ret != 0) { + LOGE("Sm4Decrypt failed, ret:%d!", ret); + goto CLEAR_UP; + } + +CLEAR_UP: + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + EXPECT_EQ(ret, 0); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest020, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[128] = {0}; // openssl support iv max 128 bytes + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + HcfObjDestroy((HcfObjectBase *)key); + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + EXPECT_EQ(ret, 0); + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + EXPECT_EQ(ret, 0); + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); +} + +HWTEST_F(CryptoSM4GcmCipherTest, CryptoSM4GcmCipherTest021, TestSize.Level0) +{ + int ret = 0; + uint8_t aad[8] = {0}; + uint8_t tag[16] = {0}; + uint8_t iv[129] = {0}; + uint8_t cipherText[128] = {0}; + int cipherTextLen = 128; + + HcfCipher *cipher = nullptr; + HcfSymKey *key = nullptr; + + HcfGcmParamsSpec spec = {}; + spec.aad.data = aad; + spec.aad.len = sizeof(aad); + spec.tag.data = tag; + spec.tag.len = sizeof(tag); + spec.iv.data = iv; + spec.iv.len = sizeof(iv); + + ret = GenerateSymKey("SM4_128", &key); + if (ret != 0) { + LOGE("generateSymKey failed!"); + HcfObjDestroy((HcfObjectBase *)key); + } + + ret = HcfCipherCreate("SM4_128|GCM|NoPadding", &cipher); + if (ret != 0) { + LOGE("HcfCipherCreate failed!"); + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); + } + + ret = Sm4Encrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, &cipherTextLen); + EXPECT_NE(ret, 0); + + (void)memcpy_s(spec.tag.data, 16, cipherText + cipherTextLen - 16, 16); + PrintfHex("gcm tag", spec.tag.data, spec.tag.len); + cipherTextLen -= 16; + + ret = Sm4Decrypt(cipher, key, (HcfParamsSpec *)&spec, cipherText, cipherTextLen); + EXPECT_NE(ret, 0); + HcfObjDestroy((HcfObjectBase *)key); + HcfObjDestroy((HcfObjectBase *)cipher); +} +} \ No newline at end of file diff --git a/test/unittest/src/sm4_common.cpp b/test/unittest/src/sm4_common.cpp index 94e418d..e6953c8 100644 --- a/test/unittest/src/sm4_common.cpp +++ b/test/unittest/src/sm4_common.cpp @@ -17,6 +17,7 @@ #include #include "securec.h" #include "aes_openssl.h" +#include "aes_common.h" #include "blob.h" #include "cipher.h" #include "detailed_iv_params.h" -- Gitee