From b11c1c15171af6b021937422ff14a3cd64a8ecc2 Mon Sep 17 00:00:00 2001 From: WuXinTao Date: Mon, 14 Aug 2023 21:27:46 +0800 Subject: [PATCH] add code for new function: SM2 encrypt/decrypt Signed-off-by: wuxintao --- .../main/common/src/hks_base_check.c | 8 +- .../main/common/src/hks_check_paramset.c | 4 +- .../main/common/src/hks_common_check.c | 3 + .../huks_standard/main/include/hks_type.h | 4 +- .../core/src/hks_core_service_three_stage.c | 82 ++- .../three_stage_test/BUILD.gn | 1 + .../asymmetric_alg_test/hks_sm2_cipher_test.h | 66 ++ .../hks_sm2_cipher_test.cpp | 601 ++++++++++++++++++ 8 files changed, 759 insertions(+), 10 deletions(-) create mode 100644 test/unittest/huks_standard_test/three_stage_test/include/asymmetric_alg_test/hks_sm2_cipher_test.h create mode 100644 test/unittest/huks_standard_test/three_stage_test/src/asymmetric_alg_test/hks_sm2_cipher_test.cpp diff --git a/frameworks/huks_standard/main/common/src/hks_base_check.c b/frameworks/huks_standard/main/common/src/hks_base_check.c index 191b24c3..6878cf3a 100644 --- a/frameworks/huks_standard/main/common/src/hks_base_check.c +++ b/frameworks/huks_standard/main/common/src/hks_base_check.c @@ -344,7 +344,7 @@ static const struct ExpectParamsValuesChecker g_expectEccParams[] = { static const struct ParamsValuesChecker g_sm2ParamSet[] = { { HKS_CHECK_TYPE_GEN_KEY, { { true, 0, false}, { false, 0, false}, { true, 0, false}, { true, 0, false}, { false, 0, false} } }, - { HKS_CHECK_TYPE_USE_KEY, { { false, 0, false}, { false, 0, false}, { true, 0, false}, { true, 0, false}, + { HKS_CHECK_TYPE_USE_KEY, { { true, 0, false}, { false, 0, false}, { true, 0, false}, { true, 0, false}, { false, 0, false} } } }; static const struct ExpectParamsValuesChecker g_expectSm2Params[] = { @@ -357,7 +357,7 @@ static const struct ExpectParamsValuesChecker g_expectSm2Params[] = { } }, { HKS_CHECK_TYPE_USE_KEY, { - { false, NULL, 0 }, + { true, g_sm2KeySize, HKS_ARRAY_SIZE(g_sm2KeySize) }, { false, NULL, 0 }, { false, NULL, 0 }, { true, g_sm2Digest, HKS_ARRAY_SIZE(g_sm2Digest) }, @@ -1583,7 +1583,7 @@ static int32_t CheckOptionalParams(bool needCheck, bool isAbsent, uint32_t input if (needCheck) { if (!isAbsent) { if (HksCheckValue(inputValue, expectValue, expectCnt) != HKS_SUCCESS) { - HKS_LOG_E("CheckOptionalParams invalid argument, %d", inputValue); + HKS_LOG_E("CheckOptionalParams invalid argument, %" LOG_PUBLIC "d", inputValue); return HKS_ERROR_INVALID_ARGUMENT; } } @@ -1897,8 +1897,10 @@ int32_t HksCheckCihperData(uint32_t cmdId, uint32_t alg, const struct ParamsValu case HKS_ALG_SM4: return CheckBlockCipherData(cmdId, inputParams, inData, outData, HKS_ALG_SM4); #endif +#if defined(HKS_SUPPORT_SM2_C) && defined(HKS_SUPPORT_SM2_ENCRYPT_DECRYPT) case HKS_ALG_SM2: return HKS_SUCCESS; +#endif default: return HKS_ERROR_INVALID_ALGORITHM; } diff --git a/frameworks/huks_standard/main/common/src/hks_check_paramset.c b/frameworks/huks_standard/main/common/src/hks_check_paramset.c index 12280638..9626e919 100644 --- a/frameworks/huks_standard/main/common/src/hks_check_paramset.c +++ b/frameworks/huks_standard/main/common/src/hks_check_paramset.c @@ -914,9 +914,9 @@ int32_t HksCoreCheckCipherParams(uint32_t cmdId, const struct HksBlob *key, cons ret = HksGetInputParmasByAlg(alg, HKS_CHECK_TYPE_USE_KEY, paramSet, ¶ms); HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher get input params failed, ret = %" LOG_PUBLIC "d", ret) - if ((alg == HKS_ALG_RSA) || (alg == HKS_ALG_SM4)) { + if ((alg == HKS_ALG_RSA) || (alg == HKS_ALG_SM4) || (alg == HKS_ALG_SM4)) { ret = HksGetKeySize(alg, key, ¶ms.keyLen.value); - HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "rsa cipher get key size failed") + HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "rsa/SM4/SM2 cipher get key size failed") } ret = CheckCipherParamsByAlg(cmdId, alg, paramSet, ¶ms); diff --git a/frameworks/huks_standard/main/common/src/hks_common_check.c b/frameworks/huks_standard/main/common/src/hks_common_check.c index 068064e5..76b375a8 100644 --- a/frameworks/huks_standard/main/common/src/hks_common_check.c +++ b/frameworks/huks_standard/main/common/src/hks_common_check.c @@ -123,6 +123,9 @@ int32_t HksGetDigestLen(uint32_t digest, uint32_t *digestLen) case HKS_DIGEST_SM3: *digestLen = HKS_DIGEST_SM3_LEN; break; + case HKS_DIGEST_NONE: + *digestLen = 0; + break; default: return HKS_ERROR_INVALID_DIGEST; } diff --git a/interfaces/inner_api/huks_standard/main/include/hks_type.h b/interfaces/inner_api/huks_standard/main/include/hks_type.h index d33b39ca..ac4c1c9a 100644 --- a/interfaces/inner_api/huks_standard/main/include/hks_type.h +++ b/interfaces/inner_api/huks_standard/main/include/hks_type.h @@ -115,8 +115,8 @@ enum HksKeyType { * @brief hks key purpose */ enum HksKeyPurpose { - HKS_KEY_PURPOSE_ENCRYPT = 1, /* Usable with RSA, EC, AES, and SM4 keys. */ - HKS_KEY_PURPOSE_DECRYPT = 2, /* Usable with RSA, EC, AES, and SM4 keys. */ + HKS_KEY_PURPOSE_ENCRYPT = 1, /* Usable with RSA, EC, AES, SM2, and SM4 keys. */ + HKS_KEY_PURPOSE_DECRYPT = 2, /* Usable with RSA, EC, AES, SM2, and SM4 keys. */ HKS_KEY_PURPOSE_SIGN = 4, /* Usable with RSA, EC keys. */ HKS_KEY_PURPOSE_VERIFY = 8, /* Usable with RSA, EC keys. */ HKS_KEY_PURPOSE_DERIVE = 16, /* Usable with EC keys. */ diff --git a/services/huks_standard/huks_engine/main/core/src/hks_core_service_three_stage.c b/services/huks_standard/huks_engine/main/core/src/hks_core_service_three_stage.c index d46bb685..64fc21a5 100644 --- a/services/huks_standard/huks_engine/main/core/src/hks_core_service_three_stage.c +++ b/services/huks_standard/huks_engine/main/core/src/hks_core_service_three_stage.c @@ -51,6 +51,7 @@ #endif #define HKS_RSA_OAEP_DIGEST_NUM 2 +#define HKS_SM2_Len_C1_NUM 2 #define HKS_BLOCK_CIPHER_CBC_BLOCK_SIZE 16 #define HKS_TEMP_SIZE 32 #define MAX_BUF_SIZE (5 * 1024 * 1024) @@ -96,6 +97,27 @@ static int32_t CheckRsaCipherData(bool isEncrypt, uint32_t keyLen, struct HksUsa return HKS_SUCCESS; } +static int32_t CheckSm2CipherData(bool isEncrypt, struct HksUsageSpec *usageSpec, const struct HksBlob *inData, + const struct HksBlob *outData) +{ + if(isEncrypt) { + uint32_t digest = usageSpec->digest; + uint32_t digestLen; + int32_t ret = HksGetDigestLen(digest, &digestLen); + HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetDigestLen failed, ret = %" LOG_PUBLIC "x", ret) + + uint32_t lenC1 = HKS_SM2_Len_C1_NUM * HKS_SM2_KEY_SIZE_256 + 1; + uint32_t needLen = (lenC1 + digestLen + inData->size); + + if (outData->size < needLen) { + HKS_LOG_E("encrypt, outData buffer too small size: %" LOG_PUBLIC "u, needLen: %" LOG_PUBLIC "d", + outData->size, needLen); + return HKS_ERROR_BUFFER_TOO_SMALL; + } + } + return HKS_SUCCESS; +} + static int32_t CheckAesCipherAead(bool isEncrypt, const struct HksBlob *inData, const struct HksBlob *outData) { @@ -179,6 +201,8 @@ static int32_t HksCheckFinishOutSize(bool isEncrypt, struct HksParamSet *paramSe switch (alg) { case HKS_ALG_RSA: return CheckRsaCipherData(isEncrypt, cihperSpec.keyLen, &usageSpec, outData); + case HKS_ALG_SM2: + return CheckSm2CipherData(isEncrypt, &usageSpec, inData, outData); case HKS_ALG_AES: return CheckBlockCipherData(isEncrypt, &usageSpec, inData, outData); case HKS_ALG_SM4: @@ -347,7 +371,7 @@ static int32_t UpdateCachedData(const struct HuksKeyNode *keyNode, const struct ret = GetNewCachedData(cachedData, srcData, newCachedBlob); if (ret != HKS_SUCCESS) { - HKS_LOG_E("get mew cached data failed, ret = %" LOG_PUBLIC "d", ret); + HKS_LOG_E("get new cached data failed, ret = %" LOG_PUBLIC "d", ret); HKS_FREE_PTR(newCachedBlob); return ret; } @@ -743,18 +767,66 @@ static int32_t RsaCipherFinish(const struct HuksKeyNode *keyNode, const struct H return ret; } +static int32_t Sm2CipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData, + struct HksBlob *outData) +{ + HKS_LOG_E("sm2 CipherFinish, inData.size = %" LOG_PUBLIC "u", inData->size); + struct HksBlob rawKey = { 0, NULL }; + int32_t ret = HksGetRawKey(keyNode->keyBlobParamSet, &rawKey); + HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "SignVerify get raw key failed!") + + struct HksUsageSpec usageSpec; + (void)memset_s(&usageSpec, sizeof(struct HksUsageSpec), 0, sizeof(struct HksUsageSpec)); + HksFillUsageSpec(keyNode->runtimeParamSet, &usageSpec); + + bool isEncrypt = (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT) ? true : false; + ret = HksCheckFinishOutSize(isEncrypt, keyNode->runtimeParamSet, inData, outData); + if (ret != HKS_SUCCESS) { + HKS_LOG_E("sm2 cipher finish check data size failed"); + (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size); + HKS_FREE_PTR(rawKey.data); + return ret; + } + + if (usageSpec.purpose == HKS_KEY_PURPOSE_ENCRYPT) { + struct HksBlob tag = { 0, NULL }; + ret = HksCryptoHalEncrypt(&rawKey, &usageSpec, inData, outData, &tag); + } else { + ret = HksCryptoHalDecrypt(&rawKey, &usageSpec, inData, outData); + } + HKS_IF_NOT_SUCC_LOGE(ret, "sm2 cipher Finish failed, purpose = 0x%" LOG_PUBLIC "x, ret = %" LOG_PUBLIC "d", + usageSpec.purpose, ret) + + (void)memset_s(rawKey.data, rawKey.size, 0, rawKey.size); + HKS_FREE_PTR(rawKey.data); + return ret; +} + static int32_t CoreRsaCipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData, struct HksBlob *outData) { + struct HksBlob tempInData = { 0, NULL }; int32_t ret = FinishCachedData(keyNode, inData, &tempInData); - HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get rsa cipher cached data faile") + HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get rsa cipher cached data failed") ret = RsaCipherFinish(keyNode, &tempInData, outData); HKS_FREE_BLOB(tempInData); return ret; } +static int32_t CoreSm2CipherFinish(const struct HuksKeyNode *keyNode, const struct HksBlob *inData, + struct HksBlob *outData) +{ + struct HksBlob tempInData = { 0, NULL }; + int32_t ret = FinishCachedData(keyNode, inData, &tempInData); + HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get sm2 cipher cached data failed") + + ret = Sm2CipherFinish(keyNode, &tempInData, outData); + HKS_FREE_BLOB(tempInData); + return ret; +} + static void FreeCryptoCtx(const struct HuksKeyNode *keyNode, uint32_t alg) { struct HksParam *ctxParam = NULL; @@ -971,7 +1043,7 @@ int32_t HksCoreCryptoThreeStageUpdate(const struct HuksKeyNode *keyNode, const s HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL, "get param get 0x%" LOG_PUBLIC "x failed", HKS_TAG_ALGORITHM) - if (algParam->uint32Param == HKS_ALG_RSA) { + if ((algParam->uint32Param == HKS_ALG_RSA) || (algParam->uint32Param == HKS_ALG_SM2)) { return UpdateCachedData(keyNode, inData); } else if (algParam->uint32Param == HKS_ALG_AES) { return CoreCipherUpdate(keyNode, inData, outData, alg); @@ -995,6 +1067,8 @@ int32_t HksCoreEncryptThreeStageFinish(const struct HuksKeyNode *keyNode, const if (algParam->uint32Param == HKS_ALG_RSA) { return CoreRsaCipherFinish(keyNode, inData, outData); + } else if (algParam->uint32Param == HKS_ALG_SM2) { + return CoreSm2CipherFinish(keyNode, inData, outData); } else if (algParam->uint32Param == HKS_ALG_AES) { return CoreAesEncryptFinish(keyNode, inData, outData, alg); } else if (algParam->uint32Param == HKS_ALG_SM4) { @@ -1017,6 +1091,8 @@ int32_t HksCoreDecryptThreeStageFinish(const struct HuksKeyNode *keyNode, const if (algParam->uint32Param == HKS_ALG_RSA) { return CoreRsaCipherFinish(keyNode, inData, outData); + } else if (algParam->uint32Param == HKS_ALG_SM2) { + return CoreSm2CipherFinish(keyNode, inData, outData); } else if (algParam->uint32Param == HKS_ALG_AES) { return CoreAesDecryptFinish(keyNode, inData, outData, alg); } else if (algParam->uint32Param == HKS_ALG_SM4) { diff --git a/test/unittest/huks_standard_test/three_stage_test/BUILD.gn b/test/unittest/huks_standard_test/three_stage_test/BUILD.gn index a5f77e4f..eb315db7 100644 --- a/test/unittest/huks_standard_test/three_stage_test/BUILD.gn +++ b/test/unittest/huks_standard_test/three_stage_test/BUILD.gn @@ -79,6 +79,7 @@ ohos_unittest("huks_UT_test") { "src/asymmetric_alg_test/hks_ecc_sign_verify_part1_test.cpp", "src/asymmetric_alg_test/hks_rsa_cipher_part1_test.cpp", "src/asymmetric_alg_test/hks_rsa_cipher_part2_test.cpp", + "src/asymmetric_alg_test/hks_sm2_cipher_test.cpp", "src/asymmetric_alg_test/hks_rsa_sign_verify_part1_test.cpp", "src/asymmetric_alg_test/hks_rsa_sign_verify_part2_test.cpp", "src/asymmetric_alg_test/hks_rsa_sign_verify_part3_test.cpp", diff --git a/test/unittest/huks_standard_test/three_stage_test/include/asymmetric_alg_test/hks_sm2_cipher_test.h b/test/unittest/huks_standard_test/three_stage_test/include/asymmetric_alg_test/hks_sm2_cipher_test.h new file mode 100644 index 00000000..34cd1166 --- /dev/null +++ b/test/unittest/huks_standard_test/three_stage_test/include/asymmetric_alg_test/hks_sm2_cipher_test.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef HKS_SM2_COMMON_TEST_H +#define HKS_SM2_COMMON_TEST_H + +#include +#include +#include "hks_in_data_array_after_hash_test_common.h" +#include "hks_three_stage_test_common.h" + +#define inDataArrSize 8 + + +namespace Unittest::Sm2Cipher { +static const uint32_t SM2_COMMON_SIZE = 1024; +static const std::string g_inData = "Hks_SM2_Sign_Verify_Test_000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000_string"; + +static const std::string g_inDataArr[] ={ "SM2_12_00000", + "SM2_14_0000000", + "SM2_63_00000000000000000000000000000000000000000000000000000000", + "SM2_64_000000000000000000000000000000000000000000000000000000000", + "SM2_65_0000000000000000000000000000000000000000000000000000000000", + "SM2_96_000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", + "SM2_128_00000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", + "SM2_256_00000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" +}; + +struct TestCaseParam { + uint32_t id; + int32_t result; + std::vector params; +}; + +struct GenEncryptDecryptParam { + struct TestCaseParam gen; + struct TestCaseParam encrypt; + struct TestCaseParam decrypt; +}; + +int HksSm2CipherTest001(void); + +int HksSm2CipherTest002(void); + +int HksSm2CipherTest003(void); +} // namespace Unittest::Sm2Cipher +#endif // HKS_SM2_COMMON_TEST_COMMON_H \ No newline at end of file diff --git a/test/unittest/huks_standard_test/three_stage_test/src/asymmetric_alg_test/hks_sm2_cipher_test.cpp b/test/unittest/huks_standard_test/three_stage_test/src/asymmetric_alg_test/hks_sm2_cipher_test.cpp new file mode 100644 index 00000000..074a84ce --- /dev/null +++ b/test/unittest/huks_standard_test/three_stage_test/src/asymmetric_alg_test/hks_sm2_cipher_test.cpp @@ -0,0 +1,601 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifdef L2_STANDARD +#include "file_ex.h" +#endif +#include "hks_sm2_cipher_test.h" +#include "hks_type.h" +#include "hks_log.h" + +#include +#include + +using namespace testing::ext; +namespace Unittest::Sm2Cipher { +class HksSm2CipherTest : public testing::Test { +public: + static void SetUpTestCase(void); + + static void TearDownTestCase(void); + + void SetUp(); + + void TearDown(); +}; + +void HksSm2CipherTest::SetUpTestCase(void) +{ +#ifdef L2_STANDARD + OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "0"); +#endif +} + +void HksSm2CipherTest::TearDownTestCase(void) +{ +#ifdef L2_STANDARD + OHOS::SaveStringToFile("/sys/fs/selinux/enforce", "1"); +#endif +} + +void HksSm2CipherTest::SetUp() +{ + EXPECT_EQ(HksInitialize(), 0); +} + +void HksSm2CipherTest::TearDown() +{ +} + +static const struct TestCaseParam POSITIVE_CASE_GEN_PARAM = { + 0, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, +}; + +static const struct TestCaseParam NEGATIVE_CASE_GEN_PARAMS[] = { + { + 1, + HKS_ERROR_INVALID_KEY_SIZE, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_AES_KEY_SIZE_512 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, + }, + + { + 2, + HKS_ERROR_INVALID_DIGEST, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SHA1 + }, + }, + }, + + { + 3, + HKS_ERROR_INVALID_PURPOSE, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_WRAP + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, + }, + { + 4, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT + } + }, + } +}; + +static const struct TestCaseParam NON_DIGEST_CASE_GEN_PARAM = { + 4, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT + } + }, +}; + +static const struct TestCaseParam POSITIVE_CASE_ENCRYPT_PARAM = { + 0, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, +}; + +static const struct TestCaseParam NEGATIVE_CASE_ENCRYPT_PARAMS[] = { + { + 1, + HKS_ERROR_INVALID_KEY_SIZE, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_AES_KEY_SIZE_512 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, + }, + + { + 2, + HKS_ERROR_INVALID_DIGEST, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SHA1 + }, + }, + }, + { + 3, + HKS_ERROR_INVALID_DIGEST, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_MD5 + }, + }, + }, + { + 4, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_NONE + }, + } + } +}; + +static const struct TestCaseParam NON_DIGEST_CASE_ENCRYPT_PARAM = { + 4, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_ENCRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_NONE + }, + }, +}; + +static const struct TestCaseParam POSITIVE_CASE_DECRYPT_PARAM = { + 0, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, +}; + +static const struct TestCaseParam NEGATIVE_CASE_DECRYPT_PARAMS[] = { + { + 1, + HKS_ERROR_INVALID_KEY_SIZE, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_AES_KEY_SIZE_512 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SM3 + }, + }, + }, + + { + 2, + HKS_ERROR_INVALID_ARGUMENT, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_SHA1 + }, + }, + }, +}; + +static const struct TestCaseParam NON_DIGEST_CASE_DECRYPT_PARAM = { + 4, + HKS_SUCCESS, + { + { + .tag = HKS_TAG_ALGORITHM, + .uint32Param = HKS_ALG_SM2 + }, { + .tag = HKS_TAG_KEY_SIZE, + .uint32Param = HKS_SM2_KEY_SIZE_256 + }, { + .tag = HKS_TAG_PURPOSE, + .uint32Param = HKS_KEY_PURPOSE_DECRYPT + }, { + .tag = HKS_TAG_DIGEST, + .uint32Param = HKS_DIGEST_NONE + }, + }, +}; + + +static int32_t HksSm2CipherTestEncrypt(const struct HksBlob *keyAlias, + const struct HksParamSet *encryptParamSet, const struct HksBlob *inData, struct HksBlob *cipherText) +{ + uint8_t handleE[sizeof(uint64_t)] = {0}; + struct HksBlob handleEncrypt = { sizeof(uint64_t), handleE }; + int32_t ret = HksInit(keyAlias, encryptParamSet, &handleEncrypt, nullptr); + EXPECT_EQ(ret, HKS_SUCCESS) << "HksSm2CipherTestEncrypt ->Init failed."; + if (ret != HKS_SUCCESS) { + return ret; + } + + ret = TestUpdateFinish(&handleEncrypt, encryptParamSet, HKS_KEY_PURPOSE_ENCRYPT, inData, cipherText); + EXPECT_EQ(ret, HKS_SUCCESS) << "TestUpdateFinish failed."; + if (ret != HKS_SUCCESS) { + return ret; + } + EXPECT_NE(HksMemCmp(inData->data, cipherText->data, inData->size), HKS_SUCCESS) << "cipherText equals inData"; + + uint8_t tmpOut[SM2_COMMON_SIZE] = {0}; + struct HksBlob outData = { SM2_COMMON_SIZE, tmpOut }; + ret = HksEncrypt(keyAlias, encryptParamSet, inData, &outData); + EXPECT_EQ(ret, HKS_SUCCESS) << "HksEncrypt failed."; + if (ret != HKS_SUCCESS) { + return ret; + } + + return HKS_SUCCESS; +} + +static int32_t HksSm2CipherTestDecrypt(const struct HksBlob *keyAlias, const struct HksParamSet *decryptParamSet, + const struct HksBlob *cipherText, struct HksBlob *plainText, const struct HksBlob *inData) +{ + uint8_t handleD[sizeof(uint64_t)] = {0}; + struct HksBlob handleDecrypt = { sizeof(uint64_t), handleD }; + int32_t ret = HksInit(keyAlias, decryptParamSet, &handleDecrypt, nullptr); + if (ret != HKS_SUCCESS) { + return ret; + } + + ret = TestUpdateFinish(&handleDecrypt, decryptParamSet, HKS_KEY_PURPOSE_DECRYPT, cipherText, plainText); + if (ret != HKS_SUCCESS) { + return ret; + } + EXPECT_EQ(HksMemCmp(inData->data, plainText->data, inData->size), HKS_SUCCESS) << "plainText not equals inData"; + + uint8_t tmpOut[SM2_COMMON_SIZE] = {0}; + struct HksBlob outData = { SM2_COMMON_SIZE, tmpOut }; + ret = HksDecrypt(keyAlias, decryptParamSet, cipherText, &outData); + if (ret != HKS_SUCCESS) { + return ret; + } + EXPECT_EQ(HksMemCmp(outData.data, plainText->data, outData.size), HKS_SUCCESS) << "plainText not equals outData"; + + return HKS_SUCCESS; +} + +static int32_t HksSm2CipherTestRun(const struct HksBlob *keyAlias, const GenEncryptDecryptParam ¶m, + const struct HksBlob *inData) +{ + struct HksParamSet *genParamSet = nullptr; + struct HksParamSet *encryptParamSet = nullptr; + struct HksParamSet *decryptParamSet = nullptr; + int32_t ret; + ret = InitParamSet(&genParamSet, param.gen.params.data(), param.gen.params.size()); + EXPECT_EQ(ret, HKS_SUCCESS) << "InitGenParamSet failed."; + + ret = InitParamSet(&encryptParamSet, param.encrypt.params.data(), param.encrypt.params.size()); + EXPECT_EQ(ret, HKS_SUCCESS) << "InitEncryptParamSet failed."; + + char tmpKey[] = "SM2_Encrypt_Decrypt_KeyAlias"; + struct HksBlob newKeyAlias = { .size = strlen(tmpKey), .data = reinterpret_cast(tmpKey) }; + + uint8_t pubKey[HKS_SM2_KEY_SIZE_256] = {0}; + struct HksBlob publicKey = { HKS_SM2_KEY_SIZE_256, pubKey }; + + do { + /* 1. Generate Key */ + ret = HksGenerateKey(keyAlias, genParamSet, nullptr); + + if (ret != HKS_SUCCESS) { + ret = ((ret == param.gen.result) ? HKS_SUCCESS : ret); + EXPECT_EQ(ret, HKS_SUCCESS) << "Generate Key err code don't meet expectation."; + break; + } + + /* 2. Export Public Key */ + ret = HksExportPublicKey(keyAlias, genParamSet, &publicKey); + EXPECT_EQ(ret, HKS_SUCCESS) << "ExportPublicKey failed."; + + /* 3. Import Key */ + ret = HksImportKey(&newKeyAlias, encryptParamSet, &publicKey); + if (ret != HKS_SUCCESS) { + ret = ((ret == param.encrypt.result) ? HKS_SUCCESS : ret); + EXPECT_EQ(ret, HKS_SUCCESS) << "Import Key failed."; + break; + } + + /* 4. Encrypt Three Stage */ + uint8_t cipher[SM2_COMMON_SIZE] = {0}; + struct HksBlob cipherText = { SM2_COMMON_SIZE, cipher }; + ret = HksSm2CipherTestEncrypt(&newKeyAlias, encryptParamSet, inData, &cipherText); + EXPECT_EQ(ret, HKS_SUCCESS) << "HksSm2CipherTestEncrypt failed."; + if (ret != HKS_SUCCESS) { + ret = ((ret == param.encrypt.result) ? HKS_SUCCESS : ret); + EXPECT_EQ(ret, HKS_SUCCESS) << "Encrypt Three Stage: err code don't meet expectation."; + break; + } + + /* 5. Decrypt Three Stage */ + ret = InitParamSet(&decryptParamSet, param.decrypt.params.data(), param.decrypt.params.size()); + EXPECT_EQ(ret, HKS_SUCCESS) << "InitDecryptParamSet failed."; + + uint8_t plain[SM2_COMMON_SIZE] = {0}; + struct HksBlob plainText = { SM2_COMMON_SIZE, plain }; + ret = HksSm2CipherTestDecrypt(keyAlias, decryptParamSet, &cipherText, &plainText, inData); + if (ret != HKS_SUCCESS) { + ret = ((ret == param.decrypt.result) ? HKS_SUCCESS : ret); + EXPECT_EQ(ret, HKS_SUCCESS) << "Decrypt Three Stage: err code don't meet expectation."; + break; + } + + /* 6. Delete Key */ + EXPECT_EQ(HksDeleteKey(keyAlias, genParamSet), HKS_SUCCESS) << "DeleteKey failed."; + EXPECT_EQ(HksDeleteKey(&newKeyAlias, encryptParamSet), HKS_SUCCESS) << "Delete ImportKey failed."; + } while (0); + + + HksFreeParamSet(&genParamSet); + HksFreeParamSet(&encryptParamSet); + HksFreeParamSet(&decryptParamSet); + return ret; +} + +/** + * @tc.name: HksSm2CipherTest.HksSm2CipherTest001 + * @tc.desc: normal parameter test case : alg-SM2, pur-encrypt/decrypt, keySize-256 and dig-SM3. + * @tc.type: FUNC + */ +HWTEST_F(HksSm2CipherTest, HksSm2CipherTest001, TestSize.Level0) +{ + HKS_LOG_E("Enter HksSm2CipherTest001"); + const char *keyAliasString = "HksSm2CipherTest001AliasTest001"; + struct HksBlob keyAlias = { strlen(keyAliasString), (uint8_t *)keyAliasString }; + struct HksBlob inData = { g_inData.length(), (uint8_t *)g_inData.c_str() }; + GenEncryptDecryptParam param { POSITIVE_CASE_GEN_PARAM, POSITIVE_CASE_ENCRYPT_PARAM, POSITIVE_CASE_DECRYPT_PARAM }; + int ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest001 failed."; +} + +/** + * @tc.name: HksSm2CipherTest.HksSm2CipherTest002 + * @tc.desc: abnormal parameter test cases : the abnormal parameter is tag + * @tc.type: FUNC + */ +HWTEST_F(HksSm2CipherTest, HksSm2CipherTest002, TestSize.Level0) +{ + HKS_LOG_E("Enter HksSm2CipherTest002"); + const char *keyAliasString = "HksSM2CipherKeyAliasTest002"; + struct HksBlob keyAlias = { strlen(keyAliasString), (uint8_t *)keyAliasString }; + struct HksBlob inData = { g_inData.length(), (uint8_t *)g_inData.c_str() }; + + int ret; + for (const struct TestCaseParam &negativeGenParam : NEGATIVE_CASE_GEN_PARAMS) { + GenEncryptDecryptParam param { negativeGenParam, POSITIVE_CASE_ENCRYPT_PARAM, POSITIVE_CASE_DECRYPT_PARAM }; + ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest002 gen abnormal test failed."; + } + + for (const struct TestCaseParam &negativeEncryptParam : NEGATIVE_CASE_ENCRYPT_PARAMS) { + GenEncryptDecryptParam param { POSITIVE_CASE_GEN_PARAM, negativeEncryptParam, POSITIVE_CASE_DECRYPT_PARAM }; + ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest002 encrypt abnormal test failed."; + } + + for (const struct TestCaseParam &negativeDecryptParam : NEGATIVE_CASE_DECRYPT_PARAMS) { + GenEncryptDecryptParam param { POSITIVE_CASE_GEN_PARAM, POSITIVE_CASE_ENCRYPT_PARAM, negativeDecryptParam }; + ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest002 decrypt abnormal test failed."; + } +} + +/** + * @tc.name: HksSm2CipherTest.HksSm2CipherTest003 + * @tc.desc: normal parameter test case : alg-SM2, pur-encrypt/decrypt, + * keySize-256 and dig-NONE, message size is SM3 digest size + * @tc.type: FUNC + * @tc.require:issueI611S5 + */ +HWTEST_F(HksSm2CipherTest, HksSm2CipherTest003, TestSize.Level0) +{ + HKS_LOG_E("Enter HksSm2CipherTest003"); + const char *keyAliasString = "HksSM2CipherKeyAliasTest003"; + struct HksBlob keyAlias = { strlen(keyAliasString), (uint8_t *)keyAliasString }; + struct HksBlob inData = { sizeof(DATA_AFTER_SHA256_HASH), (uint8_t *)DATA_AFTER_SHA256_HASH }; + GenEncryptDecryptParam param { NON_DIGEST_CASE_GEN_PARAM, NON_DIGEST_CASE_ENCRYPT_PARAM, NON_DIGEST_CASE_DECRYPT_PARAM }; + int ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest003 failed."; +} + + +/** + * @tc.name: HksSm2CipherTest.HksSm2CipherTest004 + * @tc.desc: normal parameter test case : alg-SM2, pur-encrypt/decrypt, keySize-256 and dig-SM3. + * @tc.type: FUNC + */ +HWTEST_F(HksSm2CipherTest, HksSm2CipherTest004, TestSize.Level0) +{ + HKS_LOG_E("Enter HksSm2CipherTest004"); + const char *keyAliasString = "HksSm2CipherTest004AliasTest004"; + struct HksBlob keyAlias = { strlen(keyAliasString), (uint8_t *)keyAliasString }; + for (int16_t i = 0; i < inDataArrSize; i++) { + struct HksBlob inData = { g_inDataArr[i].length(), (uint8_t *)g_inDataArr[i].c_str() }; + GenEncryptDecryptParam param { POSITIVE_CASE_GEN_PARAM, POSITIVE_CASE_ENCRYPT_PARAM, POSITIVE_CASE_DECRYPT_PARAM }; + int ret = HksSm2CipherTestRun(&keyAlias, param, &inData); + EXPECT_EQ(ret, HKS_SUCCESS) << "sm2CipherTest004 failed."; + } +} + +} + + -- Gitee