diff --git a/BUILD.gn b/BUILD.gn index 5b63a968661ab9de478ae0d4f36d465326df8252..cab89629c627888db43df4869e3cb9b2163df9f6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -11,6 +11,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +declare_args() { + crypto_framework_enabled = true +} + group("crypto_framework_component") { if (os_level == "standard") { deps = [ diff --git a/README_zh.md b/README_zh.md index 45f5b4ee6f2f52b7127cd85c7993164ebd64dac7..7cad669c1c0cf04775ae0c473812160b9adc5126 100644 --- a/README_zh.md +++ b/README_zh.md @@ -35,7 +35,7 @@ base/security/crypto_framwork ## 说明 ### 接口说明 -- [加解密算法库框架-API参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md) +- [加解密算法库框架-API参考](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-crypto-architecture-kit/js-apis-cryptoFramework.md) ### 使用说明 diff --git a/bundle.json b/bundle.json index 11c5ca2d0b0929178f0311e6466634dceb18b207..66b071df07e99ab7fbb261cadac4c93e6ef69728 100644 --- a/bundle.json +++ b/bundle.json @@ -25,12 +25,11 @@ "components": [ "hilog", "c_utils", - "napi" - ], - "third_party": [ + "napi", "openssl", "bounds_checking_function" - ] + ], + "third_party": [] }, "build": { "sub_component": [ @@ -53,6 +52,7 @@ "algorithm_parameter/detailed_pbkdf2_params.h", "algorithm_parameter/detailed_rsa_key_params.h", "algorithm_parameter/kdf_params.h", + "algorithm_parameter/sm2_crypto_params.h", "common/big_integer.h", "common/blob.h", "common/object_base.h", diff --git a/common/BUILD.gn b/common/BUILD.gn index 512ae8620d6c456832aa3f68009dc40c288e1676..f216116e63dfb9e5d80563c1d236932a79848f11 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -17,11 +17,7 @@ import("//build/ohos.gni") ohos_static_library("crypto_plugin_common") { subsystem_name = "security" part_name = "crypto_framework" - include_dirs = [ - "//commonlibrary/c_utils/base/include", - "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", - ] - include_dirs += crypto_framwork_common_inc_path + include_dirs = crypto_framwork_common_inc_path sources = crypto_framwork_common_files @@ -30,7 +26,6 @@ ohos_static_library("crypto_plugin_common") { cfi = true cfi_cross_dso = true debug = false - blocklist = "//base/security/crypto_framework/cfi_blocklist.txt" } } diff --git a/common/common.gni b/common/common.gni index 80da1f7d29ee7825bf4816df764abf37253b4032..5253c1ae9a79e77a2a7f0e5310eafe499929edff 100644 --- a/common/common.gni +++ b/common/common.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Huawei Device Co., Ltd. +# Copyright (C) 2022-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 @@ -21,7 +21,6 @@ framework_common_util_files = [ "//base/security/crypto_framework/common/src/asy_key_params.c", "//base/security/crypto_framework/common/src/blob.c", "//base/security/crypto_framework/common/src/utils.c", - "//base/security/crypto_framework/common/src/log.c", "//base/security/crypto_framework/common/src/memory.c", "//base/security/crypto_framework/common/src/hcf_parcel.c", "//base/security/crypto_framework/common/src/hcf_string.c", diff --git a/common/inc/log.h b/common/inc/log.h index 0431a5e8e66837674948f241cccc5a027452b6b7..c0d2ebc25265b5713042777a319693a83b046bb3 100644 --- a/common/inc/log.h +++ b/common/inc/log.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -18,38 +18,18 @@ #ifdef HILOG_ENABLE -typedef enum { - HCF_LOG_LEVEL_DEBUG = 0, - HCF_LOG_LEVEL_INFO = 1, - HCF_LOG_LEVEL_WARN = 2, - HCF_LOG_LEVEL_ERROR = 3 -} HcfLogLevel; - -#ifdef __cplusplus -extern "C" { -#endif - -void HcfLogPrint(HcfLogLevel level, const char *funName, const char *fmt, ...); - -#ifdef __cplusplus -} -#endif - #include "hilog/log.h" -#ifndef CRYPTO_LOG_DOMAIN -#define CRYPTO_LOG_DOMAIN 0xD002F10 /* Security subsystem's domain id */ -#endif +#undef LOG_TAG +#define LOG_TAG "HCF" -#define LOGD(fmt, ...) (HcfLogPrint(HCF_LOG_LEVEL_DEBUG, __FUNCTION__, fmt, ##__VA_ARGS__)) -#define LOGI(fmt, ...) (HcfLogPrint(HCF_LOG_LEVEL_INFO, __FUNCTION__, fmt, ##__VA_ARGS__)) -#define LOGW(fmt, ...) (HcfLogPrint(HCF_LOG_LEVEL_WARN, __FUNCTION__, fmt, ##__VA_ARGS__)) -#define LOGE(fmt, ...) (HcfLogPrint(HCF_LOG_LEVEL_ERROR, __FUNCTION__, fmt, ##__VA_ARGS__)) +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD002F0A /* Security subsystem's domain id */ -#define HCF_LOG_DEBUG(fmt, ...) HiLogPrint(LOG_CORE, LOG_DEBUG, CRYPTO_LOG_DOMAIN, "[HCF]", "%{public}s", buf) -#define HCF_LOG_INFO(buf) HiLogPrint(LOG_CORE, LOG_INFO, CRYPTO_LOG_DOMAIN, "[HCF]", "%{public}s", buf) -#define HCF_LOG_WARN(buf) HiLogPrint(LOG_CORE, LOG_WARN, CRYPTO_LOG_DOMAIN, "[HCF]", "%{public}s", buf) -#define HCF_LOG_ERROR(buf) HiLogPrint(LOG_CORE, LOG_ERROR, CRYPTO_LOG_DOMAIN, "[HCF]", "%{public}s", buf) +#define LOGD(fmt, ...) HILOG_DEBUG(LOG_CORE, "[%{public}s] " fmt, __func__, ##__VA_ARGS__) +#define LOGI(fmt, ...) HILOG_INFO(LOG_CORE, "[%{public}s] " fmt, __func__, ##__VA_ARGS__) +#define LOGW(fmt, ...) HILOG_WARN(LOG_CORE, "[%{public}s] " fmt, __func__, ##__VA_ARGS__) +#define LOGE(fmt, ...) HILOG_DEBUG(LOG_CORE, "[%{public}s] " fmt, __func__, ##__VA_ARGS__) #else diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index 8fd6422d5e4c9e9e62de31609cace30a69d02f8e..6e333c6aa865f45cbf56d984d331f0b0ab7b5053 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2022-2023 Huawei Device Co., Ltd. +* Copyright (C) 2022-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 @@ -28,6 +28,8 @@ typedef enum { HCF_ALG_DIGEST, HCF_ALG_MGF1_DIGEST, HCF_ALG_TEXT_FORMAT, + HCF_ALG_SIGN_TYPE, + HCF_ALG_VERIFY_TYPE, } HcfAlgParaType; typedef enum { @@ -44,6 +46,7 @@ typedef enum { HCF_ALG_ED25519, HCF_ALG_X25519, HCF_ALG_DH, + HCF_ALG_HKDF, } HcfAlgValue; typedef enum { @@ -165,8 +168,33 @@ typedef enum { HCF_OPENSSL_DH_FFDHE_4096, HCF_OPENSSL_DH_FFDHE_6144, HCF_OPENSSL_DH_FFDHE_8192, + + HCF_ALG_ONLY_SIGN, + HCF_ALG_VERIFY_RECOVER, + // key derivation function, HKDF + HCF_ALG_HKDF_DEFAULT, + + // hkdf mode + HCF_ALG_MODE_EXTRACT_AND_EXPAND, + HCF_ALG_MODE_EXTRACT_ONLY, + HCF_ALG_MODE_EXPAND_ONLY, } HcfAlgParaValue; +typedef enum { + HCF_OPERATIOPN_ONLY_SIGN = 1, + HCF_OPERATION_SIGN, +} HcfSignParams; + +typedef enum { + HCF_UNCOMPRESSED_FORMAT_VALUE = 1, + HCF_COMPRESSED_FORMAT_VALUE, +} HcfFormatValue; + +typedef struct { + const char *formatName; + HcfFormatValue formatValue; +} HcfFormatMap; + typedef struct { const char *tag; HcfAlgParaType paraType; @@ -203,6 +231,7 @@ typedef struct { HcfAlgParaValue padding; HcfAlgParaValue md; HcfAlgParaValue mgf1md; + HcfAlgParaValue operation; } HcfSignatureParams; typedef struct { @@ -212,6 +241,7 @@ typedef struct { typedef struct { HcfAlgValue algo; // algType HcfAlgParaValue md; + HcfAlgParaValue mode; } HcfKdfDeriveParams; typedef HcfResult (*SetParameterFunc) (const HcfParaConfig* config, void *params); @@ -226,6 +256,10 @@ HcfResult ParseAlgNameToParams(const char *algNameStr, HcfAsyKeyGenParams *param HcfResult ParseCurveNameToParams(const char *curveNameStr, HcfAsyKeyGenParams *params); +HcfResult GetAlgValueByCurveName(const char *curveNameStr, HcfAlgParaValue *algValue); + +HcfResult GetFormatValueByFormatName(const char *formatName, HcfFormatValue *formatValue); + #ifdef __cplusplus } #endif diff --git a/common/src/asy_key_params.c b/common/src/asy_key_params.c index d7a7f1dbc8d611d5301278f67ca4e7ab84079e24..17dc9dc4ade3987d17416831d8dcd1a1ad592181 100644 --- a/common/src/asy_key_params.c +++ b/common/src/asy_key_params.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -25,6 +25,7 @@ #include "detailed_ecc_key_params.h" #include "detailed_rsa_key_params.h" #include "detailed_alg_25519_key_params.h" +#include "sm2_crypto_params.h" #include "memory.h" #include "log.h" @@ -162,8 +163,11 @@ static void FreeEcFieldMem(HcfECField **field) *field = NULL; } -static void FreeEcPointMem(HcfPoint *point) +void FreeEcPointMem(HcfPoint *point) { + if (point == NULL) { + return; + } HcfFree(point->x.data); point->x.data = NULL; HcfFree(point->y.data); @@ -462,3 +466,17 @@ void FreeAsyKeySpec(HcfAsyKeyParamsSpec *spec) } } +void DestroySm2CipherTextSpec(Sm2CipherTextSpec *spec) +{ + if (spec == NULL) { + return; + } + HcfFree(spec->xCoordinate.data); + spec->xCoordinate.data = NULL; + HcfFree(spec->yCoordinate.data); + spec->yCoordinate.data = NULL; + HcfBlobDataFree(&(spec->cipherTextData)); + HcfBlobDataFree(&(spec->hashData)); + HcfFree(spec); +} + diff --git a/common/src/params_parser.c b/common/src/params_parser.c index ab7f8fe4a0dd9e8510b53c06d4df754b844bfb82..bccee488b4fca43c4e85e32510558cf9e45327bb 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -110,6 +110,10 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"3DES", HCF_ALG_TYPE, HCF_ALG_3DES_DEFAULT}, {"HMAC", HCF_ALG_TYPE, HCF_ALG_HMAC_DEFAULT}, {"PBKDF2", HCF_ALG_TYPE, HCF_ALG_PBKDF2_DEFAULT}, + {"HKDF", HCF_ALG_TYPE, HCF_ALG_HKDF_DEFAULT}, + {"EXTRACT_AND_EXPAND", HCF_ALG_MODE, HCF_ALG_MODE_EXTRACT_AND_EXPAND}, + {"EXTRACT_ONLY", HCF_ALG_MODE, HCF_ALG_MODE_EXTRACT_ONLY}, + {"EXPAND_ONLY", HCF_ALG_MODE, HCF_ALG_MODE_EXPAND_ONLY}, {"ECC_BP", HCF_ALG_TYPE, HCF_ALG_ECC_BRAINPOOL_DEFAULT}, {"X25519_BP", HCF_ALG_TYPE, HCF_ALG_X25519_DEFAULT}, {"DH", HCF_ALG_TYPE, HCF_ALG_DH_DEFAULT}, @@ -133,7 +137,10 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"ECC_BrainPoolP512t1", HCF_ALG_KEY_TYPE, HCF_ALG_ECC_BP512T1}, {"Ed25519", HCF_ALG_KEY_TYPE, HCF_ALG_ED25519_256}, - {"X25519", HCF_ALG_KEY_TYPE, HCF_ALG_X25519_256} + {"X25519", HCF_ALG_KEY_TYPE, HCF_ALG_X25519_256}, + + {"OnlySign", HCF_ALG_SIGN_TYPE, HCF_ALG_ONLY_SIGN}, + {"Recover", HCF_ALG_VERIFY_TYPE, HCF_ALG_VERIFY_RECOVER} }; static const HcfAlgMap ALG_MAP[] = { @@ -168,6 +175,11 @@ static const HcfCurveMap CURVE_MAP[] = { {"NID_brainpoolP512t1", HCF_ALG_ECC_BP512T1} }; +static const HcfFormatMap FORMAT_MAP[] = { + {"UNCOMPRESSED", HCF_UNCOMPRESSED_FORMAT_VALUE}, + {"COMPRESSED", HCF_COMPRESSED_FORMAT_VALUE} +}; + static const HcfParaConfig *FindConfig(const HcString* tag) { if (tag == NULL) { @@ -259,3 +271,36 @@ HcfResult ParseCurveNameToParams(const char *curveNameStr, HcfAsyKeyGenParams *p LOGE("Not support algorithm name: %s", curveNameStr); return HCF_NOT_SUPPORT; } + +HcfResult GetAlgValueByCurveName(const char *curveNameStr, HcfAlgParaValue *algValue) +{ + if (curveNameStr == NULL || algValue == NULL) { + LOGE("Invalid parameter!"); + return HCF_INVALID_PARAMS; + } + for (uint32_t i = 0; i < sizeof(CURVE_MAP) / sizeof(CURVE_MAP[0]); i++) { + if (strcmp(CURVE_MAP[i].curveNameStr, curveNameStr) == 0) { + *algValue = CURVE_MAP[i].algValue; + return HCF_SUCCESS; + } + } + LOGE("Invalid curve name: %s", curveNameStr); + return HCF_INVALID_PARAMS; +} + +HcfResult GetFormatValueByFormatName(const char *formatName, HcfFormatValue *formatValue) +{ + if (formatName == NULL || formatValue == NULL) { + LOGE("Invalid parameter!"); + return HCF_INVALID_PARAMS; + } + + for (uint32_t i = 0; i < sizeof(FORMAT_MAP) / sizeof(FORMAT_MAP[0]); i++) { + if (strcmp(FORMAT_MAP[i].formatName, formatName) == 0) { + *formatValue = FORMAT_MAP[i].formatValue; + return HCF_SUCCESS; + } + } + LOGE("Invalid format name: %s", formatName); + return HCF_INVALID_PARAMS; +} diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn index ba063dc710aa3bec8f7f9bed723741db1463d7b5..11b713af5b01fecc4f989bee07094114f07deee6 100644 --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -29,11 +29,7 @@ ohos_shared_library("crypto_framework_lib") { innerapi_tags = [ "platformsdk" ] part_name = "crypto_framework" public_configs = [ ":framework_config" ] - include_dirs = [ - "//commonlibrary/c_utils/base/include", - "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", - ] - include_dirs += framework_inc_path + crypto_framwork_common_inc_path + include_dirs = framework_inc_path + crypto_framwork_common_inc_path sources = framework_files @@ -42,7 +38,6 @@ ohos_shared_library("crypto_framework_lib") { cfi = true cfi_cross_dso = true debug = false - blocklist = "//base/security/crypto_framework/cfi_blocklist.txt" } } diff --git a/frameworks/crypto_operation/kdf.c b/frameworks/crypto_operation/kdf.c index fe95cf5f1dfd2be01f585c4132af762a3fdefbf3..7d7a3c15809debb8491b89f32a5b292d2407c1f8 100644 --- a/frameworks/crypto_operation/kdf.c +++ b/frameworks/crypto_operation/kdf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -23,6 +23,7 @@ #include "log.h" #include "params_parser.h" #include "pbkdf2_openssl.h" +#include "hkdf_openssl.h" #include "utils.h" typedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **); @@ -44,6 +45,9 @@ static void SetKdfType(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) case HCF_ALG_PBKDF2_DEFAULT: kdf->algo = HCF_ALG_PKBDF2; break; + case HCF_ALG_HKDF_DEFAULT: + kdf->algo = HCF_ALG_HKDF; + break; default: LOGE("Invalid algo %u.", value); break; @@ -55,6 +59,11 @@ static void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) kdf->md = value; } +static void SetMode(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) +{ + kdf->mode = value; +} + static HcfResult ParseKdfParams(const HcfParaConfig *config, void *params) { if (config == NULL || params == NULL) { @@ -71,6 +80,9 @@ static HcfResult ParseKdfParams(const HcfParaConfig *config, void *params) case HCF_ALG_DIGEST: SetDigest(config->paraValue, paramsObj); break; + case HCF_ALG_MODE: + SetMode(config->paraValue, paramsObj); + break; default: ret = HCF_INVALID_PARAMS; break; @@ -80,6 +92,7 @@ static HcfResult ParseKdfParams(const HcfParaConfig *config, void *params) static const HcfKdfGenAbility KDF_ABILITY_SET[] = { { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate }, + { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate}, }; static HcfKdfSpiCreateFunc FindAbility(HcfKdfDeriveParams* params) diff --git a/frameworks/crypto_operation/mac.c b/frameworks/crypto_operation/mac.c index 06d60cb6564437b8f9ef08d90a978f4e9b451bc1..ef82eb606fa4bbc8271b401574a8d74ff37106ab 100644 --- a/frameworks/crypto_operation/mac.c +++ b/frameworks/crypto_operation/mac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -48,6 +48,7 @@ static const HcfMacAbility MAC_ABILITY_SET[] = { { "SHA384", OpensslMacSpiCreate }, { "SHA512", OpensslMacSpiCreate }, { "SM3", OpensslMacSpiCreate }, + { "MD5", OpensslMacSpiCreate }, }; static const char *GetMacClass(void) diff --git a/frameworks/crypto_operation/signature.c b/frameworks/crypto_operation/signature.c index da3cac429f92a3c59429127c26a8d1c6610b4677..1cbf53f7c108f3019966bfd450d660604161dfa3 100644 --- a/frameworks/crypto_operation/signature.c +++ b/frameworks/crypto_operation/signature.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -80,6 +80,11 @@ static const HcfVerifyGenAbility VERIFY_GEN_ABILITY_SET[] = { static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) { + if (params->operation == HCF_ALG_ONLY_SIGN && params->algo != HCF_ALG_RSA) { + LOGE("Algo not support in OnlySign! [Algo]: %d", params->algo); + return NULL; + } + for (uint32_t i = 0; i < sizeof(SIGN_GEN_ABILITY_SET) / sizeof(SIGN_GEN_ABILITY_SET[0]); i++) { if (SIGN_GEN_ABILITY_SET[i].algo == params->algo) { return SIGN_GEN_ABILITY_SET[i].createFunc; @@ -91,6 +96,11 @@ static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) static HcfVerifySpiCreateFunc FindVerifyAbility(HcfSignatureParams *params) { + if (params->operation == HCF_ALG_VERIFY_RECOVER && params->algo != HCF_ALG_RSA) { + LOGE("Failed to check recover params!"); + return NULL; + } + for (uint32_t i = 0; i < sizeof(VERIFY_GEN_ABILITY_SET) / sizeof(VERIFY_GEN_ABILITY_SET[0]); i++) { if (VERIFY_GEN_ABILITY_SET[i].algo == params->algo) { return VERIFY_GEN_ABILITY_SET[i].createFunc; @@ -200,6 +210,12 @@ static HcfResult ParseSignatureParams(const HcfParaConfig *config, void *params) case HCF_ALG_MGF1_DIGEST: paramsObj->mgf1md = config->paraValue; break; + case HCF_ALG_SIGN_TYPE: + paramsObj->operation = config->paraValue; + break; + case HCF_ALG_VERIFY_TYPE: + paramsObj->operation = config->paraValue; + break; default: ret = HCF_INVALID_PARAMS; break; @@ -466,6 +482,25 @@ static bool VerifyDoFinal(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData return ((HcfVerifyImpl *)self)->spiObj->engineVerify(((HcfVerifyImpl *)self)->spiObj, data, signatureData); } +static HcfResult VerifyRecover(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfVerifySpi *verifySpiObj = ((HcfVerifyImpl *)self)->spiObj; + if (verifySpiObj->engineRecover == NULL) { + LOGE("Not support verify recover operation."); + return HCF_INVALID_PARAMS; + } + + return verifySpiObj->engineRecover(verifySpiObj, signatureData, rawSignatureData); +} + HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) { LOGD("HcfSignCreate start"); @@ -559,6 +594,7 @@ HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) returnVerify->base.init = VerifyInit; returnVerify->base.update = VerifyUpdate; returnVerify->base.verify = VerifyDoFinal; + returnVerify->base.recover = VerifyRecover; returnVerify->base.setVerifySpecInt = SetVerifySpecInt; returnVerify->base.getVerifySpecInt = GetVerifySpecInt; returnVerify->base.getVerifySpecString = GetVerifySpecString; diff --git a/frameworks/crypto_operation/sm2_crypto_util.c b/frameworks/crypto_operation/sm2_crypto_util.c new file mode 100644 index 0000000000000000000000000000000000000000..a28cece0b31016348193ac5e23cd3dab407a63f1 --- /dev/null +++ b/frameworks/crypto_operation/sm2_crypto_util.c @@ -0,0 +1,135 @@ +/* + * 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 "sm2_crypto_util.h" +#include +#include "cipher_sm2_crypto_util_openssl.h" +#include "log.h" +#include "memory.h" +#include "utils.h" + +#define HCF_SM2_C3_LEN 32 + +typedef HcfResult (*HcfSm2SpecToASN1CreateFunc)(Sm2CipherTextSpec *spec, HcfBlob *output); + +typedef struct { + char *mode; + HcfSm2SpecToASN1CreateFunc createFunc; +} HcfSm2UtilAbility; + +static const HcfSm2UtilAbility CONVERT_ABILITY_SET[] = { + { "C1C3C2", HcfSm2SpecToAsn1 }, +}; + +static HcfSm2SpecToASN1CreateFunc FindAbility(const char *mode) +{ + // mode default C1C3C2 + if (HcfStrlen(mode) == 0) { + return CONVERT_ABILITY_SET[0].createFunc; + } + for (uint32_t i = 0; i < sizeof(CONVERT_ABILITY_SET) / sizeof(HcfSm2UtilAbility); i++) { + if (strcmp(mode, CONVERT_ABILITY_SET[i].mode) == 0) { + return CONVERT_ABILITY_SET[i].createFunc; + } + } + return NULL; +} + +static bool CheckMode(const char *mode) +{ + if (HcfStrlen(mode) == 0) { + return true; + } + for (uint32_t i = 0; i < sizeof(CONVERT_ABILITY_SET) / sizeof(HcfSm2UtilAbility); i++) { + if (strcmp(mode, CONVERT_ABILITY_SET[i].mode) == 0) { + return true; + } + } + LOGE("Invalid param mode"); + return false; +} + +static bool CheckSm2CipherTextSpec(Sm2CipherTextSpec *spec) +{ + if (spec == NULL) { + LOGE("Spec is null"); + return false; + } + if ((spec->xCoordinate.data == NULL) || (spec->xCoordinate.len == 0)) { + LOGE("Spec.xCoordinate is null"); + return false; + } + if ((spec->yCoordinate.data == NULL) || (spec->yCoordinate.len == 0)) { + LOGE("Spec.yCoordinate is null"); + return false; + } + if ((spec->hashData.data == NULL) || (spec->hashData.len == 0)) { + LOGE("Spec.hashData is null"); + return false; + } + if ((spec->cipherTextData.data == NULL) || (spec->cipherTextData.len == 0)) { + LOGE("Spec.cipherTextData is null"); + return false; + } + if (spec->hashData.len != HCF_SM2_C3_LEN) { + LOGE("Invalid param hashData"); + return false; + } + return true; +} + +HcfResult HcfGenCipherTextBySpec(Sm2CipherTextSpec *spec, const char *mode, HcfBlob *output) +{ + if (!CheckMode(mode)) { + LOGE("Invalid param mode!"); + return HCF_INVALID_PARAMS; + } + if (output == NULL) { + LOGE("Invalid param output!"); + return HCF_INVALID_PARAMS; + } + if (!CheckSm2CipherTextSpec(spec)) { + LOGE("Invalid param spec!"); + return HCF_INVALID_PARAMS; + } + HcfSm2SpecToASN1CreateFunc createFunc = FindAbility(mode); + HcfResult res = createFunc(spec, output); + if (res != HCF_SUCCESS) { + LOGE("Failed to convert construct to asn1!"); + } + return res; +} + +HcfResult HcfGetCipherTextSpec(HcfBlob *input, const char *mode, Sm2CipherTextSpec **returnSpc) +{ + if (!CheckMode(mode)) { + LOGE("Invalid param mode!"); + return HCF_INVALID_PARAMS; + } + if (input == NULL) { + LOGE("Invalid param input!"); + return HCF_INVALID_PARAMS; + } + if (returnSpc == NULL) { + LOGE("Invalid param returnSpc!"); + return HCF_INVALID_PARAMS; + } + HcfResult res = HcfAsn1ToSm2Spec(input, returnSpc); + if (res != HCF_SUCCESS) { + LOGE("Failed to convert asn1 to construct!"); + return res; + } + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/frameworks/frameworks.gni b/frameworks/frameworks.gni index 625e96ca4a61067b342e35b5fbdb15bd7e3371ec..623a379253235fdbd20ddcdcd699a8cd4b2e789b 100644 --- a/frameworks/frameworks.gni +++ b/frameworks/frameworks.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Huawei Device Co., Ltd. +# Copyright (C) 2022-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 @@ -57,7 +57,11 @@ framework_md_files = [ "${framework_path}/crypto_operation/md.c" ] framework_kdf_files = [ "${framework_path}/crypto_operation/kdf.c" ] +framework_sm2_crypto_util_files = + [ "${framework_path}/crypto_operation/sm2_crypto_util.c" ] + framework_files = framework_key_agreement_files + framework_signature_files + framework_cipher_files + framework_key_files + framework_mac_files + - framework_rand_files + framework_md_files + framework_kdf_files + framework_rand_files + framework_md_files + framework_kdf_files + + framework_sm2_crypto_util_files diff --git a/frameworks/js/napi/crypto/BUILD.gn b/frameworks/js/napi/crypto/BUILD.gn index ac45bbf7717447c03fe10e79b9e8ebb1d0610406..4adb38c4f90bfb92ac1ce0819413579a37ffcd6c 100644 --- a/frameworks/js/napi/crypto/BUILD.gn +++ b/frameworks/js/napi/crypto/BUILD.gn @@ -19,12 +19,8 @@ ohos_shared_library("cryptoframework_napi") { subsystem_name = "security" part_name = "crypto_framework" relative_install_dir = "module/security" - include_dirs = [ - "//third_party/bounds_checking_function/include", - "//commonlibrary/c_utils/base/include", - "//base/security/crypto_framework/frameworks/js/napi/crypto/inc", - "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", - ] + include_dirs = + [ "//base/security/crypto_framework/frameworks/js/napi/crypto/inc" ] include_dirs += framework_inc_path if (os_level == "standard") { @@ -32,7 +28,6 @@ ohos_shared_library("cryptoframework_napi") { cfi = true cfi_cross_dso = true debug = false - blocklist = "//base/security/crypto_framework/cfi_blocklist.txt" } } @@ -59,18 +54,17 @@ ohos_shared_library("cryptoframework_napi") { "src/napi_pub_key.cpp", "src/napi_rand.cpp", "src/napi_sign.cpp", + "src/napi_sm2_crypto_util.cpp", "src/napi_sym_key.cpp", "src/napi_sym_key_generator.cpp", "src/napi_utils.cpp", "src/napi_verify.cpp", ] - deps = [ - "//base/security/crypto_framework/frameworks:crypto_framework_lib", - "//third_party/bounds_checking_function:libsec_shared", - ] + deps = [ "//base/security/crypto_framework/frameworks:crypto_framework_lib" ] external_deps = [ + "bounds_checking_function:libsec_shared", "hilog:libhilog", "napi:ace_napi", ] diff --git a/frameworks/js/napi/crypto/inc/napi_asy_key_generator.h b/frameworks/js/napi/crypto/inc/napi_asy_key_generator.h index 39923aec188a41d6ac226c92ba439a2fc34ff3d6..4b87803d42b60e102773770b26c167f8de19b896 100644 --- a/frameworks/js/napi/crypto/inc/napi_asy_key_generator.h +++ b/frameworks/js/napi/crypto/inc/napi_asy_key_generator.h @@ -36,7 +36,9 @@ public: static napi_value CreateJsAsyKeyGenerator(napi_env env, napi_callback_info info); static napi_value JsGenerateKeyPair(napi_env env, napi_callback_info info); + static napi_value JsGenerateKeyPairSync(napi_env env, napi_callback_info info); static napi_value JsConvertKey(napi_env env, napi_callback_info info); + static napi_value JsConvertKeySync(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; diff --git a/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h b/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h index dd45e66155b93359cc0d9f131b44f61469681ced..344022f447b88e4fc5d4a63f598b142bb8218648 100644 --- a/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h +++ b/frameworks/js/napi/crypto/inc/napi_asy_key_spec_generator.h @@ -36,8 +36,11 @@ public: static napi_value CreateJsAsyKeyGeneratorBySpec(napi_env env, napi_callback_info info); static napi_value JsGenerateKeyPair(napi_env env, napi_callback_info info); + static napi_value JsGenerateKeyPairSync(napi_env env, napi_callback_info info); static napi_value JsGeneratePubKey(napi_env env, napi_callback_info info); + static napi_value JsGeneratePubKeySync(napi_env env, napi_callback_info info); static napi_value JsGeneratePriKey(napi_env env, napi_callback_info info); + static napi_value JsGeneratePriKeySync(napi_env env, napi_callback_info info); static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; diff --git a/frameworks/js/napi/crypto/inc/napi_cipher.h b/frameworks/js/napi/crypto/inc/napi_cipher.h index fe7dc8dc0c812e1a738a3bdf3a380357db46dd9c..8fdf6ba09b38215c5ab44c4dad88d7e9047b8bd9 100644 --- a/frameworks/js/napi/crypto/inc/napi_cipher.h +++ b/frameworks/js/napi/crypto/inc/napi_cipher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -39,6 +39,10 @@ public: static napi_value JsCipherDoFinal(napi_env env, napi_callback_info info); static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); + static napi_value JsCipherInitSync(napi_env env, napi_callback_info info); + static napi_value JsCipherUpdateSync(napi_env env, napi_callback_info info); + static napi_value JsCipherDoFinalSync(napi_env env, napi_callback_info info); + static napi_value JsSetCipherSpec(napi_env env, napi_callback_info info); static napi_value JsGetCipherSpec(napi_env env, napi_callback_info info); HcfCipher *GetCipher() const; diff --git a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h index bf209066c747171abfab270df4c2143cfb274364..ca0a427be831af9126b07c5b5fef737096a56aac 100644 --- a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h +++ b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -84,8 +84,19 @@ const std::string RSA_KEYPAIR_ASY_KEY_SPEC = "RsaKeyPairParamsSpec"; const std::string PBKDF2_ALG_NAME = "PBKDF2"; const std::string PBKDF2_PARAMS_ITER = "iterations"; const std::string PBKDF2_PARAMS_PASSWORD = "password"; -const std::string PBKDF2_PARAMS_SALT = "salt"; -const std::string PBKDF2_PARAMS_KEY_SIZE = "keySize"; + +const std::string SM2_UTIL_PARAM_X_COORDINATE = "xCoordinate"; +const std::string SM2_UTIL_PARAM_Y_COORDINATE = "yCoordinate"; +const std::string SM2_UTIL_PARAM_CIPHER_TEXT_DATA = "cipherTextData"; +const std::string SM2_UTIL_PARAM_HASH_DATA = "hashData"; + +const std::string KDF_PARAMS_SALT = "salt"; +const std::string KDF_PARAMS_KEY_SIZE = "keySize"; + +const std::string HKDF_ALG_NAME = "HKDF"; +const std::string HKDF_PARAMS_KEY = "key"; +const std::string HKDF_PARAMS_INFO = "info"; + } // namespace CryptoFramework } // namespace OHOS diff --git a/frameworks/js/napi/crypto/inc/napi_ecc_key_util.h b/frameworks/js/napi/crypto/inc/napi_ecc_key_util.h index 71764e73bcc718eff18bb183587108d2347661ed..08e850ccd3f24ac70e096a4463101e85d788240a 100644 --- a/frameworks/js/napi/crypto/inc/napi_ecc_key_util.h +++ b/frameworks/js/napi/crypto/inc/napi_ecc_key_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -32,6 +32,8 @@ public: static napi_value JsGenECCCommonParamsSpec(napi_env env, napi_callback_info info); static napi_value ECCKeyUtilConstructor(napi_env env, napi_callback_info info); static napi_value GenECCCommonParamSpec(napi_env env); + static napi_value JsConvertPoint(napi_env env, napi_callback_info info); + static napi_value JsGetEncodedPoint(napi_env env, napi_callback_info info); static void DefineNapiECCKeyUtilJSClass(napi_env env, napi_value exports); }; } // namespace CryptoFramework diff --git a/frameworks/js/napi/crypto/inc/napi_pri_key.h b/frameworks/js/napi/crypto/inc/napi_pri_key.h index 8046cffc142ba902850445baa93ae111e4243b7f..4b6345ea4bbc481b5f9dc569697636b8d304fa74 100644 --- a/frameworks/js/napi/crypto/inc/napi_pri_key.h +++ b/frameworks/js/napi/crypto/inc/napi_pri_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -37,6 +37,8 @@ public: static napi_value PriKeyConstructor(napi_env env, napi_callback_info info); static napi_value JsGetEncoded(napi_env env, napi_callback_info info); + static napi_value JsGetEncodedDer(napi_env env, napi_callback_info info); + static napi_value JsClearMem(napi_env env, napi_callback_info info); static napi_value JsGetAsyKeySpec(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/crypto/inc/napi_pub_key.h b/frameworks/js/napi/crypto/inc/napi_pub_key.h index a1ce1d071eaa68ad909e8700508b17ddbb316eec..427ef866ccd81b9a18ca7c79cbc05bc788622b67 100644 --- a/frameworks/js/napi/crypto/inc/napi_pub_key.h +++ b/frameworks/js/napi/crypto/inc/napi_pub_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -37,6 +37,7 @@ public: static napi_value PubKeyConstructor(napi_env env, napi_callback_info info); static napi_value JsGetEncoded(napi_env env, napi_callback_info info); + static napi_value JsGetEncodedDer(napi_env env, napi_callback_info info); static napi_value JsGetAsyKeySpec(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; diff --git a/frameworks/js/napi/crypto/inc/napi_sm2_crypto_util.h b/frameworks/js/napi/crypto/inc/napi_sm2_crypto_util.h new file mode 100644 index 0000000000000000000000000000000000000000..dd70d1b45db98beb7649b021593145070253b37a --- /dev/null +++ b/frameworks/js/napi/crypto/inc/napi_sm2_crypto_util.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef HCF_NAPI_SM2_CRYPTO_UTIL_H +#define HCF_NAPI_SM2_CRYPTO_UTIL_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "sm2_crypto_util.h" + +namespace OHOS { +namespace CryptoFramework { +class NapiSm2CryptoUtil { +public: + explicit NapiSm2CryptoUtil(); + ~NapiSm2CryptoUtil(); + + static napi_value JsGenCipherTextBySpec(napi_env env, napi_callback_info info); + static napi_value JsGetCipherTextSpec(napi_env env, napi_callback_info info); + static napi_value Sm2CryptoUtilConstructor(napi_env env, napi_callback_info info); + static napi_value Sm2CryptoUtilConstructorClass(napi_env env); + static void DefineNapiSm2CryptoUtilJSClass(napi_env env, napi_value exports); +}; +} // namespace CryptoFramework +} // namespace OHOS +#endif diff --git a/frameworks/js/napi/crypto/inc/napi_sym_key_generator.h b/frameworks/js/napi/crypto/inc/napi_sym_key_generator.h index 92f6591e7782f0d6866d405cf873912c1798b938..e1cda313026ef5b20cd4e1092ff2a9e233477302 100644 --- a/frameworks/js/napi/crypto/inc/napi_sym_key_generator.h +++ b/frameworks/js/napi/crypto/inc/napi_sym_key_generator.h @@ -36,6 +36,8 @@ public: static napi_value JsGenerateSymKey(napi_env env, napi_callback_info info); static napi_value JsGetAlgorithm(napi_env env, napi_callback_info info); static napi_value JsConvertKey(napi_env env, napi_callback_info info); + static napi_value JsGenerateSymKeySync(napi_env env, napi_callback_info info); + static napi_value JsConvertKeySync(napi_env env, napi_callback_info info); static thread_local napi_ref classRef_; private: diff --git a/frameworks/js/napi/crypto/inc/napi_utils.h b/frameworks/js/napi/crypto/inc/napi_utils.h index 30c5632ae6863b6532eec852e5626afb3c28f36e..e8eaae43d9d15fe12d9075af5b95c734867d4d53 100644 --- a/frameworks/js/napi/crypto/inc/napi_utils.h +++ b/frameworks/js/napi/crypto/inc/napi_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -56,14 +56,16 @@ HcfBlob *GetBlobFromNapiDataBlob(napi_env env, napi_value arg); bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec); napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob); -napi_value ConvertCipherBlobToNapiValue(napi_env env, HcfBlob *blob); +napi_value ConvertObjectBlobToNapiValue(napi_env env, HcfBlob *blob); bool GetAsyKeySpecFromNapiValue(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec); bool BuildSetNamedProperty(napi_env env, HcfBigInteger *number, const char *name, napi_value *intence); napi_value ConvertBigIntToNapiValue(napi_env env, HcfBigInteger *blob); napi_value ConvertEccCommParamsSpecToNapiValue(napi_env env, HcfEccCommParamsSpec *blob); napi_value ConvertDhCommParamsSpecToNapiValue(napi_env env, HcfDhCommParamsSpec *blob); +napi_value ConvertEccPointToNapiValue(napi_env env, HcfPoint *p); +bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point); bool GetStringFromJSParams(napi_env env, napi_value arg, std::string &returnStr); bool GetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt); bool GetUint32FromJSParams(napi_env env, napi_value arg, uint32_t &returnInt); @@ -76,6 +78,9 @@ napi_value GenerateBusinessError(napi_env env, HcfResult errCode, const char *er int32_t GetAsyKeySpecType(AsyKeySpecItem targetItemType); int32_t GetSignSpecType(SignSpecItem targetItemType); int32_t GetCipherSpecType(CipherSpecItem targetItemType); + +napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, std::string argName); +bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt); } // namespace CryptoFramework } // namespace OHOS #endif diff --git a/frameworks/js/napi/crypto/inc/napi_verify.h b/frameworks/js/napi/crypto/inc/napi_verify.h index f7211ab5c9641b15abb10d3b6698f99e61174ae7..748f05fb73ee423e15fed0d332913c8e3d16dd9d 100644 --- a/frameworks/js/napi/crypto/inc/napi_verify.h +++ b/frameworks/js/napi/crypto/inc/napi_verify.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -38,6 +38,8 @@ public: static napi_value JsInit(napi_env env, napi_callback_info info); static napi_value JsUpdate(napi_env env, napi_callback_info info); static napi_value JsVerify(napi_env env, napi_callback_info info); + static napi_value JsRecover(napi_env env, napi_callback_info info); + static napi_value JsRecoverSync(napi_env env, napi_callback_info info); static napi_value JsSetVerifySpec(napi_env env, napi_callback_info info); static napi_value JsGetVerifySpec(napi_env env, napi_callback_info info); diff --git a/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp b/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp index f42ea7cba647d8e26a0e7083a34a7067dc39ff2a..170856eb8729c650fdb50edab3c0b6c7e905d877 100644 --- a/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_asy_key_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -35,6 +35,7 @@ struct GenKeyPairCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref generatorRef = nullptr; HcfAsyKeyGenerator *generator = nullptr; HcfParamsSpec *params = nullptr; @@ -52,6 +53,7 @@ struct ConvertKeyCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref generatorRef = nullptr; HcfAsyKeyGenerator *generator = nullptr; HcfParamsSpec *params = nullptr; @@ -81,6 +83,11 @@ static void FreeGenKeyPairCtx(napi_env env, GenKeyPairCtx *ctx) ctx->callback = nullptr; } + if (ctx->generatorRef != nullptr) { + napi_delete_reference(env, ctx->generatorRef); + ctx->generatorRef = nullptr; + } + HcfFree(ctx); } @@ -100,6 +107,11 @@ static void FreeConvertKeyCtx(napi_env env, ConvertKeyCtx *ctx) ctx->callback = nullptr; } + if (ctx->generatorRef != nullptr) { + napi_delete_reference(env, ctx->generatorRef); + ctx->generatorRef = nullptr; + } + HcfBlobDataFree(ctx->pubKey); HcfFree(ctx->pubKey); HcfBlobDataFree(ctx->priKey); @@ -130,6 +142,11 @@ static bool BuildGenKeyPairCtx(napi_env env, napi_callback_info info, GenKeyPair ctx->generator = napiGenerator->GetAsyKeyGenerator(); ctx->params = nullptr; + if (napi_create_reference(env, thisVar, 1, &ctx->generatorRef) != napi_ok) { + LOGE("create generator ref failed generator key pair!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -201,6 +218,11 @@ static bool BuildConvertKeyCtx(napi_env env, napi_callback_info info, ConvertKey ctx->pubKey = pubKey; ctx->priKey = priKey; + if (napi_create_reference(env, thisVar, 1, &ctx->generatorRef) != napi_ok) { + LOGE("create generator ref failed when convert asym key!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -450,6 +472,71 @@ napi_value NapiAsyKeyGenerator::JsGenerateKeyPair(napi_env env, napi_callback_in return NewGenKeyPairAsyncWork(env, ctx); } +static bool GetHcfKeyPairInstance(napi_env env, HcfKeyPair *returnKeyPair, napi_value *instance) +{ + NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(returnKeyPair); + if (napiKeyPair == nullptr) { + HcfObjDestroy(returnKeyPair); + LOGE("new napi key pair failed"); + return false; + } + + *instance = napiKeyPair->ConvertToJsKeyPair(env); + napi_status ret = napi_wrap( + env, *instance, napiKeyPair, + [](napi_env env, void *data, void *hint) { + NapiKeyPair *keyPair = static_cast(data); + delete keyPair; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiKeyPair obj!"); + delete napiKeyPair; + return false; + } + + return true; +} + +napi_value NapiAsyKeyGenerator::JsGenerateKeyPairSync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + + NapiAsyKeyGenerator *napiGenerator = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (status != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap napi asyKeyGenerator obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi asyKeyGenerator obj.")); + return nullptr; + } + + HcfAsyKeyGenerator *generator = napiGenerator->GetAsyKeyGenerator(); + if (generator == nullptr) { + LOGE("get generator fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get generator fail!")); + return nullptr; + } + + HcfParamsSpec *params = nullptr; + HcfKeyPair *returnKeyPair = nullptr; + HcfResult errCode = generator->generateKeyPair(generator, params, &returnKeyPair); + if (errCode != HCF_SUCCESS) { + LOGE("generate key pair fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "generate key pair fail.")); + return nullptr; + } + + napi_value instance = nullptr; + if (!GetHcfKeyPairInstance(env, returnKeyPair, &instance)) { + LOGE("failed to get generate key pair instance!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get generate key pair instance!")); + return nullptr; + } + + return instance; +} + napi_value NapiAsyKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info) { ConvertKeyCtx *ctx = static_cast(HcfMalloc(sizeof(ConvertKeyCtx), 0)); @@ -469,6 +556,70 @@ napi_value NapiAsyKeyGenerator::JsConvertKey(napi_env env, napi_callback_info in return NewConvertKeyAsyncWork(env, ctx); } +static void HcfFreePubKeyAndPriKey(HcfBlob *pubKey, HcfBlob *priKey) +{ + HcfBlobDataFree(pubKey); + HcfFree(pubKey); + HcfBlobDataFree(priKey); + HcfFree(priKey); +} + +napi_value NapiAsyKeyGenerator::JsConvertKeySync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = PARAMS_NUM_TWO; + napi_value argv[PARAMS_NUM_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != PARAMS_NUM_TWO) { + LOGE("wrong argument num. require %d arguments. [Argc]: %zu!", PARAMS_NUM_TWO, argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num.")); + return nullptr; + } + + NapiAsyKeyGenerator *napiGenerator = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (status != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap napi asyKeyGenerator obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi asyKeyGenerator obj.")); + return nullptr; + } + + HcfBlob *pubKey = nullptr; + HcfBlob *priKey = nullptr; + if (!GetPkAndSkBlobFromNapiValueIfInput(env, argv[PARAM0], argv[PARAM1], &pubKey, &priKey)) { + LOGE("failed to unwrap napi asyKeyGenerator obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi asyKeyGenerator obj.")); + return nullptr; + } + + HcfAsyKeyGenerator *generator = napiGenerator->GetAsyKeyGenerator(); + if (generator == nullptr) { + HcfFreePubKeyAndPriKey(pubKey, priKey); + LOGE("get generator fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get generator fail!")); + return nullptr; + } + + HcfParamsSpec *params = nullptr; + HcfKeyPair *returnKeyPair = nullptr; + HcfResult errCode = generator->convertKey(generator, params, pubKey, priKey, &(returnKeyPair)); + HcfFreePubKeyAndPriKey(pubKey, priKey); + if (errCode != HCF_SUCCESS) { + LOGE("convert key fail."); + napi_throw(env, GenerateBusinessError(env, errCode, "convert key fail.")); + return nullptr; + } + + napi_value instance = nullptr; + if (!GetHcfKeyPairInstance(env, returnKeyPair, &instance)) { + LOGE("failed to get convert key instance!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get convert key instance!")); + return nullptr; + } + + return instance; +} + napi_value NapiAsyKeyGenerator::AsyKeyGeneratorConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -552,7 +703,9 @@ void NapiAsyKeyGenerator::DefineAsyKeyGeneratorJSClass(napi_env env, napi_value napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("generateKeyPair", NapiAsyKeyGenerator::JsGenerateKeyPair), + DECLARE_NAPI_FUNCTION("generateKeyPairSync", NapiAsyKeyGenerator::JsGenerateKeyPairSync), DECLARE_NAPI_FUNCTION("convertKey", NapiAsyKeyGenerator::JsConvertKey), + DECLARE_NAPI_FUNCTION("convertKeySync", NapiAsyKeyGenerator::JsConvertKeySync), }; napi_value constructor = nullptr; napi_define_class(env, "AsyKeyGenerator", NAPI_AUTO_LENGTH, NapiAsyKeyGenerator::AsyKeyGeneratorConstructor, diff --git a/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp b/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp index 525b01292647a05e388918d98e0412f512ed64ad..02cfa2bb7440b04055ac3f7ede4287d1b230073f 100644 --- a/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_asy_key_spec_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -36,6 +36,7 @@ struct AsyKeyCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref generatorRef = nullptr; HcfAsyKeyGeneratorBySpec *generator; HcfResult errCode = HCF_SUCCESS; @@ -62,6 +63,12 @@ static void FreeAsyKeyCtx(napi_env env, AsyKeyCtx *ctx) napi_delete_reference(env, ctx->callback); ctx->callback = nullptr; } + + if (ctx->generatorRef != nullptr) { + napi_delete_reference(env, ctx->generatorRef); + ctx->generatorRef = nullptr; + } + HcfFree(ctx); } @@ -85,6 +92,12 @@ static bool BuildAsyKeyCtx(napi_env env, napi_callback_info info, AsyKeyCtx *ctx return false; } ctx->generator = napiGenerator->GetAsyKeyGeneratorBySpec(); + + if (napi_create_reference(env, thisVar, 1, &ctx->generatorRef) != napi_ok) { + LOGE("create generator ref failed when generator asym key by spec!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -93,6 +106,21 @@ static bool BuildAsyKeyCtx(napi_env env, napi_callback_info info, AsyKeyCtx *ctx } } +static bool GetAsyKeyGenerator(napi_env env, napi_callback_info info, HcfAsyKeyGeneratorBySpec **generator) +{ + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + + NapiAsyKeyGeneratorBySpec *napiGenerator; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (status != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap napi asyKeyGenerator obj."); + return false; + } + *generator = napiGenerator->GetAsyKeyGeneratorBySpec(); + return true; +} + static void ReturnAsyKeyCallbackResult(napi_env env, AsyKeyCtx *ctx, napi_value result) { napi_value businessError = nullptr; @@ -382,6 +410,50 @@ napi_value NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair(napi_env env, napi_callb return NewGenKeyPairAsyncWork(env, ctx); } +napi_value NapiAsyKeyGeneratorBySpec::JsGenerateKeyPairSync(napi_env env, napi_callback_info info) +{ + HcfAsyKeyGeneratorBySpec *generator = nullptr; + if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) { + LOGE("build generator fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!")); + return nullptr; + } + + HcfKeyPair *returnKeyPair = nullptr; + HcfResult errCode = generator->generateKeyPair(generator, &(returnKeyPair)); + if (errCode != HCF_SUCCESS) { + LOGE("generate key pair fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "generate key pair fail.")); + return nullptr; + } + + napi_value instance = nullptr; + NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(returnKeyPair); + if (napiKeyPair == nullptr) { + HcfObjDestroy(returnKeyPair); + LOGE("new napi key pair failed"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!")); + return nullptr; + } + + instance = napiKeyPair->ConvertToJsKeyPair(env); + napi_status ret = napi_wrap( + env, instance, napiKeyPair, + [](napi_env env, void *data, void *hint) { + NapiKeyPair *keyPair = static_cast(data); + delete keyPair; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiKeyPair obj!"); + errCode = HCF_INVALID_PARAMS; + delete napiKeyPair; + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiKeyPair obj!")); + return nullptr; + } + return instance; +} + napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKey(napi_env env, napi_callback_info info) { AsyKeyCtx *ctx = static_cast(HcfMalloc(sizeof(AsyKeyCtx), 0)); @@ -401,6 +473,53 @@ napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKey(napi_env env, napi_callba return NewPubKeyAsyncWork(env, ctx); } +napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKeySync(napi_env env, napi_callback_info info) +{ + HcfAsyKeyGeneratorBySpec *generator = nullptr; + if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) { + LOGE("build generator fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!")); + return nullptr; + } + + HcfPubKey *returnPubKey = nullptr; + HcfResult errCode = generator->generatePubKey(generator, &(returnPubKey)); + if (errCode != HCF_SUCCESS) { + LOGE("generate PubKey fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "generate PubKey fail.")); + return nullptr; + } + + napi_value instance = nullptr; + NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(returnPubKey); + if (napiPubKey == nullptr) { + HcfObjDestroy(returnPubKey); + LOGE("new napi pub key failed"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pub key failed!")); + return nullptr; + } + + instance = napiPubKey->ConvertToJsPubKey(env); + napi_status ret = napi_wrap( + env, instance, napiPubKey, + [](napi_env env, void *data, void *hint) { + NapiPubKey *napiPubKey = static_cast(data); + HcfObjDestroy(napiPubKey->GetPubKey()); + delete napiPubKey; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiPubKey obj!"); + errCode = HCF_INVALID_PARAMS; + HcfObjDestroy(napiPubKey->GetPubKey()); + delete napiPubKey; + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiPubKey obj!")); + return nullptr; + } + + return instance; +} + napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKey(napi_env env, napi_callback_info info) { AsyKeyCtx *ctx = static_cast(HcfMalloc(sizeof(AsyKeyCtx), 0)); @@ -420,6 +539,53 @@ napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKey(napi_env env, napi_callba return NewPriKeyAsyncWork(env, ctx); } +napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKeySync(napi_env env, napi_callback_info info) +{ + HcfAsyKeyGeneratorBySpec *generator = nullptr; + if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) { + LOGE("build generator fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!")); + return nullptr; + } + + HcfPriKey *returnPriKey = nullptr; + HcfResult errCode = generator->generatePriKey(generator, &(returnPriKey)); + if (errCode != HCF_SUCCESS) { + LOGE("generate PriKey fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "generate PriKey fail.")); + return nullptr; + } + + napi_value instance = nullptr; + NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(returnPriKey); + if (napiPriKey == nullptr) { + HcfObjDestroy(returnPriKey); + LOGE("new napi pri key failed"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pri key failed!")); + return nullptr; + } + + instance = napiPriKey->ConvertToJsPriKey(env); + napi_status ret = napi_wrap( + env, instance, napiPriKey, + [](napi_env env, void *data, void *hint) { + NapiPriKey *napiPriKey = static_cast(data); + HcfObjDestroy(napiPriKey->GetPriKey()); + delete napiPriKey; + return; + }, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("failed to wrap napiPriKey obj!"); + errCode = HCF_INVALID_PARAMS; + HcfObjDestroy(napiPriKey->GetPriKey()); + delete napiPriKey; + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiPriKey obj!")); + return nullptr; + } + + return instance; +} + napi_value NapiAsyKeyGeneratorBySpec::AsyKeyGeneratorBySpecConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -517,8 +683,11 @@ void NapiAsyKeyGeneratorBySpec::DefineAsyKeyGeneratorBySpecJSClass(napi_env env, napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("generateKeyPair", NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair), + DECLARE_NAPI_FUNCTION("generateKeyPairSync", NapiAsyKeyGeneratorBySpec::JsGenerateKeyPairSync), DECLARE_NAPI_FUNCTION("generatePriKey", NapiAsyKeyGeneratorBySpec::JsGeneratePriKey), + DECLARE_NAPI_FUNCTION("generatePriKeySync", NapiAsyKeyGeneratorBySpec::JsGeneratePriKeySync), DECLARE_NAPI_FUNCTION("generatePubKey", NapiAsyKeyGeneratorBySpec::JsGeneratePubKey), + DECLARE_NAPI_FUNCTION("generatePubKeySync", NapiAsyKeyGeneratorBySpec::JsGeneratePubKeySync), { .utf8name = "algName", .getter = NapiAsyKeyGeneratorBySpec::JsGetAlgorithm }, }; napi_value constructor = nullptr; diff --git a/frameworks/js/napi/crypto/src/napi_cipher.cpp b/frameworks/js/napi/crypto/src/napi_cipher.cpp index 5534c727b50e350a8d77ece16041ae9dc6ce01b7..9e0763a6f2a9887fe30759da5c95ebd1b86e0f07 100644 --- a/frameworks/js/napi/crypto/src/napi_cipher.cpp +++ b/frameworks/js/napi/crypto/src/napi_cipher.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -37,6 +37,8 @@ struct CipherFwkCtxT { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref cipherRef = nullptr; + napi_ref keyRef = nullptr; HcfCipher *cipher = nullptr; HcfKey *key = nullptr; @@ -104,6 +106,17 @@ static void FreeCipherFwkCtx(napi_env env, CipherFwkCtx &context) napi_delete_reference(env, context->callback); context->callback = nullptr; } + + if (context->cipherRef != nullptr) { + napi_delete_reference(env, context->cipherRef); + context->cipherRef = nullptr; + } + + if (context->keyRef != nullptr) { + napi_delete_reference(env, context->keyRef); + context->keyRef = nullptr; + } + if (context->input.data != nullptr) { HcfFree(context->input.data); context->input.data = nullptr; @@ -124,6 +137,21 @@ static void FreeCipherFwkCtx(napi_env env, CipherFwkCtx &context) context = nullptr; } +static bool CreateCipherRef(napi_env env, napi_value thisVar, napi_value key, CipherFwkCtx ctx) +{ + if (napi_create_reference(env, thisVar, 1, &ctx->cipherRef) != napi_ok) { + LOGE("create cipher ref failed when do cipher init!"); + return false; + } + + if (napi_create_reference(env, key, 1, &ctx->keyRef) != napi_ok) { + LOGE("create key ref failed when do cipher init!"); + return false; + } + + return true; +} + static bool BuildContextForInit(napi_env env, napi_callback_info info, CipherFwkCtx context) { napi_value thisVar = nullptr; @@ -172,6 +200,10 @@ static bool BuildContextForInit(napi_env env, napi_callback_info info, CipherFwk } index++; + if (!CreateCipherRef(env, thisVar, argv[PARAM1], context)) { + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -213,6 +245,12 @@ static bool BuildContextForUpdate(napi_env env, napi_callback_info info, CipherF context->input.data = input->data; context->input.len = input->len; HcfFree(input); + + if (napi_create_reference(env, thisVar, 1, &context->cipherRef) != napi_ok) { + LOGE("create cipher ref failed when do cipher update!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -257,6 +295,12 @@ static bool BuildContextForFinal(napi_env env, napi_callback_info info, CipherFw context->input.len = input->len; HcfFree(input); } + + if (napi_create_reference(env, thisVar, 1, &context->cipherRef) != napi_ok) { + LOGE("create cipher ref failed when do cipher final!"); + return false; + } + index++; if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); @@ -491,6 +535,70 @@ napi_value NapiCipher::JsCipherInit(napi_env env, napi_callback_info info) return NewAsyncInit(env, context); } +static napi_value SyncInit(napi_env env, HcfCipher *cipher, HcfCryptoMode opMode, HcfKey *key, + HcfParamsSpec *paramsSpec) +{ + HcfResult res = cipher->init(cipher, opMode, key, paramsSpec); + if (res != HCF_SUCCESS) { + LOGE("failed to cipher init."); + napi_throw(env, GenerateBusinessError(env, res, "init cipher fail.")); + return nullptr; + } + return NapiGetNull(env); +} + +napi_value NapiCipher::JsCipherInitSync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = ARGS_SIZE_THREE; + napi_value argv[ARGS_SIZE_THREE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != ARGS_SIZE_THREE) { + LOGE("wrong argument num. require 3 arguments. [Argc]: %zu!", argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); + return nullptr; + } + NapiCipher *napiCipher = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); + if (status != napi_ok || napiCipher == nullptr) { + LOGE("failed to unwrap napi napiCipher obj!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "unwrap napi napiCipher failed!")); + return nullptr; + } + HcfCipher *cipher = napiCipher->GetCipher(); + // get opMode, type is uint32 + size_t index = 0; + enum HcfCryptoMode opMode = ENCRYPT_MODE; + if (napi_get_value_uint32(env, argv[index++], reinterpret_cast(&opMode)) != napi_ok) { + LOGE("get option mode failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get napi option mode failed!")); + return nullptr; + } + // get key, unwrap from JS + NapiKey *napiKey = nullptr; + status = napi_unwrap(env, argv[index++], reinterpret_cast(&napiKey)); + if (status != napi_ok || napiKey == nullptr) { + LOGE("get key obj failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get napi key failed!")); + return nullptr; + } + HcfKey *key = napiKey->GetHcfKey(); + // get paramsSpec, unwrap from JS + HcfParamsSpec *paramsSpec = nullptr; + napi_valuetype valueType; + napi_typeof(env, argv[index], &valueType); + if (valueType != napi_null) { + if (!GetParamsSpecFromNapiValue(env, argv[index], opMode, ¶msSpec)) { + LOGE("get params failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get napi paramsSpec failed!")); + return nullptr; + } + } + napi_value instance = SyncInit(env, cipher, opMode, key, paramsSpec); + FreeParamsSpec(paramsSpec); + return instance; +} + napi_value NapiCipher::JsCipherUpdate(napi_env env, napi_callback_info info) { CipherFwkCtx context = static_cast(HcfMalloc(sizeof(CipherFwkCtxT), 0)); @@ -510,6 +618,48 @@ napi_value NapiCipher::JsCipherUpdate(napi_env env, napi_callback_info info) return NewAsyncUpdate(env, context); } +napi_value NapiCipher::JsCipherUpdateSync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiCipher *napiCipher = nullptr; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != ARGS_SIZE_ONE) { + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); + return nullptr; + } + HcfCipher *cipher = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); + if (status != napi_ok || napiCipher == nullptr) { + LOGE("failed to unwrap napi napiCipher obj!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "unwrap napi cipher failed!")); + return nullptr; + } + cipher = napiCipher->GetCipher(); + // get input, type is blob + HcfBlob *input = nullptr; + input = GetBlobFromNapiDataBlob(env, argv[PARAM0]); + if (input == nullptr) { + LOGE("failed to get input blob!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get input blob failed!")); + return nullptr; + } + HcfBlob output = { .data = nullptr, .len = 0 }; + HcfResult res = cipher->update(cipher, input, &output); + HcfFree(input->data); + HcfFree(input); + if (res != HCF_SUCCESS) { + LOGE("failed to update!"); + napi_throw(env, GenerateBusinessError(env, res, "update fail!")); + return nullptr; + } + napi_value instance = ConvertBlobToNapiValue(env, &output); + HcfFree(output.data); + return instance; +} + napi_value NapiCipher::JsCipherDoFinal(napi_env env, napi_callback_info info) { CipherFwkCtx context = static_cast(HcfMalloc(sizeof(CipherFwkCtxT), 0)); @@ -525,9 +675,58 @@ napi_value NapiCipher::JsCipherDoFinal(napi_env env, napi_callback_info info) FreeCipherFwkCtx(env, context); return nullptr; } + return NewAsyncDoFinal(env, context); } +napi_value NapiCipher::JsCipherDoFinalSync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiCipher *napiCipher = nullptr; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != ARGS_SIZE_ONE) { + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "invalid params count")); + return nullptr; + } + HcfCipher *cipher = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiCipher)); + if (status != napi_ok || napiCipher == nullptr) { + LOGE("failed to unwrap napi cipher obj!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "unwrap napi cipher failed")); + return nullptr; + } + cipher = napiCipher->GetCipher(); + // get input, type is blob + napi_valuetype valueType; + HcfBlob *input = nullptr; + napi_typeof(env, argv[PARAM0], &valueType); + if (valueType != napi_null) { + input = GetBlobFromNapiDataBlob(env, argv[PARAM0]); + if (input == nullptr) { + LOGE("failed to get input blob!"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "get input blob failed!")); + return nullptr; + } + } + HcfBlob output = { .data = nullptr, .len = 0 }; + HcfResult res = cipher->doFinal(cipher, input, &output); + if (input != nullptr) { + HcfFree(input->data); + HcfFree(input); + } + if (res != HCF_SUCCESS) { + LOGE("failed to do final!"); + napi_throw(env, GenerateBusinessError(env, res, "do final fail!")); + return nullptr; + } + napi_value instance = ConvertBlobToNapiValue(env, &output); + HcfFree(output.data); + return instance; +} + napi_value NapiCipher::JsGetAlgorithm(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -696,7 +895,7 @@ static napi_value GetCipherSpecUint8Array(napi_env env, CipherSpecItem item, Hcf return nullptr; } - napi_value instance = ConvertCipherBlobToNapiValue(env, &blob); + napi_value instance = ConvertObjectBlobToNapiValue(env, &blob); HcfBlobDataClearAndFree(&blob); return instance; } @@ -756,6 +955,9 @@ void NapiCipher::DefineCipherJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiCipher::JsCipherInit), DECLARE_NAPI_FUNCTION("update", NapiCipher::JsCipherUpdate), DECLARE_NAPI_FUNCTION("doFinal", NapiCipher::JsCipherDoFinal), + DECLARE_NAPI_FUNCTION("initSync", NapiCipher::JsCipherInitSync), + DECLARE_NAPI_FUNCTION("updateSync", NapiCipher::JsCipherUpdateSync), + DECLARE_NAPI_FUNCTION("doFinalSync", NapiCipher::JsCipherDoFinalSync), DECLARE_NAPI_FUNCTION("setCipherSpec", NapiCipher::JsSetCipherSpec), DECLARE_NAPI_FUNCTION("getCipherSpec", NapiCipher::JsGetCipherSpec), { .utf8name = "algName", .getter = NapiCipher::JsGetAlgorithm }, diff --git a/frameworks/js/napi/crypto/src/napi_ecc_key_util.cpp b/frameworks/js/napi/crypto/src/napi_ecc_key_util.cpp index b8e26a1811933e86e280d7d0c1485d2c200a8532..00edecbcbbc3af480a0136649e02ca584cc788ab 100644 --- a/frameworks/js/napi/crypto/src/napi_ecc_key_util.cpp +++ b/frameworks/js/napi/crypto/src/napi_ecc_key_util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -18,6 +18,7 @@ #include "detailed_ecc_key_params.h" #include "log.h" +#include "memory.h" #include "napi_crypto_framework_defines.h" #include "napi_utils.h" #include "napi_key_pair.h" @@ -61,6 +62,98 @@ napi_value NapiECCKeyUtil::JsGenECCCommonParamsSpec(napi_env env, napi_callback_ return instance; } +napi_value NapiECCKeyUtil::JsConvertPoint(napi_env env, napi_callback_info info) +{ + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc != expectedArgc) { + LOGE("The input args num is invalid."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); + return nullptr; + } + + std::string curveName; + if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) { + LOGE("failed to get curveName."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName.")); + return nullptr; + } + + HcfBlob *pointBlob = GetBlobFromNapiUint8Arr(env, argv[PARAM1]); + if (pointBlob == nullptr) { + LOGE("failed to get point blob."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point blob.")); + return nullptr; + } + + HcfPoint point; + HcfResult ret = HcfConvertPoint(curveName.c_str(), pointBlob, &point); + if (ret != HCF_SUCCESS) { + LOGE("failed to convert point."); + HcfBlobDataFree(pointBlob); + HcfFree(pointBlob); + napi_throw(env, GenerateBusinessError(env, ret, "failed to convert point.")); + return nullptr; + } + napi_value instance = ConvertEccPointToNapiValue(env, &point); + FreeEcPointMem(&point); + HcfBlobDataFree(pointBlob); + HcfFree(pointBlob); + return instance; +} + +napi_value NapiECCKeyUtil::JsGetEncodedPoint(napi_env env, napi_callback_info info) +{ + size_t expectedArgc = ARGS_SIZE_THREE; + size_t argc = ARGS_SIZE_THREE; + napi_value argv[ARGS_SIZE_THREE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc != expectedArgc) { + LOGE("The input args num is invalid."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); + return nullptr; + } + + std::string curveName; + if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) { + LOGE("failed to get curveName."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName.")); + return nullptr; + } + + HcfPoint point; + if (!GetPointFromNapiValue(env, argv[PARAM1], &point)) { + LOGE("failed to get point."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point.")); + return nullptr; + } + + std::string format; + if (!GetStringFromJSParams(env, argv[PARAM2], format)) { + LOGE("failed to get format."); + FreeEcPointMem(&point); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format.")); + return nullptr; + } + + HcfBlob returnBlob; + HcfResult ret = HcfGetEncodedPoint(curveName.c_str(), &point, format.c_str(), &returnBlob); + if (ret != HCF_SUCCESS) { + LOGE("fail to get point data."); + FreeEcPointMem(&point); + napi_throw(env, GenerateBusinessError(env, ret, "failed to get point data.")); + return nullptr; + } + napi_value instance = ConvertObjectBlobToNapiValue(env, &returnBlob); + FreeEcPointMem(&point); + HcfBlobDataFree(&returnBlob); + return instance; +} + napi_value NapiECCKeyUtil::ECCKeyUtilConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -75,6 +168,8 @@ napi_value NapiECCKeyUtil::GenECCCommonParamSpec(napi_env env) napi_value cons = nullptr; napi_property_descriptor clzDes[] = { DECLARE_NAPI_STATIC_FUNCTION("genECCCommonParamsSpec", NapiECCKeyUtil::JsGenECCCommonParamsSpec), + DECLARE_NAPI_STATIC_FUNCTION("convertPoint", NapiECCKeyUtil::JsConvertPoint), + DECLARE_NAPI_STATIC_FUNCTION("getEncodedPoint", NapiECCKeyUtil::JsGetEncodedPoint), }; NAPI_CALL(env, napi_define_class(env, "ECCKeyUtil", NAPI_AUTO_LENGTH, NapiECCKeyUtil::ECCKeyUtilConstructor, nullptr, sizeof(clzDes) / sizeof(clzDes[0]), clzDes, &cons)); diff --git a/frameworks/js/napi/crypto/src/napi_init.cpp b/frameworks/js/napi/crypto/src/napi_init.cpp index e3a47f38ad18ab2b93341fe2e5d262e458d811e1..b36f0d3db991d60887b0b6a86de7b355d6161178 100644 --- a/frameworks/js/napi/crypto/src/napi_init.cpp +++ b/frameworks/js/napi/crypto/src/napi_init.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -26,6 +26,7 @@ #include "napi_pri_key.h" #include "napi_pub_key.h" #include "napi_sign.h" +#include "napi_sm2_crypto_util.h" #include "napi_verify.h" #include "napi_key_agreement.h" #include "napi_mac.h" @@ -231,6 +232,7 @@ static napi_value ModuleExport(napi_env env, napi_value exports) NapiKdf::DefineKdfJSClass(env, exports); NapiECCKeyUtil::DefineNapiECCKeyUtilJSClass(env, exports); NapiDHKeyUtil::DefineNapiDHKeyUtilJSClass(env, exports); + NapiSm2CryptoUtil::DefineNapiSm2CryptoUtilJSClass(env, exports); LOGD("module init end."); return exports; } diff --git a/frameworks/js/napi/crypto/src/napi_kdf.cpp b/frameworks/js/napi/crypto/src/napi_kdf.cpp index 2d1626cd9146eb18d4b8d7e494aa9d72eb4c104c..5bcda945735f0ab1aefd6e4aaf19c070037d21e6 100644 --- a/frameworks/js/napi/crypto/src/napi_kdf.cpp +++ b/frameworks/js/napi/crypto/src/napi_kdf.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -21,6 +21,7 @@ #include "napi_utils.h" #include "napi_crypto_framework_defines.h" #include "detailed_pbkdf2_params.h" +#include "detailed_hkdf_params.h" #define PBKDF2_ALG_SIZE 6 @@ -36,6 +37,7 @@ struct KdfCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref kdfRef = nullptr; HcfResult errCode = HCF_SUCCESS; const char *errMsg = nullptr; @@ -72,6 +74,12 @@ static void FreeCryptoFwkCtx(napi_env env, KdfCtx *context) napi_delete_reference(env, context->callback); context->callback = nullptr; } + + if (context->kdfRef != nullptr) { + napi_delete_reference(env, context->kdfRef); + context->kdfRef = nullptr; + } + FreeKdfParamsSpec(context->paramsSpec); context->paramsSpec = nullptr; context->errMsg = nullptr; @@ -125,7 +133,11 @@ static void KdfGenSecretComplete(napi_env env, napi_status status, void *data) if (PBKDF2_ALG_NAME.compare(context->paramsSpec->algName) == 0) { HcfPBKDF2ParamsSpec *params = reinterpret_cast(context->paramsSpec); returnBlob = ConvertBlobToNapiValue(env, &(params->output)); + } else if (HKDF_ALG_NAME.compare(context->paramsSpec->algName) == 0) { + HcfHkdfParamsSpec *params = reinterpret_cast(context->paramsSpec); + returnBlob = ConvertBlobToNapiValue(env, &(params->output)); } + if (returnBlob == nullptr) { LOGE("returnOutBlob is nullptr!"); returnBlob = NapiGetNull(env); @@ -138,7 +150,7 @@ static void KdfGenSecretComplete(napi_env env, napi_status status, void *data) FreeCryptoFwkCtx(env, context); } -static bool GetInt32FromPBKDF2Params(napi_env env, napi_value arg, const std::string &name, int32_t &retInt) +static bool GetInt32FromKdfParams(napi_env env, napi_value arg, const std::string &name, int32_t &retInt) { // int attribute napi_value dataInt = nullptr; @@ -190,7 +202,7 @@ static bool GetCharArrayFromUint8Arr(napi_env env, napi_value data, HcfBlob *ret return true; } -static bool GetCharArrayFromJsString(napi_env env, napi_value arg, HcfBlob *retPassword) +static bool GetCharArrayFromJsString(napi_env env, napi_value arg, HcfBlob *retBlob) { size_t length = 0; if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) { @@ -215,12 +227,12 @@ static bool GetCharArrayFromJsString(napi_env env, napi_value arg, HcfBlob *retP HcfFree(tmpPassword); return false; } - retPassword->data = reinterpret_cast(tmpPassword); - retPassword->len = length; + retBlob->data = reinterpret_cast(tmpPassword); + retBlob->len = length; return true; } -static bool GetPasswordFromPBKDF2Params(napi_env env, napi_value arg, const std::string &name, HcfBlob *retPassword) +static bool GetKeyOrPwdFromKdfParams(napi_env env, napi_value arg, const std::string &name, HcfBlob *retBlob) { napi_value data = nullptr; napi_valuetype valueType = napi_undefined; @@ -231,12 +243,12 @@ static bool GetPasswordFromPBKDF2Params(napi_env env, napi_value arg, const std: return false; } if (valueType == napi_string) { - if (GetCharArrayFromJsString(env, data, retPassword) != true) { + if (GetCharArrayFromJsString(env, data, retBlob) != true) { LOGE("get char string failed"); return false; } } else { - if (GetCharArrayFromUint8Arr(env, data, retPassword) != true) { + if (GetCharArrayFromUint8Arr(env, data, retBlob) != true) { LOGE("get uint8arr failed"); return false; } @@ -244,7 +256,7 @@ static bool GetPasswordFromPBKDF2Params(napi_env env, napi_value arg, const std: return true; } -static HcfBlob *GetBlobFromPBKDF2ParamsSpec(napi_env env, napi_value arg, const std::string &name) +static HcfBlob *GetBlobFromKdfParamsSpec(napi_env env, napi_value arg, const std::string &name) { // get uint8Array attribute napi_value data = nullptr; @@ -270,14 +282,24 @@ static void SetPBKDF2ParamsSpecAttribute(int iter, const HcfBlob &out, HcfBlob * tmp->base.algName = PBKDF2_ALG_NAME.c_str(); } +static void SetHkdfParamsSpecAttribute(const HcfBlob &out, HcfBlob *salt, const HcfBlob &key, HcfBlob *info, + HcfHkdfParamsSpec *tmpParams) +{ + tmpParams->output = out; + tmpParams->salt = *salt; + tmpParams->key = key; + tmpParams->info = *info; + tmpParams->base.algName = HKDF_ALG_NAME.c_str(); +} + static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { // get attribute from params // int attribute int iter = -1; int keySize = -1; - if (!GetInt32FromPBKDF2Params(env, arg, PBKDF2_PARAMS_ITER, iter) || - !GetInt32FromPBKDF2Params(env, arg, PBKDF2_PARAMS_KEY_SIZE, keySize)) { + if (!GetInt32FromKdfParams(env, arg, PBKDF2_PARAMS_ITER, iter) || + !GetInt32FromKdfParams(env, arg, KDF_PARAMS_KEY_SIZE, keySize)) { LOGE("failed to get valid num"); return false; } @@ -295,12 +317,12 @@ static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec * HcfPBKDF2ParamsSpec *tmp = nullptr; do { // get password - if (!GetPasswordFromPBKDF2Params(env, arg, PBKDF2_PARAMS_PASSWORD, &tmpPassword)) { + if (!GetKeyOrPwdFromKdfParams(env, arg, PBKDF2_PARAMS_PASSWORD, &tmpPassword)) { LOGE("failed to get password"); break; } // get salt attribute - salt = GetBlobFromPBKDF2ParamsSpec(env, arg, PBKDF2_PARAMS_SALT); + salt = GetBlobFromKdfParamsSpec(env, arg, KDF_PARAMS_SALT); if (salt == nullptr) { LOGE("fail to get salt"); break; @@ -324,6 +346,64 @@ static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec * return false; } +static bool GetHkdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) +{ + int keySize = -1; + if (!GetInt32FromKdfParams(env, arg, KDF_PARAMS_KEY_SIZE, keySize)) { + LOGE("failed to get valid num"); + return false; + } + if (keySize <= 0) { + LOGE("keySize should larger than 0"); + return false; + } + HcfBlob out = { .data = static_cast(HcfMalloc(keySize, 0)), .len = keySize }; + if (out.data == nullptr) { + LOGE("output malloc failed!"); + return false; + } + + HcfBlob *salt = nullptr; + HcfBlob key = { .data = nullptr, .len = 0 }; + HcfBlob *info = nullptr; + HcfHkdfParamsSpec *tmpParams = nullptr; + do { + // get key + if (!GetKeyOrPwdFromKdfParams(env, arg, HKDF_PARAMS_KEY, &key)) { + LOGE("failed to get key"); + break; + } + + // get info、salt + info = GetBlobFromKdfParamsSpec(env, arg, HKDF_PARAMS_INFO); + salt = GetBlobFromKdfParamsSpec(env, arg, KDF_PARAMS_SALT); + if (info == nullptr or salt == nullptr) { + LOGE("fail to get info or salt"); + break; + } + + // malloc tmpParams + tmpParams = static_cast(HcfMalloc(sizeof(HcfHkdfParamsSpec), 0)); + if (tmpParams == nullptr) { + LOGE("hkdf spec malloc failed!"); + break; + } + SetHkdfParamsSpecAttribute(out, salt, key, info, tmpParams); + // only need the data and data length of the salt, so free the blob pointer. + HcfFree(salt); + HcfFree(info); + *params = reinterpret_cast(tmpParams); + return true; + } while (0); + HcfBlobDataClearAndFree(salt); + HcfBlobDataClearAndFree(&key); + HcfBlobDataClearAndFree(info); + HcfFree(salt); + HcfFree(info); + HcfFree(out.data); + return false; +} + static bool GetKdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { napi_value data = nullptr; @@ -346,6 +426,8 @@ static bool GetKdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **pa } if (algoName.compare(PBKDF2_ALG_NAME) == 0) { return GetPBKDF2ParamsSpec(env, arg, params); + } else if (algoName.compare(HKDF_ALG_NAME) == 0) { + return GetHkdfParamsSpec(env, arg, params); } else { LOGE("Not support that alg"); return false; @@ -379,6 +461,11 @@ static bool BuildKdfGenSecretCtx(napi_env env, napi_callback_info info, KdfCtx * context->asyncType = isCallback(env, argv[expectedArgsCount - 1], argc, expectedArgsCount) ? ASYNC_CALLBACK : ASYNC_PROMISE; + if (napi_create_reference(env, thisVar, 1, &context->kdfRef) != napi_ok) { + LOGE("create kdf ref failed when derive secret key using kdf!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_key_agreement.cpp b/frameworks/js/napi/crypto/src/napi_key_agreement.cpp index 46bc7566f7903ae8d287200a32e0728fdfd0478f..74e730356d07f39ce0947c1356881f264b0e89ae 100644 --- a/frameworks/js/napi/crypto/src/napi_key_agreement.cpp +++ b/frameworks/js/napi/crypto/src/napi_key_agreement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -34,6 +34,9 @@ struct KeyAgreementCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref keyAgreementRef = nullptr; + napi_ref priKeyRef = nullptr; + napi_ref pubKeyRef = nullptr; HcfKeyAgreement *keyAgreement = nullptr; HcfPriKey *priKey = nullptr; @@ -62,6 +65,21 @@ static void FreeKeyAgreementCtx(napi_env env, KeyAgreementCtx *ctx) ctx->callback = nullptr; } + if (ctx->keyAgreementRef != nullptr) { + napi_delete_reference(env, ctx->keyAgreementRef); + ctx->keyAgreementRef = nullptr; + } + + if (ctx->priKeyRef != nullptr) { + napi_delete_reference(env, ctx->priKeyRef); + ctx->priKeyRef = nullptr; + } + + if (ctx->pubKeyRef != nullptr) { + napi_delete_reference(env, ctx->pubKeyRef); + ctx->pubKeyRef = nullptr; + } + if (ctx->returnSecret.data != nullptr) { HcfFree(ctx->returnSecret.data); ctx->returnSecret.data = nullptr; @@ -71,6 +89,27 @@ static void FreeKeyAgreementCtx(napi_env env, KeyAgreementCtx *ctx) HcfFree(ctx); } +static bool CreateKeyAgreementRef(napi_env env, napi_value thisVar, napi_value priKey, napi_value pubKey, + KeyAgreementCtx *ctx) +{ + if (napi_create_reference(env, thisVar, 1, &ctx->keyAgreementRef) != napi_ok) { + LOGE("create key agreement ref failed when derive secret key using key agreement!"); + return false; + } + + if (napi_create_reference(env, priKey, 1, &ctx->priKeyRef) != napi_ok) { + LOGE("create private key ref failed when derive secret key using key agreement!"); + return false; + } + + if (napi_create_reference(env, pubKey, 1, &ctx->pubKeyRef) != napi_ok) { + LOGE("create public key ref failed when derive secret key using key agreement!"); + return false; + } + + return true; +} + static bool BuildKeyAgreementJsCtx(napi_env env, napi_callback_info info, KeyAgreementCtx *ctx) { napi_value thisVar = nullptr; @@ -111,6 +150,10 @@ static bool BuildKeyAgreementJsCtx(napi_env env, napi_callback_info info, KeyAgr ctx->priKey = napiPriKey->GetPriKey(); ctx->pubKey = napiPubKey->GetPubKey(); + if (!CreateKeyAgreementRef(env, thisVar, argv[PARAM0], argv[PARAM1], ctx)) { + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_mac.cpp b/frameworks/js/napi/crypto/src/napi_mac.cpp index 19ae545f08ddf11ebdc5bf1e605a7d32c68e2b31..469bb3188c839c58caaaa80e3e542bcb68e7e6c6 100644 --- a/frameworks/js/napi/crypto/src/napi_mac.cpp +++ b/frameworks/js/napi/crypto/src/napi_mac.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -35,6 +35,8 @@ struct MacCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref macRef = nullptr; + napi_ref symKeyRef = nullptr; std::string algoName = ""; HcfSymKey *symKey = nullptr; @@ -59,6 +61,14 @@ static void FreeCryptoFwkCtx(napi_env env, MacCtx *context) napi_delete_reference(env, context->callback); context->callback = nullptr; } + if (context->macRef != nullptr) { + napi_delete_reference(env, context->macRef); + context->macRef = nullptr; + } + if (context->symKeyRef != nullptr) { + napi_delete_reference(env, context->symKeyRef); + context->symKeyRef = nullptr; + } context->symKey = nullptr; if (context->inBlob != nullptr) { HcfFree(context->inBlob->data); @@ -223,6 +233,16 @@ static bool BuildMacJsInitCtx(napi_env env, napi_callback_info info, MacCtx *con context->mac = napiMac->GetMac(); + if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) { + LOGE("create mac ref failed when do mac init!"); + return false; + } + + if (napi_create_reference(env, argv[PARAM0], 1, &context->symKeyRef) != napi_ok) { + LOGE("create sym key ref failed when do mac init!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -258,6 +278,11 @@ static bool BuildMacJsUpdateCtx(napi_env env, napi_callback_info info, MacCtx *c context->mac = napiMac->GetMac(); + if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) { + LOGE("create mac ref failed when do mac update!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -288,6 +313,11 @@ static bool BuildMacJsDoFinalCtx(napi_env env, napi_callback_info info, MacCtx * context->mac = napiMac->GetMac(); + if (napi_create_reference(env, thisVar, 1, &context->macRef) != napi_ok) { + LOGE("create mac ref failed when do mac final!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_md.cpp b/frameworks/js/napi/crypto/src/napi_md.cpp index 1172201c22197098e0018dda8114d406156b0865..c5d32d8dd51fa83963c93424f53439d0a9c814b4 100644 --- a/frameworks/js/napi/crypto/src/napi_md.cpp +++ b/frameworks/js/napi/crypto/src/napi_md.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -33,6 +33,7 @@ struct MdCtx { napi_ref callback = nullptr; napi_deferred deferred = nullptr; napi_value promise = nullptr; + napi_ref mdRef = nullptr; napi_async_work asyncWork = nullptr; @@ -58,6 +59,10 @@ static void FreeCryptoFwkCtx(napi_env env, MdCtx *context) napi_delete_reference(env, context->callback); context->callback = nullptr; } + if (context->mdRef != nullptr) { + napi_delete_reference(env, context->mdRef); + context->mdRef = nullptr; + } if (context->inBlob != nullptr) { HcfFree(context->inBlob->data); context->inBlob->data = nullptr; @@ -192,6 +197,11 @@ static bool BuildMdJsUpdateCtx(napi_env env, napi_callback_info info, MdCtx *con context->md = napiMd->GetMd(); + if (napi_create_reference(env, thisVar, 1, &context->mdRef) != napi_ok) { + LOGE("create md ref failed when do md update!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -223,6 +233,11 @@ static bool BuildMdJsDoFinalCtx(napi_env env, napi_callback_info info, MdCtx *co context->md = napiMd->GetMd(); + if (napi_create_reference(env, thisVar, 1, &context->mdRef) != napi_ok) { + LOGE("create md ref failed when do md final!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_pri_key.cpp b/frameworks/js/napi/crypto/src/napi_pri_key.cpp index baa1966b8f4c94a2a2b66b9e14e8445589e42ad2..b0860e69cc4cd9effe9b5c760d4b50c071ac8dc0 100644 --- a/frameworks/js/napi/crypto/src/napi_pri_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_pri_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -211,10 +211,53 @@ napi_value NapiPriKey::JsGetAsyKeySpec(napi_env env, napi_callback_info info) } } +napi_value NapiPriKey::JsGetEncodedDer(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiPriKey *napiPriKey = nullptr; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != ARGS_SIZE_ONE) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + std::string format; + if (!GetStringFromJSParams(env, argv[0], format)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format.")); + LOGE("get format fail."); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPriKey)); + if (status != napi_ok || napiPriKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap private key obj!")); + LOGE("failed to unwrap private key obj!"); + return nullptr; + } + HcfPriKey *priKey = napiPriKey->GetPriKey(); + if (priKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get private key obj!")); + LOGE("failed to get private key obj!"); + return nullptr; + } + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult res = priKey->getEncodedDer(priKey, format.c_str(), &returnBlob); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "ecc get private key encodedDer fail.")); + LOGE("ecc get private key encodeDer fail."); + return nullptr; + } + napi_value instance = ConvertBlobToNapiValue(env, &returnBlob); + HcfBlobDataFree(&returnBlob); + return instance; +} + void NapiPriKey::DefinePriKeyJSClass(napi_env env) { napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("getEncoded", NapiPriKey::JsGetEncoded), + DECLARE_NAPI_FUNCTION("getEncodedDer", NapiPriKey::JsGetEncodedDer), DECLARE_NAPI_FUNCTION("clearMem", NapiPriKey::JsClearMem), DECLARE_NAPI_FUNCTION("getAsyKeySpec", NapiPriKey::JsGetAsyKeySpec), }; diff --git a/frameworks/js/napi/crypto/src/napi_pub_key.cpp b/frameworks/js/napi/crypto/src/napi_pub_key.cpp index 113b2b40419c8f4438bb347fc7d707faefb2768a..8217afff81af5f1de512d813110182fb86adadd4 100644 --- a/frameworks/js/napi/crypto/src/napi_pub_key.cpp +++ b/frameworks/js/napi/crypto/src/napi_pub_key.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -85,7 +85,53 @@ napi_value NapiPubKey::JsGetEncoded(napi_env env, napi_callback_info info) HcfResult res = pubKey->base.getEncoded(&pubKey->base, &returnBlob); if (res != HCF_SUCCESS) { napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "c getEncoded fail.")); - LOGD("[error] c getEncoded fail."); + LOGE("c getEncoded fail."); + return nullptr; + } + + napi_value instance = ConvertBlobToNapiValue(env, &returnBlob); + HcfBlobDataFree(&returnBlob); + return instance; +} + +napi_value NapiPubKey::JsGetEncodedDer(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiPubKey *napiPubKey = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetEncodedDer fail, wrong argument num.")); + return nullptr; + } + std::string format; + if (!GetStringFromJSParams(env, argv[PARAM0], format)) { + LOGE("get format fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format.")); + return nullptr; + } + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiPubKey)); + if (status != napi_ok || napiPubKey == nullptr) { + LOGE("failed to unwrap napiPubKeyDer obj!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPubKeyDer obj!")); + return nullptr; + } + + HcfPubKey *pubKey = napiPubKey->GetPubKey(); + if (pubKey == nullptr) { + LOGE("failed to get pubKeyDer obj!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get pubKeyDer obj!")); + return nullptr; + } + + HcfBlob returnBlob; + HcfResult res = pubKey->getEncodedDer(pubKey, format.c_str(), &returnBlob); + if (res != HCF_SUCCESS) { + LOGE("c getEncodedDer fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "c getEncodedDer fail.")); return nullptr; } @@ -190,6 +236,7 @@ void NapiPubKey::DefinePubKeyJSClass(napi_env env) { napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("getEncoded", NapiPubKey::JsGetEncoded), + DECLARE_NAPI_FUNCTION("getEncodedDer", NapiPubKey::JsGetEncodedDer), DECLARE_NAPI_FUNCTION("getAsyKeySpec", NapiPubKey::JsGetAsyKeySpec), }; napi_value constructor = nullptr; diff --git a/frameworks/js/napi/crypto/src/napi_rand.cpp b/frameworks/js/napi/crypto/src/napi_rand.cpp index d95570285a4cd8c8b6525064d4b87cb5ecc8f7fe..212a7c511434cbe6d6389be8c050e551035bb3ef 100644 --- a/frameworks/js/napi/crypto/src/napi_rand.cpp +++ b/frameworks/js/napi/crypto/src/napi_rand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -34,6 +34,7 @@ struct RandCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref randomRef = nullptr; int32_t numBytes = 0; HcfBlob *seedBlob = nullptr; @@ -58,6 +59,10 @@ static void FreeCryptoFwkCtx(napi_env env, RandCtx *context) napi_delete_reference(env, context->callback); context->callback = nullptr; } + if (context->randomRef != nullptr) { + napi_delete_reference(env, context->randomRef); + context->randomRef = nullptr; + } if (context->seedBlob != nullptr) { HcfFree(context->seedBlob->data); context->seedBlob->data = nullptr; @@ -171,6 +176,11 @@ static bool BuildGenerateRandomCtx(napi_env env, napi_callback_info info, RandCt context->rand = napiRand->GetRand(); + if (napi_create_reference(env, thisVar, 1, &context->randomRef) != napi_ok) { + LOGE("create random ref failed when generate random!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_sign.cpp b/frameworks/js/napi/crypto/src/napi_sign.cpp index 23ee95cac5b05753f93e642c5cc0bda1b2f1db0b..56becc2689953a3683c0badfd520d1fce901bb9e 100644 --- a/frameworks/js/napi/crypto/src/napi_sign.cpp +++ b/frameworks/js/napi/crypto/src/napi_sign.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -34,6 +34,8 @@ struct SignInitCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref signRef = nullptr; + napi_ref priKeyRef = nullptr; HcfSign *sign = nullptr; HcfParamsSpec *params = nullptr; @@ -51,6 +53,7 @@ struct SignUpdateCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref signRef = nullptr; HcfSign *sign; HcfBlob *data; @@ -67,6 +70,7 @@ struct SignDoFinalCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref signRef = nullptr; HcfSign *sign; HcfBlob *data; @@ -92,6 +96,16 @@ static void FreeSignInitCtx(napi_env env, SignInitCtx *ctx) napi_delete_reference(env, ctx->callback); } + if (ctx->signRef != nullptr) { + napi_delete_reference(env, ctx->signRef); + ctx->signRef = nullptr; + } + + if (ctx->priKeyRef != nullptr) { + napi_delete_reference(env, ctx->priKeyRef); + ctx->priKeyRef = nullptr; + } + HcfFree(ctx); } @@ -109,6 +123,11 @@ static void FreeSignUpdateCtx(napi_env env, SignUpdateCtx *ctx) napi_delete_reference(env, ctx->callback); } + if (ctx->signRef != nullptr) { + napi_delete_reference(env, ctx->signRef); + ctx->signRef = nullptr; + } + HcfBlobDataFree(ctx->data); HcfFree(ctx->data); HcfFree(ctx); @@ -130,6 +149,11 @@ static void FreeSignDoFinalCtx(napi_env env, SignDoFinalCtx *ctx) ctx->callback = nullptr; } + if (ctx->signRef != nullptr) { + napi_delete_reference(env, ctx->signRef); + ctx->signRef = nullptr; + } + if (ctx->returnSignatureData.data != nullptr) { HcfFree(ctx->returnSignatureData.data); ctx->returnSignatureData.data = nullptr; @@ -173,6 +197,16 @@ static bool BuildSignJsInitCtx(napi_env env, napi_callback_info info, SignInitCt ctx->params = nullptr; ctx->priKey = napiPriKey->GetPriKey(); + if (napi_create_reference(env, thisVar, 1, &ctx->signRef) != napi_ok) { + LOGE("create sign ref failed when do sign init!"); + return false; + } + + if (napi_create_reference(env, argv[PARAM0], 1, &ctx->priKeyRef) != napi_ok) { + LOGE("create private key ref failed when do sign init!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -211,6 +245,11 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda ctx->sign = napiSign->GetSign(); ctx->data = blob; + if (napi_create_reference(env, thisVar, 1, &ctx->signRef) != napi_ok) { + LOGE("create sign ref failed when do sign update!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -254,6 +293,11 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF ctx->sign = napiSign->GetSign(); ctx->data = data; + if (napi_create_reference(env, thisVar, 1, &ctx->signRef) != napi_ok) { + LOGE("create sign ref failed when do sign final!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; diff --git a/frameworks/js/napi/crypto/src/napi_sm2_crypto_util.cpp b/frameworks/js/napi/crypto/src/napi_sm2_crypto_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d44e4262b11e0506488028cccc446372e92f3298 --- /dev/null +++ b/frameworks/js/napi/crypto/src/napi_sm2_crypto_util.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2022-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 "napi_sm2_crypto_util.h" + +#include +#include "securec.h" +#include "log.h" +#include "memory.h" +#include "napi_crypto_framework_defines.h" +#include "napi_utils.h" + +namespace OHOS { +namespace CryptoFramework { +NapiSm2CryptoUtil::NapiSm2CryptoUtil() {} +NapiSm2CryptoUtil::~NapiSm2CryptoUtil() {} + +static HcfBlob *GetBlobFromNapi(napi_env env, napi_value arg, const std::string &name) +{ + // get uint8Array attribute + napi_value data = nullptr; + napi_valuetype valueType = napi_undefined; + napi_status status = napi_get_named_property(env, arg, name.c_str(), &data); + napi_typeof(env, data, &valueType); + if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { + LOGE("failed to get valid salt"); + return nullptr; + } + return GetBlobFromNapiUint8Arr(env, data); +} + +static bool GetSm2CipherTextSpecFromNapiValue(napi_env env, napi_value arg, Sm2CipherTextSpec **returnSpec) +{ + if ((env == nullptr) || (arg == nullptr) || (returnSpec == nullptr)) { + LOGE("Invalid params."); + return false; + } + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + LOGE("Malloc failed!"); + return false; + } + napi_value xCoordinate = GetDetailAsyKeySpecValue(env, arg, SM2_UTIL_PARAM_X_COORDINATE); + napi_value yCoordinate = GetDetailAsyKeySpecValue(env, arg, SM2_UTIL_PARAM_Y_COORDINATE); + if ((xCoordinate == nullptr) || (yCoordinate == nullptr)) { + LOGE("Invalid params!"); + DestroySm2CipherTextSpec(tempSpec); + return false; + } + bool ret = GetBigIntFromNapiValue(env, xCoordinate, &tempSpec->xCoordinate); + if (!ret) { + LOGE("Failed to get valid x coordinate."); + DestroySm2CipherTextSpec(tempSpec); + return false; + } + ret = GetBigIntFromNapiValue(env, yCoordinate, &tempSpec->yCoordinate); + if (!ret) { + LOGE("Failed to get valid y coordinate."); + DestroySm2CipherTextSpec(tempSpec); + return false; + } + HcfBlob *cipherTextBlob = GetBlobFromNapi(env, arg, SM2_UTIL_PARAM_CIPHER_TEXT_DATA); + if (cipherTextBlob == nullptr) { + LOGE("Failed to get valid cipherTextData."); + DestroySm2CipherTextSpec(tempSpec); + return false; + } + HcfBlob *hashDataBlob = GetBlobFromNapi(env, arg, SM2_UTIL_PARAM_HASH_DATA); + if (hashDataBlob == nullptr) { + LOGE("Failed to get valid hashData."); + HcfBlobDataFree(cipherTextBlob); + HcfFree(cipherTextBlob); + DestroySm2CipherTextSpec(tempSpec); + return false; + } + tempSpec->cipherTextData = *cipherTextBlob; + tempSpec->hashData = *hashDataBlob; + *returnSpec = tempSpec; + HcfFree(cipherTextBlob); + HcfFree(hashDataBlob); + return true; +} + +static bool DealMode(napi_env env, napi_value arg, std::string &returnStr) +{ + napi_valuetype valueType; + napi_typeof(env, arg, &valueType); + if (valueType == napi_null || valueType == napi_undefined) { + return true; + } + if (!GetStringFromJSParams(env, arg, returnStr)) { + return false; + } + return true; +} + +napi_value NapiSm2CryptoUtil::JsGenCipherTextBySpec(napi_env env, napi_callback_info info) +{ + size_t expectedArgc = PARAMS_NUM_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + // second attribute mode can be null + if ((argc != expectedArgc) && (argc != (expectedArgc - 1))) { + LOGE("The input args num is invalid."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); + return nullptr; + } + Sm2CipherTextSpec *spec = nullptr; + if (!GetSm2CipherTextSpecFromNapiValue(env, argv[0], &spec)) { + LOGE("Failed to get spec."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get spec.")); + return nullptr; + } + std::string dataMode; + if (argc == expectedArgc) { + if (!DealMode(env, argv[1], dataMode)) { + LOGE("Failed to get mode."); + DestroySm2CipherTextSpec(spec); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get mode.")); + return nullptr; + } + } + HcfBlob *output = static_cast(HcfMalloc(sizeof(HcfBlob), 0)); + if (output == NULL) { + LOGE("Failed to allocate HcfBlob memory!"); + DestroySm2CipherTextSpec(spec); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "Failed to allocate memory.")); + return nullptr; + } + HcfResult res = HcfGenCipherTextBySpec(spec, dataMode.c_str(), output); + if (res != HCF_SUCCESS) { + LOGE("Gen cipher text by spec fail."); + HcfFree(output); + DestroySm2CipherTextSpec(spec); + napi_throw(env, GenerateBusinessError(env, res, "gen cipher text by spec fail.")); + return nullptr; + } + napi_value instance = ConvertBlobToNapiValue(env, output); + HcfBlobDataFree(output); + HcfFree(output); + DestroySm2CipherTextSpec(spec); + return instance; +} + +static bool CheckSm2CipherTextSpec(Sm2CipherTextSpec *spec) +{ + if (spec == nullptr) { + LOGE("Invalid spec!"); + return false; + } + if (spec->xCoordinate.data == nullptr || spec->xCoordinate.len == 0) { + LOGE("Invalid xCoordinate!"); + return false; + } + if (spec->yCoordinate.data == nullptr || spec->yCoordinate.len == 0) { + LOGE("Invalid yCoordinate!"); + return false; + } + if (spec->cipherTextData.data == nullptr || spec->cipherTextData.len == 0) { + LOGE("Invalid cipherTextData!"); + return false; + } + if (spec->hashData.data == nullptr || spec->hashData.len == 0) { + LOGE("Invalid hashData!"); + return false; + } + return true; +} + +static bool BuildBlobNapiValue(napi_env env, HcfBlob *blob, const char *name, napi_value *instance) +{ + napi_value napiData = ConvertObjectBlobToNapiValue(env, blob); + napi_status status = napi_set_named_property(env, *instance, name, napiData); + if (status != napi_ok) { + LOGE("Build blob[napi_value] failed!"); + return false; + } + return true; +} + +static bool BuildSm2CipherTextSpecToNapiValue(napi_env env, Sm2CipherTextSpec *spec, napi_value *instance) +{ + if (!BuildSetNamedProperty(env, &(spec->xCoordinate), SM2_UTIL_PARAM_X_COORDINATE.c_str(), instance)) { + LOGE("Build xCoordinate failed!"); + return false; + } + if (!BuildSetNamedProperty(env, &(spec->yCoordinate), SM2_UTIL_PARAM_Y_COORDINATE.c_str(), instance)) { + LOGE("Build yCoordinate failed!"); + return false; + } + if (!BuildBlobNapiValue(env, &(spec->cipherTextData), SM2_UTIL_PARAM_CIPHER_TEXT_DATA.c_str(), instance)) { + LOGE("Build cipherTextData failed!"); + return false; + } + if (!BuildBlobNapiValue(env, &(spec->hashData), SM2_UTIL_PARAM_HASH_DATA.c_str(), instance)) { + LOGE("Build hashData failed!"); + return false; + } + return true; +} + +static napi_value ConvertSm2CipherTextSpecToNapiValue(napi_env env, Sm2CipherTextSpec *spec) +{ + if (!CheckSm2CipherTextSpec(spec)) { + LOGE("Invalid spec!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid spec!")); + return NapiGetNull(env); + } + napi_value instance; + napi_status status = napi_create_object(env, &instance); + if (status != napi_ok) { + LOGE("Create object failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create object failed!")); + return NapiGetNull(env); + } + if (!BuildSm2CipherTextSpecToNapiValue(env, spec, &instance)) { + LOGE("Build object failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build object failed!")); + return NapiGetNull(env); + } + return instance; +} + +napi_value NapiSm2CryptoUtil::JsGetCipherTextSpec(napi_env env, napi_callback_info info) +{ + size_t expectedArgc = PARAMS_NUM_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + // second attribute mode can be null + if ((argc != expectedArgc) && (argc != (expectedArgc - 1))) { + LOGE("The input args num is invalid."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); + return nullptr; + } + HcfBlob *cipherText = GetBlobFromNapiDataBlob(env, argv[0]); + if (cipherText == nullptr) { + LOGE("Failed to get cipherText."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get cipherText.")); + return nullptr; + } + std::string dataMode; + if (argc == expectedArgc) { + if (!DealMode(env, argv[1], dataMode)) { + LOGE("Failed to get mode."); + HcfBlobDataFree(cipherText); + HcfFree(cipherText); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get mode.")); + return nullptr; + } + } + Sm2CipherTextSpec *returnSpec = nullptr; + HcfResult res = HcfGetCipherTextSpec(cipherText, dataMode.c_str(), &returnSpec); + if (res != HCF_SUCCESS) { + LOGE("Get cipher text spec fail."); + HcfBlobDataFree(cipherText); + HcfFree(cipherText); + napi_throw(env, GenerateBusinessError(env, res, "get cipher text spec fail.")); + return nullptr; + } + napi_value instance = ConvertSm2CipherTextSpecToNapiValue(env, returnSpec); + DestroySm2CipherTextSpec(returnSpec); + HcfBlobDataFree(cipherText); + HcfFree(cipherText); + return instance; +} + +napi_value NapiSm2CryptoUtil::Sm2CryptoUtilConstructor(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + return thisVar; +} + +napi_value NapiSm2CryptoUtil::Sm2CryptoUtilConstructorClass(napi_env env) +{ + napi_value cons = nullptr; + napi_property_descriptor clzDes[] = { + DECLARE_NAPI_STATIC_FUNCTION("genCipherTextBySpec", NapiSm2CryptoUtil::JsGenCipherTextBySpec), + DECLARE_NAPI_STATIC_FUNCTION("getCipherTextSpec", NapiSm2CryptoUtil::JsGetCipherTextSpec), + }; + NAPI_CALL(env, napi_define_class(env, "SM2CryptoUtil", NAPI_AUTO_LENGTH, + NapiSm2CryptoUtil::Sm2CryptoUtilConstructor, + nullptr, sizeof(clzDes) / sizeof(clzDes[0]), clzDes, &cons)); + return cons; +} + +void NapiSm2CryptoUtil::DefineNapiSm2CryptoUtilJSClass(napi_env env, napi_value exports) +{ + napi_set_named_property(env, exports, "SM2CryptoUtil", NapiSm2CryptoUtil::Sm2CryptoUtilConstructorClass(env)); +} +} // CryptoFramework +} // OHOS + \ No newline at end of file diff --git a/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp index 918ac652013831a60e7a8d8c54cadbfa3b048aba..10697cb91d62f1fc79e94f8ca51f93739a2b8488 100644 --- a/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -33,7 +33,8 @@ struct SymKeyGeneratorFwkCtxT { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; - + napi_ref symKeyGeneratorRef = nullptr; + HcfResult errCode = HCF_SUCCESS; HcfSymKey *returnSymKey = nullptr; const char *errMsg = nullptr; @@ -60,6 +61,11 @@ static void FreeSymKeyGeneratorFwkCtx(napi_env env, SymKeyGeneratorFwkCtx &conte context->callback = nullptr; } + if (context->symKeyGeneratorRef != nullptr) { + napi_delete_reference(env, context->symKeyGeneratorRef); + context->symKeyGeneratorRef = nullptr; + } + if (context->keyMaterial.data != nullptr) { (void)memset_s(context->keyMaterial.data, context->keyMaterial.len, 0, context->keyMaterial.len); HcfFree(context->keyMaterial.data); @@ -96,6 +102,12 @@ static bool BuildContextForGenerateKey(napi_env env, napi_callback_info info, Sy LOGE("failed to get generator obj!"); return false; } + + if (napi_create_reference(env, thisVar, 1, &context->symKeyGeneratorRef) != napi_ok) { + LOGE("create sym key generator ref failed when generate sym key!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -138,6 +150,12 @@ static bool BuildContextForConvertKey(napi_env env, napi_callback_info info, Sym } context->keyMaterial = *blob; HcfFree(blob); + + if (napi_create_reference(env, thisVar, 1, &context->symKeyGeneratorRef) != napi_ok) { + LOGE("create sym key generator ref failed when covert sym key!"); + return false; + } + if (context->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &context->deferred, &context->promise); return true; @@ -181,7 +199,7 @@ static void AsyncGenKeyProcess(napi_env env, void *data) HcfSymKey *key = nullptr; context->errCode = generator->generateSymKey(generator, &key); if (context->errCode != HCF_SUCCESS) { - LOGD("[error] generate sym key failed."); + LOGE("generate sym key failed."); context->errMsg = "generate sym key failed."; return; } @@ -231,7 +249,7 @@ static void AsyncConvertKeyProcess(napi_env env, void *data) HcfSymKey *key = nullptr; context->errCode = generator->convertSymKey(generator, &context->keyMaterial, &key); if (context->errCode != HCF_SUCCESS) { - LOGD("[error] convertSymKey key failed!"); + LOGE("convertSymKey key failed!"); context->errMsg = "convert sym key failed."; return; } @@ -310,6 +328,32 @@ HcfSymKeyGenerator *NapiSymKeyGenerator::GetSymKeyGenerator() const return this->generator_; } +static bool napiGetInstance(napi_env env, HcfSymKey *key, napi_value instance) +{ + NapiSymKey *napiSymKey = new (std::nothrow) NapiSymKey(key); + if (napiSymKey == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sym key failed.")); + LOGE("new napi sym key failed."); + HcfObjDestroy(key); + return false; + } + + napi_status wrapStatus = napi_wrap( + env, instance, napiSymKey, + [](napi_env env, void *data, void *hint) { + NapiSymKey *napiSymKey = static_cast(data); + delete napiSymKey; + return; + }, nullptr, nullptr); + if (wrapStatus != napi_ok) { + LOGE("failed to wrap napiSymKey obj!"); + delete napiSymKey; + return false; + } + + return true; +} + napi_value NapiSymKeyGenerator::JsGenerateSymKey(napi_env env, napi_callback_info info) { SymKeyGeneratorFwkCtx context = static_cast(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0)); @@ -335,6 +379,42 @@ napi_value NapiSymKeyGenerator::JsGenerateSymKey(napi_env env, napi_callback_inf return result; } +napi_value NapiSymKeyGenerator::JsGenerateSymKeySync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + NapiSymKeyGenerator *napiGenerator = nullptr; + napi_status unwrapStatus = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (unwrapStatus != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap NapiSymKeyGenerator obj!"); + return nullptr; + } + + HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator(); + if (generator == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to get generator obj.")); + LOGE("failed to get generator obj!"); + return nullptr; + } + + HcfSymKey *key = nullptr; + HcfResult ret = generator->generateSymKey(generator, &key); + if (ret != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "generate sym key failed.")); + LOGE("generate sym key failed."); + return nullptr; + } + + napi_value instance = NapiSymKey::CreateSymKey(env); + if (!napiGetInstance(env, key, instance)) { + napi_throw(env, GenerateBusinessError(env, HCF_NOT_SUPPORT, "get instance failed!")); + LOGE("get instance failed!"); + return nullptr; + } + + return instance; +} + napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info) { SymKeyGeneratorFwkCtx context = static_cast(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0)); @@ -360,6 +440,60 @@ napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info in return result; } +napi_value NapiSymKeyGenerator::JsConvertKeySync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + LOGE("wrong argument num. require 1 or 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + + NapiSymKeyGenerator *napiGenerator = nullptr; + napi_status unwrapStatus = napi_unwrap(env, thisVar, reinterpret_cast(&napiGenerator)); + if (unwrapStatus != napi_ok || napiGenerator == nullptr) { + LOGE("failed to unwrap NapiSymKeyGenerator obj!"); + return nullptr; + } + + size_t index = 0; + HcfBlob *keyMaterial = GetBlobFromNapiDataBlob(env, argv[index++]); + if (keyMaterial == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get keyMaterial failed!")); + LOGE("get keyMaterial failed!"); + return nullptr; + } + + HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator(); + if (generator == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to get generator obj!")); + LOGE("failed to get generator obj!"); + HcfBlobDataFree(keyMaterial); + HcfFree(keyMaterial); + return nullptr; + } + + HcfSymKey *key = nullptr; + HcfResult ret = generator->convertSymKey(generator, keyMaterial, &key); + if (ret != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "convertSymKey key failed!")); + LOGE("convertSymKey key failed!"); + return nullptr; + } + + napi_value instance = NapiSymKey::CreateSymKey(env); + if (!napiGetInstance(env, key, instance)) { + napi_throw(env, GenerateBusinessError(env, HCF_NOT_SUPPORT, "get instance failed!")); + LOGE("get instance failed!"); + return nullptr; + } + + return instance; +} + napi_value NapiSymKeyGenerator::SymKeyGeneratorConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -451,7 +585,9 @@ void NapiSymKeyGenerator::DefineSymKeyGeneratorJSClass(napi_env env, napi_value napi_property_descriptor classDesc[] = { DECLARE_NAPI_FUNCTION("generateSymKey", NapiSymKeyGenerator::JsGenerateSymKey), + DECLARE_NAPI_FUNCTION("generateSymKeySync", NapiSymKeyGenerator::JsGenerateSymKeySync), DECLARE_NAPI_FUNCTION("convertKey", NapiSymKeyGenerator::JsConvertKey), + DECLARE_NAPI_FUNCTION("convertKeySync", NapiSymKeyGenerator::JsConvertKeySync), { .utf8name = "algName", .getter = NapiSymKeyGenerator::JsGetAlgorithm }, }; napi_value constructor = nullptr; diff --git a/frameworks/js/napi/crypto/src/napi_utils.cpp b/frameworks/js/napi/crypto/src/napi_utils.cpp index a7bcd04e771df25397f5761cdfe6eafcb43e272f..c86bc51da9473c7962a11a57c73f6d36ff878e45 100644 --- a/frameworks/js/napi/crypto/src/napi_utils.cpp +++ b/frameworks/js/napi/crypto/src/napi_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -224,7 +224,7 @@ static HcfBlob *GetAadFromParamsSpec(napi_env env, napi_value arg) bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt) { - if ((env == nullptr) || (arg == nullptr)) { + if ((env == nullptr) || (arg == nullptr) || (bigInt == nullptr)) { LOGE("Invalid params!"); return false; } @@ -258,9 +258,9 @@ bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt) return true; } -static bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point) +bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point) { - if ((env == nullptr) || (arg == nullptr)) { + if ((env == nullptr) || (arg == nullptr) || (point == nullptr)) { LOGE("Invalid params!"); return false; } @@ -513,10 +513,14 @@ bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMo } } -static napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, string argName) +napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, string argName) { napi_value data = nullptr; napi_valuetype valueType = napi_undefined; + if ((env == nullptr) || (arg == nullptr)) { + LOGE("Invalid params!"); + return nullptr; + } napi_status status = napi_get_named_property(env, arg, argName.c_str(), &data); napi_typeof(env, data, &valueType); if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) { @@ -1503,7 +1507,7 @@ napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob) return dataBlob; } -napi_value ConvertCipherBlobToNapiValue(napi_env env, HcfBlob *blob) +napi_value ConvertObjectBlobToNapiValue(napi_env env, HcfBlob *blob) { if (blob == nullptr || blob->data == nullptr || blob->len == 0) { napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!")); @@ -1813,6 +1817,58 @@ static napi_value ConvertEccCommonParamFieldFpToNapiValue(napi_env env, HcfEccCo return fieldFp; } +static bool IsNapiNull(napi_env env, napi_value value) +{ + napi_valuetype valueType; + napi_typeof(env, value, &valueType); + return (valueType == napi_null); +} + +napi_value ConvertEccPointToNapiValue(napi_env env, HcfPoint *p) +{ + if (p == nullptr) { + LOGE("Invalid point data!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid point data!")); + return nullptr; + } + + napi_value point; + napi_status status = napi_create_object(env, &point); + if (status != napi_ok) { + LOGE("create object failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create object failed!")); + return nullptr; + } + + napi_value x = ConvertBigIntToNapiValue(env, &(p->x)); + if (x == nullptr || IsNapiNull(env, x)) { + LOGE("Failed to convert x to NapiValue!"); + return nullptr; + } + + napi_value y = ConvertBigIntToNapiValue(env, &(p->y)); + if (y == nullptr || IsNapiNull(env, y)) { + LOGE("Failed to convert y to NapiValue!"); + return nullptr; + } + + status = napi_set_named_property(env, point, "x", x); + if (status != napi_ok) { + LOGE("set x property failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set x property failed!")); + return nullptr; + } + + status = napi_set_named_property(env, point, "y", y); + if (status != napi_ok) { + LOGE("set y property failed!"); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "set y property failed!")); + return nullptr; + } + + return point; +} + static napi_value ConvertEccCommonParamPointToNapiValue(napi_env env, HcfEccCommParamsSpec *blob) { napi_value point; diff --git a/frameworks/js/napi/crypto/src/napi_verify.cpp b/frameworks/js/napi/crypto/src/napi_verify.cpp index 6f587f84abb37f06a892a35156b9074c17282061..76faf5d995eca03fc06dd351059baeffa2985837 100644 --- a/frameworks/js/napi/crypto/src/napi_verify.cpp +++ b/frameworks/js/napi/crypto/src/napi_verify.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -34,6 +34,8 @@ struct VerifyInitCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref verifyRef = nullptr; + napi_ref pubKeyRef = nullptr; HcfVerify *verify = nullptr; HcfParamsSpec *params = nullptr; @@ -51,6 +53,7 @@ struct VerifyUpdateCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref verifyRef = nullptr; HcfVerify *verify = nullptr; HcfBlob *data = nullptr; @@ -67,6 +70,7 @@ struct VerifyDoFinalCtx { napi_deferred deferred = nullptr; napi_value promise = nullptr; napi_async_work asyncWork = nullptr; + napi_ref verifyRef = nullptr; HcfVerify *verify = nullptr; HcfBlob *data = nullptr; @@ -77,6 +81,22 @@ struct VerifyDoFinalCtx { bool isVerifySucc; }; +struct VerifyRecoverCtx { + napi_env env = nullptr; + + napi_deferred deferred = nullptr; + napi_value promise = nullptr; + napi_async_work asyncWork = nullptr; + napi_ref verifyRef = nullptr; + + HcfVerify *verify = nullptr; + HcfBlob *signatureData = nullptr; + + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; + HcfBlob rawSignatureData; +}; + thread_local napi_ref NapiVerify::classRef_ = nullptr; static void FreeVerifyInitCtx(napi_env env, VerifyInitCtx *ctx) @@ -95,6 +115,16 @@ static void FreeVerifyInitCtx(napi_env env, VerifyInitCtx *ctx) ctx->callback = nullptr; } + if (ctx->verifyRef != nullptr) { + napi_delete_reference(env, ctx->verifyRef); + ctx->verifyRef = nullptr; + } + + if (ctx->pubKeyRef != nullptr) { + napi_delete_reference(env, ctx->pubKeyRef); + ctx->pubKeyRef = nullptr; + } + HcfFree(ctx); } @@ -114,6 +144,11 @@ static void FreeVerifyUpdateCtx(napi_env env, VerifyUpdateCtx *ctx) ctx->callback = nullptr; } + if (ctx->verifyRef != nullptr) { + napi_delete_reference(env, ctx->verifyRef); + ctx->verifyRef = nullptr; + } + HcfBlobDataFree(ctx->data); HcfFree(ctx->data); HcfFree(ctx); @@ -135,6 +170,11 @@ static void FreeVerifyDoFinalCtx(napi_env env, VerifyDoFinalCtx *ctx) ctx->callback = nullptr; } + if (ctx->verifyRef != nullptr) { + napi_delete_reference(env, ctx->verifyRef); + ctx->verifyRef = nullptr; + } + HcfBlobDataFree(ctx->data); HcfFree(ctx->data); HcfBlobDataFree(ctx->signatureData); @@ -142,6 +182,33 @@ static void FreeVerifyDoFinalCtx(napi_env env, VerifyDoFinalCtx *ctx) HcfFree(ctx); } +static void FreeVerifyRecoverCtx(napi_env env, VerifyRecoverCtx *ctx) +{ + if (ctx == nullptr) { + return; + } + + if (ctx->asyncWork != nullptr) { + napi_delete_async_work(env, ctx->asyncWork); + ctx->asyncWork = nullptr; + } + + if (ctx->verifyRef != nullptr) { + napi_delete_reference(env, ctx->verifyRef); + ctx->verifyRef = nullptr; + } + + if (ctx->rawSignatureData.data != nullptr) { + HcfFree(ctx->rawSignatureData.data); + ctx->rawSignatureData.data = nullptr; + ctx->rawSignatureData.len = 0; + } + + HcfBlobDataFree(ctx->signatureData); + HcfFree(ctx->signatureData); + HcfFree(ctx); +} + static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyInitCtx *ctx) { napi_value thisVar = nullptr; @@ -174,6 +241,16 @@ static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyIn ctx->params = nullptr; ctx->pubKey = napiPubKey->GetPubKey(); + if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) { + LOGE("create verify ref failed when do verify init!"); + return false; + } + + if (napi_create_reference(env, argv[PARAM0], 1, &ctx->pubKeyRef) != napi_ok) { + LOGE("create verify ref failed when do verify init!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -212,6 +289,11 @@ static bool BuildVerifyJsUpdateCtx(napi_env env, napi_callback_info info, Verify ctx->verify = napiVerify->GetVerify(); ctx->data = blob; + if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) { + LOGE("create verify ref failed when do verify update!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -277,6 +359,11 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif ctx->data = data; ctx->signatureData = signatureData; + if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) { + LOGE("create verify ref failed when do verify final!"); + return false; + } + if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); return true; @@ -369,6 +456,15 @@ static void ReturnDoFinalPromiseResult(napi_env env, VerifyDoFinalCtx *ctx, napi } } +static void ReturnRecoverPromiseResult(napi_env env, VerifyRecoverCtx *ctx, napi_value result) +{ + if (ctx->errCode == HCF_SUCCESS) { + napi_resolve_deferred(env, ctx->deferred, result); + } else { + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); + } +} + static void VerifyJsInitAsyncWorkProcess(napi_env env, void *data) { VerifyInitCtx *ctx = static_cast(data); @@ -444,6 +540,31 @@ static void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, voi FreeVerifyDoFinalCtx(env, ctx); } +static void VerifyJsRecoverAsyncWorkProcess(napi_env env, void *data) +{ + VerifyRecoverCtx *ctx = static_cast(data); + + ctx->errCode = ctx->verify->recover(ctx->verify, ctx->signatureData, &ctx->rawSignatureData); + if (ctx->errCode != HCF_SUCCESS) { + LOGD("[error] verify revover fail."); + ctx->errMsg = "verify revover fail."; + } +} + +static void VerifyJsRecoverAsyncWorkReturn(napi_env env, napi_status status, void *data) +{ + VerifyRecoverCtx *ctx = static_cast(data); + + napi_value dataBlob = nullptr; + if (ctx->errCode == HCF_SUCCESS) { + dataBlob = ConvertBlobToNapiValue(env, &ctx->rawSignatureData); + } + + ReturnRecoverPromiseResult(env, ctx, dataBlob); + + FreeVerifyRecoverCtx(env, ctx); +} + static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx) { napi_value resourceName = nullptr; @@ -522,6 +643,28 @@ static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ct } } +static napi_value NewVerifyJsRecoverAsyncWork(napi_env env, VerifyRecoverCtx *ctx) +{ + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_async_work( + env, nullptr, resourceName, + [](napi_env env, void *data) { + VerifyJsRecoverAsyncWorkProcess(env, data); + return; + }, + [](napi_env env, napi_status status, void *data) { + VerifyJsRecoverAsyncWorkReturn(env, status, data); + return; + }, + static_cast(ctx), + &ctx->asyncWork); + + napi_queue_async_work(env, ctx->asyncWork); + return ctx->promise; +} + NapiVerify::NapiVerify(HcfVerify *verify) { this->verify_ = verify; @@ -594,6 +737,118 @@ napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info) return NewVerifyJsDoFinalAsyncWork(env, ctx); } +static bool BuildVerifyJsRecoverCtx(napi_env env, napi_callback_info info, VerifyRecoverCtx *ctx) +{ + napi_value thisVar = nullptr; + size_t expectedArgc = PARAMS_NUM_ONE; + size_t argc = PARAMS_NUM_ONE; + napi_value argv[PARAMS_NUM_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + LOGE("wrong argument num. require %zu arguments. [Argc]: %zu!", expectedArgc, argc); + return false; + } + + NapiVerify *napiVerify = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); + if (status != napi_ok || napiVerify == nullptr) { + LOGE("failed to unwrap napi verify obj."); + return false; + } + + ctx->verify = napiVerify->GetVerify(); + if (ctx->verify == nullptr) { + LOGE("failed to get verify obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get verify obj.")); + return false; + } + + HcfBlob *signatureData = GetBlobFromNapiDataBlob(env, argv[PARAM0]); + if (signatureData == nullptr) { + LOGE("failed to get signature."); + return false; + } + ctx->signatureData = signatureData; + + if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) { + LOGE("create verify ref failed when do verify recover!"); + return false; + } + + napi_create_promise(env, &ctx->deferred, &ctx->promise); + return true; +} + +napi_value NapiVerify::JsRecover(napi_env env, napi_callback_info info) +{ + VerifyRecoverCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyRecoverCtx), 0)); + if (ctx == nullptr) { + LOGE("create context fail."); + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); + return nullptr; + } + + if (!BuildVerifyJsRecoverCtx(env, info, ctx)) { + LOGE("build context fail."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); + FreeVerifyRecoverCtx(env, ctx); + return nullptr; + } + + return NewVerifyJsRecoverAsyncWork(env, ctx); +} + +napi_value NapiVerify::JsRecoverSync(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t expectedArgc = PARAMS_NUM_ONE; + size_t argc = PARAMS_NUM_ONE; + napi_value argv[PARAMS_NUM_ONE] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc) { + LOGE("wrong argument num. require %zu argument. [Argc]: %zu!", expectedArgc, argc); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num.")); + return nullptr; + } + + NapiVerify *napiVerify = nullptr; + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); + if (status != napi_ok || napiVerify == nullptr) { + LOGE("failed to unwrap napi verify obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi verify obj.")); + return nullptr; + } + + HcfVerify *verify = napiVerify->GetVerify(); + if (verify == nullptr) { + LOGE("failed to get verify obj."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get verify obj.")); + return nullptr; + } + + HcfBlob *signatureData = GetBlobFromNapiDataBlob(env, argv[PARAM0]); + if (signatureData == nullptr) { + LOGE("failed to get signature data."); + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get signature data.")); + return nullptr; + } + + HcfBlob rawSignatureData = { .data = nullptr, .len = 0}; + HcfResult res = verify->recover(verify, signatureData, &rawSignatureData); + HcfBlobDataFree(signatureData); + HcfFree(signatureData); + signatureData = NULL; + if (res != HCF_SUCCESS) { + LOGE("failed to verify recover."); + napi_throw(env, GenerateBusinessError(env, res, "failed to verify recover.")); + return nullptr; + } + + napi_value instance = ConvertBlobToNapiValue(env, &rawSignatureData); + HcfBlobDataClearAndFree(&rawSignatureData); + return instance; +} + napi_value NapiVerify::VerifyConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -842,6 +1097,8 @@ void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiVerify::JsInit), DECLARE_NAPI_FUNCTION("update", NapiVerify::JsUpdate), DECLARE_NAPI_FUNCTION("verify", NapiVerify::JsVerify), + DECLARE_NAPI_FUNCTION("recover", NapiVerify::JsRecover), + DECLARE_NAPI_FUNCTION("recoverSync", NapiVerify::JsRecoverSync), DECLARE_NAPI_FUNCTION("setVerifySpec", NapiVerify::JsSetVerifySpec), DECLARE_NAPI_FUNCTION("getVerifySpec", NapiVerify::JsGetVerifySpec), }; diff --git a/frameworks/key/ecc_key_util.c b/frameworks/key/ecc_key_util.c index 19ce3429e310f82de615ab3a9906e5bf4cf8fb34..14a369255136ae68e7f5af0b36e9f9595d70ccf7 100644 --- a/frameworks/key/ecc_key_util.c +++ b/frameworks/key/ecc_key_util.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -51,6 +51,115 @@ static HcfEccCommParamsSpecCreateFunc FindAbility(HcfAsyKeyGenParams *params) return NULL; } +static bool IsBigIntegerValid(const HcfBigInteger *bigInt) +{ + if (bigInt == NULL) { + LOGE("Invalid HcfBigInteger parameter"); + return false; + } + if (bigInt->data == NULL) { + LOGE("BigInteger data is NULL"); + return false; + } + if (bigInt->len == 0) { + LOGE("BigInteger length is 0"); + return false; + } + return true; +} + +static bool IsPointValid(const HcfPoint *point) +{ + if (point == NULL) { + LOGE("Invalid point parameter"); + return false; + } + if (!IsBigIntegerValid(&(point->x))) { + LOGE("Invalid x coordinate parameter"); + return false; + } + if (!IsBigIntegerValid(&(point->y))) { + LOGE("Invalid y coordinate parameter"); + return false; + } + return true; +} + +HcfResult HcfConvertPoint(const char *curveName, HcfBlob *encodedPoint, HcfPoint *returnPoint) +{ + if (!IsStrValid(curveName, HCF_MAX_ALGO_NAME_LEN)) { + LOGE("Failed to parse params: curveName is invalid!"); + return HCF_INVALID_PARAMS; + } + + if (!IsBlobValid(encodedPoint)) { + LOGE("Failed to parse params: encodedPoint is invalid!"); + return HCF_INVALID_PARAMS; + } + + if (returnPoint == NULL) { + LOGE("Failed to parse params: returnPoint is NULL!"); + return HCF_INVALID_PARAMS; + } + + HcfAlgParaValue algValue = 0; + HcfResult ret = GetAlgValueByCurveName(curveName, &algValue); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get algValue."); + return ret; + } + + ret = HcfEngineConvertPoint(algValue, encodedPoint, returnPoint); + if (ret != HCF_SUCCESS) { + LOGE("Failed to create spi object!"); + return ret; + } + return HCF_SUCCESS; +} + +HcfResult HcfGetEncodedPoint(const char *curveName, HcfPoint *point, const char *format, HcfBlob *returnBlob) +{ + if (!IsStrValid(curveName, HCF_MAX_ALGO_NAME_LEN)) { + LOGE("Failed to parse params: curveName is invalid!"); + return HCF_INVALID_PARAMS; + } + + if (!IsPointValid(point)) { + LOGE("Failed to parse params: point is invalid!"); + return HCF_INVALID_PARAMS; + } + + if (format == NULL) { + LOGE("Failed to parse params: format is NULL!"); + return HCF_INVALID_PARAMS; + } + + HcfFormatValue formatValue = 0; + HcfResult ret = GetFormatValueByFormatName(format, &formatValue); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get formatValue."); + return ret; + } + + if (returnBlob == NULL) { + LOGE("Failed to parse params: returnBlob is NULL!"); + return HCF_INVALID_PARAMS; + } + + HcfAlgParaValue algValue = 0; + ret = GetAlgValueByCurveName(curveName, &algValue); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get algValue."); + return ret; + } + + ret = HcfEngineGetEncodedPoint(algValue, point, formatValue, returnBlob); + if (ret != HCF_SUCCESS) { + LOGE("Failed to create spi object!"); + return ret; + } + return HCF_SUCCESS; +} HcfResult HcfEccKeyUtilCreate(const char *algName, HcfEccCommParamsSpec **returnCommonParamSpec) { diff --git a/frameworks/key/sym_key_generator.c b/frameworks/key/sym_key_generator.c index f374b7f3d00911626f1837cdd875c0db2034ebb6..78feb04c0fad3bce277443ea85702adcc66edde0 100644 --- a/frameworks/key/sym_key_generator.c +++ b/frameworks/key/sym_key_generator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -36,6 +36,7 @@ #define HMAC_KEY_SIZE_SHA384 384 #define HMAC_KEY_SIZE_SHA512 512 #define HMAC_KEY_SIZE_SM3 256 +#define HMAC_KEY_SIZE_MD5 128 typedef HcfResult (*SymKeyGeneratorSpiCreateFunc)(SymKeyAttr *, HcfSymKeyGeneratorSpi **); @@ -137,9 +138,12 @@ static void SetKeyLenByDigest(HcfAlgParaValue value, void *attr) case HCF_OPENSSL_DIGEST_SM3: keyAttr->keySize = HMAC_KEY_SIZE_SM3; break; + case HCF_OPENSSL_DIGEST_MD5: + keyAttr->keySize = HMAC_KEY_SIZE_MD5; + break; default: - // We will ignore the 'MD5' and 'NoHash' inputs - LOGE("Invalid digest input: MD5 or NoHash"); + // We will ignore the and 'NoHash' inputs + LOGE("Invalid digest input: NoHash"); break; } } diff --git a/frameworks/spi/signature_spi.h b/frameworks/spi/signature_spi.h index 68e4c12bb6a6188a75b3c45f108b4384ccedcb48..39e50c958c0a4f2a842e7c808876a7a0e186c303 100644 --- a/frameworks/spi/signature_spi.h +++ b/frameworks/spi/signature_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -58,6 +58,8 @@ struct HcfVerifySpi { bool (*engineVerify)(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData); + HcfResult (*engineRecover)(HcfVerifySpi *self, HcfBlob *signatureData, HcfBlob *rawSignatureData); + HcfResult (*engineSetVerifySpecInt)(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen); HcfResult (*engineGetVerifySpecString)(HcfVerifySpi *self, SignSpecItem item, char **returnString); diff --git a/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h b/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h index a2af54078dd14a83050c6d7ee592334782d35d4e..4ab798d26718cbab18bbbe9d869151146ecb23d4 100644 --- a/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h +++ b/interfaces/innerkits/algorithm_parameter/detailed_ecc_key_params.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -66,6 +66,8 @@ typedef struct HcfEccKeyPairParamsSpec { extern "C" { #endif +void FreeEcPointMem(HcfPoint *point); + void FreeEccCommParamsSpec(HcfEccCommParamsSpec *spec); void DestroyEccPriKeySpec(HcfEccPriKeyParamsSpec *spec); diff --git a/interfaces/innerkits/algorithm_parameter/detailed_hkdf_params.h b/interfaces/innerkits/algorithm_parameter/detailed_hkdf_params.h new file mode 100644 index 0000000000000000000000000000000000000000..f6600b8e87043cb06c60d73633cdb470440bceeb --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/detailed_hkdf_params.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#ifndef HCF_DETAILED_HKDF_PARAMS_H +#define HCF_DETAILED_HKDF_PARAMS_H + +#include "blob.h" +#include "kdf_params.h" + +typedef struct HcfHkdfParamsSpec HcfHkdfParamsSpec; + +struct HcfHkdfParamsSpec { + HcfKdfParamsSpec base; + HcfBlob key; + HcfBlob salt; + HcfBlob info; + HcfBlob output; +}; + +#endif // HCF_DETAILED_HKDF_PARAMS_H diff --git a/interfaces/innerkits/algorithm_parameter/sm2_crypto_params.h b/interfaces/innerkits/algorithm_parameter/sm2_crypto_params.h new file mode 100644 index 0000000000000000000000000000000000000000..92db7f460e1a4f10ddcfb6a769f8c1d86c0716be --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/sm2_crypto_params.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef HCF_SM2_CRYPTO_PARAMS_H +#define HCF_SM2_CRYPTO_PARAMS_H + +#include "big_integer.h" +#include "blob.h" + +typedef struct Sm2CipherTextSpec { + HcfBigInteger xCoordinate; + HcfBigInteger yCoordinate; + HcfBlob cipherTextData; + HcfBlob hashData; +} Sm2CipherTextSpec; + +#ifdef __cplusplus +extern "C" { +#endif + +void DestroySm2CipherTextSpec(Sm2CipherTextSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/interfaces/innerkits/crypto_operation/signature.h b/interfaces/innerkits/crypto_operation/signature.h index 5646261c31208d05967129b38191eccb699d9385..5eeacc3df45c35b499bd4660bb00cf6912aded76 100644 --- a/interfaces/innerkits/crypto_operation/signature.h +++ b/interfaces/innerkits/crypto_operation/signature.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -64,6 +64,8 @@ struct HcfVerify { bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData); + HcfResult (*recover)(HcfVerify *self, HcfBlob *signatureData, HcfBlob *rawSignatureData); + const char *(*getAlgoName)(HcfVerify *self); HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen); diff --git a/interfaces/innerkits/crypto_operation/sm2_crypto_util.h b/interfaces/innerkits/crypto_operation/sm2_crypto_util.h new file mode 100644 index 0000000000000000000000000000000000000000..8c77a5f756f412a3502e104a996cb5357c03c36d --- /dev/null +++ b/interfaces/innerkits/crypto_operation/sm2_crypto_util.h @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#ifndef HCF_SM2_CRYPTO_UTIL_H +#define HCF_SM2_CRYPTO_UTIL_H + +#include "result.h" +#include "sm2_crypto_params.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Generate the SM2 ciphertext in ASN.1 format according to the specific data. + * + * @param spec - indicates the specific data of SM2 ciphertext. + * @param mode - indicates the arrangement mode of the SM2 ciphertext. + * @param output - the SM2 ciphertext in ASN.1 format. + * @return Returns the status code of the execution. + * @since 12 + * @version 1.0 + */ +HcfResult HcfGenCipherTextBySpec(Sm2CipherTextSpec *spec, const char *mode, HcfBlob *output); +/** + * @brief Get the specific data from the SM2 ciphertext in ASN.1 format. + * + * @param input - indicates the SM2 ciphertext in ASN.1 format. + * @param mode - indicates the arrangement mode of the SM2 ciphertext. + * @param returnSpc - the specific data of SM2 ciphertext. + * @return Returns the status code of the execution. + * @since 12 + * @version 1.0 + */ +HcfResult HcfGetCipherTextSpec(HcfBlob *input, const char *mode, Sm2CipherTextSpec **returnSpc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/interfaces/innerkits/key/ecc_key_util.h b/interfaces/innerkits/key/ecc_key_util.h index 782d7852dbae091c3138acbbf5d432185631c3ac..87e270e718edd4d7faa5c0d5c9d0d49e03cce174 100644 --- a/interfaces/innerkits/key/ecc_key_util.h +++ b/interfaces/innerkits/key/ecc_key_util.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -18,6 +18,7 @@ #include #include "result.h" +#include "blob.h" #include "detailed_ecc_key_params.h" #ifdef __cplusplus @@ -26,6 +27,10 @@ extern "C" { HcfResult HcfEccKeyUtilCreate(const char *algName, HcfEccCommParamsSpec **returnCommonParamSpec); +HcfResult HcfConvertPoint(const char *curveName, HcfBlob *encodedPoint, HcfPoint *returnPoint); + +HcfResult HcfGetEncodedPoint(const char *curveName, HcfPoint *point, const char *format, HcfBlob *returnBlob); + #ifdef __cplusplus } #endif diff --git a/interfaces/innerkits/key/pri_key.h b/interfaces/innerkits/key/pri_key.h index 72fd9ef9ac1221cc57b35cbfd8bbd98c21fce24b..d2b2e5985f9cf8420ad51935decfd39da0cca992 100644 --- a/interfaces/innerkits/key/pri_key.h +++ b/interfaces/innerkits/key/pri_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -31,6 +31,8 @@ struct HcfPriKey { HcfResult (*getAsyKeySpecInt)(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt); + HcfResult (*getEncodedDer)(const HcfPriKey *self, const char *format, HcfBlob *returnBlob); + void (*clearMem)(HcfPriKey *self); }; diff --git a/interfaces/innerkits/key/pub_key.h b/interfaces/innerkits/key/pub_key.h index 3ed35f2ac833714ab6037f8d6509de60d4ac4b37..16cf6e77be74d1784f2856dd70866b431d5dd9bd 100644 --- a/interfaces/innerkits/key/pub_key.h +++ b/interfaces/innerkits/key/pub_key.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -30,6 +30,8 @@ struct HcfPubKey { HcfResult (*getAsyKeySpecString)(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString); HcfResult (*getAsyKeySpecInt)(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt); + + HcfResult (*getEncodedDer)(const HcfPubKey *self, const char *format, HcfBlob *returnBlob); }; #endif diff --git a/plugin/BUILD.gn b/plugin/BUILD.gn index 20292e7dc73890e3e3b2174cbea138cda74db0d1..fd6d724ee016948f2edb575bbeb836c49dff2f2c 100644 --- a/plugin/BUILD.gn +++ b/plugin/BUILD.gn @@ -30,11 +30,7 @@ ohos_shared_library("crypto_openssl_plugin_lib") { innerapi_tags = [ "platformsdk_indirect" ] part_name = "crypto_framework" public_configs = [ ":plugin_config" ] - include_dirs = [ - "//commonlibrary/c_utils/base/include", - "//third_party/openssl/include/", - ] - include_dirs += plugin_inc_path + crypto_framwork_common_inc_path + include_dirs = plugin_inc_path + crypto_framwork_common_inc_path sources = plugin_files @@ -52,14 +48,12 @@ ohos_shared_library("crypto_openssl_plugin_lib") { "-Wall", ] - deps = [ - "//base/security/crypto_framework/common:crypto_plugin_common", - "//third_party/openssl:libcrypto_shared", - ] + deps = [ "//base/security/crypto_framework/common:crypto_plugin_common" ] external_deps = [ "c_utils:utils", "hilog:libhilog", + "openssl:libcrypto_shared", ] defines = [ "OPENSSL_SUPPRESS_DEPRECATED" ] } diff --git a/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index feeeb5831706dde5f1df46943129e0a093d2e4e8..cc01eec54c86c8892688cba295455dd1cef271c1 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -25,9 +25,15 @@ #include #include #include +#include +#include +#include #include #include +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -118,6 +124,7 @@ EVP_PKEY *Openssl_EVP_PKEY_new_raw_private_key(int type, ENGINE *e, const unsign int Openssl_EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len); int Openssl_EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, size_t *len); int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +int Openssl_EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); void Openssl_EVP_PKEY_free(EVP_PKEY *pkey); EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, const char *propquery); @@ -138,7 +145,11 @@ int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e); int Openssl_EVP_PKEY_base_id(EVP_PKEY *pkey); EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const char *name, const char *propquery); +int Openssl_EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, const unsigned char *sig, + size_t siglen); OSSL_PARAM Openssl_OSSL_PARAM_construct_utf8_string(const char *key, char *buf, size_t bsize); +OSSL_PARAM Openssl_OSSL_PARAM_construct_octet_string(const char *key, void *buf, size_t bsize); OSSL_PARAM Openssl_OSSL_PARAM_construct_end(void); OSSL_PARAM Openssl_OSSL_PARAM_construct_uint(const char *key, unsigned int *buf); OSSL_PARAM Openssl_OSSL_PARAM_construct_int(const char *key, int *buf); @@ -310,9 +321,56 @@ int Openssl_EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key); int Openssl_EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); struct dh_st *Openssl_EVP_PKEY_get1_DH(EVP_PKEY *pkey); int Openssl_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits); +int Openssl_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); int Openssl_DH_up_ref(DH *r); int Openssl_DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); int Openssl_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +EVP_KDF *Openssl_EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties); +EVP_KDF_CTX *Openssl_EVP_KDF_CTX_new(EVP_KDF *kdf); +void Openssl_EVP_KDF_free(EVP_KDF *kdf); +void Openssl_EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); +int Openssl_EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]); + +// SM2 ASN1 +typedef struct SM2_Ciphertext_st SM2_Ciphertext; +DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext) + +struct SM2_Ciphertext_st { + BIGNUM *C1x; + BIGNUM *C1y; + ASN1_OCTET_STRING *C3; + ASN1_OCTET_STRING *C2; +}; + +void Openssl_SM2_Ciphertext_free(struct SM2_Ciphertext_st *sm2Text); +struct SM2_Ciphertext_st *Openssl_d2i_SM2_Ciphertext(const uint8_t *ciphertext, size_t cipherTextLen); +void Openssl_ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *field); +ASN1_OCTET_STRING *Openssl_ASN1_OCTET_STRING_new(void); +int Openssl_ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len); +struct SM2_Ciphertext_st *Openssl_SM2_Ciphertext_new(void); +int Openssl_i2d_SM2_Ciphertext(struct SM2_Ciphertext_st *sm2Text, unsigned char **returnData); +int Openssl_ASN1_STRING_length(ASN1_OCTET_STRING *p); +const unsigned char *Openssl_ASN1_STRING_get0_data(ASN1_OCTET_STRING *p); + +size_t Openssl_EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); +OSSL_PARAM_BLD *Openssl_OSSL_PARAM_BLD_new(void); +void Openssl_OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld); +OSSL_PARAM *Openssl_OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld); +int Openssl_OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, const char *buf, size_t bsize); +int Openssl_OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, const void *buf, size_t bsize); +int Openssl_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); +int Openssl_EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM params[]); +EC_KEY *Openssl_EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +void Openssl_OSSL_PARAM_free(OSSL_PARAM *params); +int Openssl_EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, const unsigned char *buf, size_t len, BN_CTX *ctx); +int Openssl_EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); +int Openssl_EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); #ifdef __cplusplus } diff --git a/plugin/openssl_plugin/common/inc/openssl_common.h b/plugin/openssl_plugin/common/inc/openssl_common.h index 78c56655bfd6409cf47e28d726f365685621af47..63d9a09f572dad814089511d2905db65d8391ccd 100644 --- a/plugin/openssl_plugin/common/inc/openssl_common.h +++ b/plugin/openssl_plugin/common/inc/openssl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -42,6 +42,9 @@ extern "C" { #endif HcfResult GetCurveNameByCurveId(int32_t curveId, char **curveName); +HcfResult GetNidByCurveNameValue(int32_t curveNameValue, int32_t *nid); +HcfResult GetGroupNameByNid(int32_t nid, char **groupName); +HcfResult GetFormatTypeByFormatValue(int32_t formatValue, int32_t *formatType); HcfResult GetAlgNameByBits(int32_t keyLen, char **algName); HcfResult GetOpensslCurveId(int32_t keyLen, int32_t *returnCurveId); HcfResult GetOpensslDigestAlg(uint32_t alg, EVP_MD **digestAlg); diff --git a/plugin/openssl_plugin/common/src/ecc_openssl_common.c b/plugin/openssl_plugin/common/src/ecc_openssl_common.c index 5859b0c0217ac8a5c2a23cea5c7e76df29e31059..bf21d01ead73fa4bf5ab84e24387711d9994458a 100644 --- a/plugin/openssl_plugin/common/src/ecc_openssl_common.c +++ b/plugin/openssl_plugin/common/src/ecc_openssl_common.c @@ -159,6 +159,7 @@ HcfResult GenerateEcGroupWithParamsSpec(const HcfEccCommParamsSpec *ecParams, EC LOGD("[error] Set Ec point fail"); return ret; } + Openssl_BN_CTX_free(ctx); *ecGroup = group; return ret; } diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index b48c03e03c12b4cc5a2a009a7aaa0a3fef725c95..523b3b8d442f8c1b6bef98c303e85246d786b746 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -14,10 +14,19 @@ */ #include "openssl_adapter.h" - +#include #include "log.h" #include "result.h" +ASN1_SEQUENCE(SM2_Ciphertext) = { + ASN1_SIMPLE(SM2_Ciphertext, C1x, BIGNUM), + ASN1_SIMPLE(SM2_Ciphertext, C1y, BIGNUM), + ASN1_SIMPLE(SM2_Ciphertext, C3, ASN1_OCTET_STRING), + ASN1_SIMPLE(SM2_Ciphertext, C2, ASN1_OCTET_STRING), +} ASN1_SEQUENCE_END(SM2_Ciphertext) + +IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext) + BIGNUM *Openssl_BN_dup(const BIGNUM *a) { return BN_dup(a); @@ -420,6 +429,11 @@ int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) return EVP_PKEY_assign_EC_KEY(pkey, key); } +int Openssl_EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + return EVP_PKEY_set1_EC_KEY(pkey, key); +} + void Openssl_EVP_PKEY_free(EVP_PKEY *pkey) { if (pkey != NULL) { @@ -491,11 +505,27 @@ EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const cha return EVP_PKEY_CTX_new_from_name(libctx, name, propquery); } +int Openssl_EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_verify_recover_init(ctx); +} + +int Openssl_EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, unsigned char *rout, size_t *routlen, const unsigned char *sig, + size_t siglen) +{ + return EVP_PKEY_verify_recover(ctx, rout, routlen, sig, siglen); +} + OSSL_PARAM Openssl_OSSL_PARAM_construct_utf8_string(const char *key, char *buf, size_t bsize) { return OSSL_PARAM_construct_utf8_string(key, buf, bsize); } +OSSL_PARAM Openssl_OSSL_PARAM_construct_octet_string(const char *key, void *buf, size_t bsize) +{ + return OSSL_PARAM_construct_octet_string(key, buf, bsize); +} + OSSL_PARAM Openssl_OSSL_PARAM_construct_end(void) { return OSSL_PARAM_construct_end(); @@ -1279,6 +1309,11 @@ int Openssl_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, pbits); } +int Openssl_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_set_signature_md(ctx, md); +} + int Openssl_DH_up_ref(DH *r) { return DH_up_ref(r); @@ -1292,4 +1327,157 @@ int Openssl_DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) int Openssl_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { return DH_set0_key(dh, pub_key, priv_key); +} + +struct SM2_Ciphertext_st *Openssl_d2i_SM2_Ciphertext(const uint8_t *ciphertext, size_t ciphertext_len) +{ + return d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len); +} + +void Openssl_SM2_Ciphertext_free(struct SM2_Ciphertext_st *sm2Text) +{ + if (sm2Text != NULL) { + SM2_Ciphertext_free(sm2Text); + } +} + +void Openssl_ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *field) +{ + if (field != NULL) { + ASN1_OCTET_STRING_free(field); + } +} + +ASN1_OCTET_STRING *Openssl_ASN1_OCTET_STRING_new(void) +{ + return ASN1_OCTET_STRING_new(); +} + +int Openssl_ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len) +{ + return ASN1_STRING_set(x, d, len); +} + +struct SM2_Ciphertext_st *Openssl_SM2_Ciphertext_new(void) +{ + return SM2_Ciphertext_new(); +} + +int Openssl_i2d_SM2_Ciphertext(struct SM2_Ciphertext_st *sm2Text, unsigned char **returnData) +{ + return i2d_SM2_Ciphertext(sm2Text, returnData); +} + +int Openssl_ASN1_STRING_length(ASN1_OCTET_STRING *p) +{ + return ASN1_STRING_length(p); +} + +const unsigned char *Openssl_ASN1_STRING_get0_data(ASN1_OCTET_STRING *p) +{ + return ASN1_STRING_get0_data(p); +} + +size_t Openssl_EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + return EC_POINT_point2oct(group, p, form, buf, len, ctx); +} + +OSSL_PARAM_BLD *Openssl_OSSL_PARAM_BLD_new(void) +{ + return OSSL_PARAM_BLD_new(); +} + +void Openssl_OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld) +{ + if (bld != NULL) { + OSSL_PARAM_BLD_free(bld); + } +} + +OSSL_PARAM *Openssl_OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld) +{ + return OSSL_PARAM_BLD_to_param(bld); +} + +int Openssl_OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, const char *buf, size_t bsize) +{ + return OSSL_PARAM_BLD_push_utf8_string(bld, key, buf, bsize); +} + +int Openssl_OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, const void *buf, size_t bsize) +{ + return OSSL_PARAM_BLD_push_octet_string(bld, key, buf, bsize); +} + +int Openssl_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) +{ + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); +} + +int Openssl_EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx) +{ + return EVP_PKEY_fromdata_init(ctx); +} + +int Openssl_EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM params[]) +{ + return EVP_PKEY_fromdata(ctx, ppkey, selection, params); +} + +EC_KEY *Openssl_EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + return EVP_PKEY_get1_EC_KEY(pkey); +} + +void Openssl_OSSL_PARAM_free(OSSL_PARAM *params) +{ + if (params != NULL) { + OSSL_PARAM_free(params); + } +} + +int Openssl_EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + return EC_POINT_oct2point(group, p, buf, len, ctx); +} + +int Openssl_EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_set_affine_coordinates(group, p, x, y, ctx); +} + +int Openssl_EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) +{ + return EC_POINT_get_affine_coordinates(group, p, x, y, ctx); +} + +EVP_KDF *Openssl_EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, + const char *properties) +{ + return EVP_KDF_fetch(libctx, algorithm, properties); +} + +EVP_KDF_CTX *Openssl_EVP_KDF_CTX_new(EVP_KDF *kdf) +{ + return EVP_KDF_CTX_new(kdf); +} + +void Openssl_EVP_KDF_free(EVP_KDF *kdf) +{ + return EVP_KDF_free(kdf); +} + +void Openssl_EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) +{ + return EVP_KDF_CTX_free(ctx); +} + +int Openssl_EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) +{ + return EVP_KDF_derive(ctx, key, keylen, params); } \ No newline at end of file diff --git a/plugin/openssl_plugin/common/src/openssl_common.c b/plugin/openssl_plugin/common/src/openssl_common.c index 5a3459874891d338ccab5b35acdbee125cdea299..4e4bdd371402a635c1445c2668c408110f3e0656 100644 --- a/plugin/openssl_plugin/common/src/openssl_common.c +++ b/plugin/openssl_plugin/common/src/openssl_common.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -47,28 +47,29 @@ static const uint32_t ASCII_CODE_ZERO = 48; typedef struct { int32_t bits; // keyLen int32_t nid; // nid + char *groupName; } NidTypeAlg; static const NidTypeAlg NID_TYPE_MAP[] = { - { HCF_ALG_ECC_224, NID_secp224r1 }, - { HCF_ALG_ECC_256, NID_X9_62_prime256v1 }, - { HCF_ALG_ECC_384, NID_secp384r1 }, - { HCF_ALG_ECC_521, NID_secp521r1 }, - { HCF_ALG_SM2_256, NID_sm2 }, - { HCF_ALG_ECC_BP160R1, NID_brainpoolP160r1 }, - { HCF_ALG_ECC_BP160T1, NID_brainpoolP160t1 }, - { HCF_ALG_ECC_BP192R1, NID_brainpoolP192r1 }, - { HCF_ALG_ECC_BP192T1, NID_brainpoolP192t1 }, - { HCF_ALG_ECC_BP224R1, NID_brainpoolP224r1 }, - { HCF_ALG_ECC_BP224T1, NID_brainpoolP224t1 }, - { HCF_ALG_ECC_BP256R1, NID_brainpoolP256r1 }, - { HCF_ALG_ECC_BP256T1, NID_brainpoolP256t1 }, - { HCF_ALG_ECC_BP320R1, NID_brainpoolP320r1 }, - { HCF_ALG_ECC_BP320T1, NID_brainpoolP320t1 }, - { HCF_ALG_ECC_BP384R1, NID_brainpoolP384r1 }, - { HCF_ALG_ECC_BP384T1, NID_brainpoolP384t1 }, - { HCF_ALG_ECC_BP512R1, NID_brainpoolP512r1 }, - { HCF_ALG_ECC_BP512T1, NID_brainpoolP512t1 }, + { HCF_ALG_ECC_224, NID_secp224r1, "secp224r1" }, + { HCF_ALG_ECC_256, NID_X9_62_prime256v1, "prime256v1" }, + { HCF_ALG_ECC_384, NID_secp384r1, "secp384r1" }, + { HCF_ALG_ECC_521, NID_secp521r1, "secp521r1" }, + { HCF_ALG_SM2_256, NID_sm2, "sm2" }, + { HCF_ALG_ECC_BP160R1, NID_brainpoolP160r1, "brainpoolP160r1" }, + { HCF_ALG_ECC_BP160T1, NID_brainpoolP160t1, "brainpoolP160t1" }, + { HCF_ALG_ECC_BP192R1, NID_brainpoolP192r1, "brainpoolP192r1" }, + { HCF_ALG_ECC_BP192T1, NID_brainpoolP192t1, "brainpoolP192t1" }, + { HCF_ALG_ECC_BP224R1, NID_brainpoolP224r1, "brainpoolP224r1" }, + { HCF_ALG_ECC_BP224T1, NID_brainpoolP224t1, "brainpoolP224t1" }, + { HCF_ALG_ECC_BP256R1, NID_brainpoolP256r1, "brainpoolP256r1" }, + { HCF_ALG_ECC_BP256T1, NID_brainpoolP256t1, "brainpoolP256t1" }, + { HCF_ALG_ECC_BP320R1, NID_brainpoolP320r1, "brainpoolP320r1" }, + { HCF_ALG_ECC_BP320T1, NID_brainpoolP320t1, "brainpoolP320t1" }, + { HCF_ALG_ECC_BP384R1, NID_brainpoolP384r1, "brainpoolP384r1" }, + { HCF_ALG_ECC_BP384T1, NID_brainpoolP384t1, "brainpoolP384t1" }, + { HCF_ALG_ECC_BP512R1, NID_brainpoolP512r1, "brainpoolP512r1" }, + { HCF_ALG_ECC_BP512T1, NID_brainpoolP512t1, "brainpoolP512t1" }, }; typedef struct { @@ -124,6 +125,16 @@ static const AlgNameType ALG_NAME_TYPE_MAP[] = { { HCF_ALG_ECC_BP512T1, "ECC" } }; +typedef struct { + int32_t formatValue; + int32_t formatType; +} FormatType; + +static const FormatType FORMAT_TYPE_MAP[] = { + { HCF_UNCOMPRESSED_FORMAT_VALUE, POINT_CONVERSION_UNCOMPRESSED }, + { HCF_COMPRESSED_FORMAT_VALUE, POINT_CONVERSION_COMPRESSED } +}; + HcfResult GetCurveNameByCurveId(int32_t curveId, char **curveName) { if (curveName == NULL) { @@ -136,7 +147,55 @@ HcfResult GetCurveNameByCurveId(int32_t curveId, char **curveName) return HCF_SUCCESS; } } - LOGD("[error] Invalid curve id:%d", curveId); + LOGE("Invalid curve id:%d", curveId); + return HCF_INVALID_PARAMS; +} + +HcfResult GetNidByCurveNameValue(int32_t curveNameValue, int32_t *nid) +{ + if (nid == NULL) { + LOGE("Invalid nid"); + return HCF_INVALID_PARAMS; + } + for (uint32_t i = 0; i < sizeof(NID_TYPE_MAP) / sizeof(NID_TYPE_MAP[0]); i++) { + if (NID_TYPE_MAP[i].bits == curveNameValue) { + *nid = NID_TYPE_MAP[i].nid; + return HCF_SUCCESS; + } + } + LOGE("Invalid curveNameValue value: %d", curveNameValue); + return HCF_INVALID_PARAMS; +} + +HcfResult GetGroupNameByNid(int32_t nid, char **groupName) +{ + if (groupName == NULL) { + LOGE("Invalid groupName"); + return HCF_INVALID_PARAMS; + } + for (uint32_t i = 0; i < sizeof(NID_TYPE_MAP) / sizeof(NID_TYPE_MAP[0]); i++) { + if (NID_TYPE_MAP[i].nid == nid) { + *groupName = NID_TYPE_MAP[i].groupName; + return HCF_SUCCESS; + } + } + LOGE("Invalid nid:%d", nid); + return HCF_INVALID_PARAMS; +} + +HcfResult GetFormatTypeByFormatValue(int32_t formatValue, int32_t *formatType) +{ + if (formatType == NULL) { + LOGE("Invalid formatType"); + return HCF_INVALID_PARAMS; + } + for (uint32_t i = 0; i < sizeof(FORMAT_TYPE_MAP) / sizeof(FORMAT_TYPE_MAP[0]); i++) { + if (FORMAT_TYPE_MAP[i].formatValue == formatValue) { + *formatType = FORMAT_TYPE_MAP[i].formatType; + return HCF_SUCCESS; + } + } + LOGE("Invalid format value: %d", formatValue); return HCF_INVALID_PARAMS; } diff --git a/common/src/log.c b/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_crypto_util_openssl.h similarity index 34% rename from common/src/log.c rename to plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_crypto_util_openssl.h index 96b2139d3c338d5a7171fe024989c515494212c8..1884a53dd161b2568913761a17bfd80ae5993434 100644 --- a/common/src/log.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/inc/cipher_sm2_crypto_util_openssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,47 +13,20 @@ * limitations under the License. */ -#include "log.h" +#ifndef HCF_CIPHER_SM2_CRYPTO_UTIL_OPENSSL_H +#define HCF_CIPHER_SM2_CRYPTO_UTIL_OPENSSL_H -#include -#include "config.h" -#include "securec.h" +#include "sm2_crypto_params.h" +#include "result.h" -static void HcfOutPrint(const char *buf, HcfLogLevel level) -{ - switch (level) { - case HCF_LOG_LEVEL_DEBUG: - HCF_LOG_DEBUG(buf); - break; - case HCF_LOG_LEVEL_INFO: - HCF_LOG_INFO(buf); - break; - case HCF_LOG_LEVEL_WARN: - HCF_LOG_WARN(buf); - break; - case HCF_LOG_LEVEL_ERROR: - HCF_LOG_ERROR(buf); - break; - default: - break; - } -} +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfSm2SpecToAsn1(Sm2CipherTextSpec *spec, HcfBlob *output); +HcfResult HcfAsn1ToSm2Spec(HcfBlob *input, Sm2CipherTextSpec **returnSpec); -void HcfLogPrint(HcfLogLevel level, const char *funName, const char *fmt, ...) -{ - int32_t ulPos = 0; - char outStr[LOG_PRINT_MAX_LEN] = {0}; - int32_t ret = sprintf_s(outStr, sizeof(outStr), "%s: ", funName); - if (ret < 0) { - return; - } - ulPos = strlen(outStr); - va_list arg; - va_start(arg, fmt); - ret = vsprintf_s(&outStr[ulPos], sizeof(outStr) - ulPos, fmt, arg); - va_end(arg); - if (ret < 0) { - return; - } - HcfOutPrint(outStr, level); +#ifdef __cplusplus } +#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c index 504b76faac79d83a17c44e12f7de594bc38c3015..80f8348f2b06e40b8ac66270b70f49460ccac5ae 100644 --- a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_aes_openssl.c @@ -528,7 +528,7 @@ static HcfResult AeadUpdate(CipherData *data, HcfAlgParaValue mode, HcfBlob *inp static HcfResult AllocateOutput(HcfBlob *input, HcfBlob *output, bool *isUpdateInput) { - uint32_t outLen = AES_BLOCK_SIZE; + uint32_t outLen = AES_BLOCK_SIZE + AES_BLOCK_SIZE; if (IsBlobValid(input)) { outLen += input->len; *isUpdateInput = true; diff --git a/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_crypto_util_openssl.c b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_crypto_util_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..4db0ff808df2012ebc364310f6611a78cc3d309e --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_crypto_util_openssl.c @@ -0,0 +1,147 @@ +/* + * 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 "cipher_sm2_crypto_util_openssl.h" +#include +#include +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_common.h" +#include "securec.h" +#include "utils.h" + +static HcfResult BuildSm2Ciphertext(const Sm2CipherTextSpec *spec, struct SM2_Ciphertext_st *sm2Text) +{ + if (BigIntegerToBigNum(&(spec->xCoordinate), &(sm2Text->C1x)) != HCF_SUCCESS) { + LOGE("Build x failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(spec->yCoordinate), &(sm2Text->C1y)) != HCF_SUCCESS) { + LOGE("Build y failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + sm2Text->C3 = Openssl_ASN1_OCTET_STRING_new(); + sm2Text->C2 = Openssl_ASN1_OCTET_STRING_new(); + if (sm2Text->C3 == NULL || sm2Text->C2 == NULL) { + LOGE("SM2 openssl [ASN1_OCTET_STRING_new] C3 C2 fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_ASN1_OCTET_STRING_set(sm2Text->C3, spec->hashData.data, spec->hashData.len) != HCF_OPENSSL_SUCCESS) { + LOGE("SM2 openssl [ASN1_OCTET_STRING_set] C3 error"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_ASN1_OCTET_STRING_set(sm2Text->C2, spec->cipherTextData.data, + spec->cipherTextData.len) != HCF_OPENSSL_SUCCESS) { + LOGE("SM2 openssl [ASN1_OCTET_STRING_set] C2 error"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +HcfResult HcfSm2SpecToAsn1(Sm2CipherTextSpec *spec, HcfBlob *output) +{ + struct SM2_Ciphertext_st *sm2Text = Openssl_SM2_Ciphertext_new(); + if (sm2Text == NULL) { + LOGE("SM2 openssl [SM2_Ciphertext_new] failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult res = BuildSm2Ciphertext(spec, sm2Text); + if (res != HCF_SUCCESS) { + Openssl_SM2_Ciphertext_free(sm2Text); + LOGE("SM2 build SM2Ciphertext fail"); + return res; + } + unsigned char *returnData = NULL; + int returnDataLen = Openssl_i2d_SM2_Ciphertext(sm2Text, &returnData); + Openssl_SM2_Ciphertext_free(sm2Text); + if (returnData == NULL || returnDataLen < 0) { + LOGE("SM2 openssl [i2d_SM2_Ciphertext] error"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + output->data = returnData; + output->len = (size_t)returnDataLen; + return HCF_SUCCESS; +} + +static HcfResult BuildSm2CiphertextSpec(struct SM2_Ciphertext_st *sm2Text, Sm2CipherTextSpec *tempSpec) +{ + if (BigNumToBigInteger(sm2Text->C1x, &(tempSpec->xCoordinate)) != HCF_SUCCESS) { + LOGE("BigNumToBigInteger xCoordinate failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigNumToBigInteger(sm2Text->C1y, &(tempSpec->yCoordinate)) != HCF_SUCCESS) { + LOGE("BigNumToBigInteger yCoordinate failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + const unsigned char *c2Data = Openssl_ASN1_STRING_get0_data(sm2Text->C2); + int c2Len = Openssl_ASN1_STRING_length(sm2Text->C2); + if (c2Data == NULL || c2Len <= 0) { + LOGE("SM2 openssl [Openssl_ASN1_STRING_get0_data] error."); + return HCF_ERR_CRYPTO_OPERATION; + } + const unsigned char *c3Data = Openssl_ASN1_STRING_get0_data(sm2Text->C3); + int c3Len = Openssl_ASN1_STRING_length(sm2Text->C3); + if (c3Data == NULL || c3Len <= 0) { + LOGE("SM2 openssl [Openssl_ASN1_STRING_get0_data] error."); + return HCF_ERR_CRYPTO_OPERATION; + } + + tempSpec->cipherTextData.data = (unsigned char *)HcfMalloc(c2Len, 0); + if (tempSpec->cipherTextData.data == NULL) { + LOGE("Failed to allocate cipherTextData.data memory"); + return HCF_ERR_MALLOC; + } + tempSpec->hashData.data = (unsigned char *)HcfMalloc(c3Len, 0); + if (tempSpec->hashData.data == NULL) { + LOGE("Failed to allocate hashData.data memory"); + return HCF_ERR_MALLOC; + } + (void)memcpy_s(tempSpec->cipherTextData.data, c2Len, c2Data, c2Len); + (void)memcpy_s(tempSpec->hashData.data, c3Len, c3Data, c3Len); + tempSpec->cipherTextData.len = c2Len; + tempSpec->hashData.len = c3Len; + return HCF_SUCCESS; +} + +HcfResult HcfAsn1ToSm2Spec(HcfBlob *input, Sm2CipherTextSpec **returnSpec) +{ + struct SM2_Ciphertext_st *sm2Text = Openssl_d2i_SM2_Ciphertext(input->data, input->len); + if (sm2Text == NULL) { + LOGE("SM2 openssl [d2i_SM2_Ciphertext] error"); + return HCF_ERR_CRYPTO_OPERATION; + } + Sm2CipherTextSpec *tempSpec = (Sm2CipherTextSpec *)(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == NULL) { + LOGE("Failed to allocate Sm2CipherTextSpec memory"); + Openssl_SM2_Ciphertext_free(sm2Text); + return HCF_ERR_MALLOC; + } + HcfResult res = BuildSm2CiphertextSpec(sm2Text, tempSpec); + if (res != HCF_SUCCESS) { + LOGE("SM2 build SM2Ciphertext fail"); + DestroySm2CipherTextSpec(tempSpec); + Openssl_SM2_Ciphertext_free(sm2Text); + return res; + } + *returnSpec = tempSpec; + Openssl_SM2_Ciphertext_free(sm2Text); + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c index fcf10b5f87787da2777a5c50b055df85c05baa8b..e288dde56e36232e8489b4db4c36f9af8d344ec2 100644 --- a/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/hmac/src/mac_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -60,6 +60,8 @@ static const EVP_MD *OpensslGetMacAlgoFromString(const char *mdName) return Openssl_EVP_sha512(); } else if (strcmp(mdName, "SM3") == 0) { return Openssl_EVP_sm3(); + } else if (strcmp(mdName, "MD5") == 0) { + return Openssl_EVP_md5(); } return NULL; } diff --git a/plugin/openssl_plugin/crypto_operation/kdf/inc/hkdf_openssl.h b/plugin/openssl_plugin/crypto_operation/kdf/inc/hkdf_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..edc5d5238650c7a3d6f7374a8ed1f35f7ecc5b4c --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/inc/hkdf_openssl.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef HCF_HKDF_OPENSSL_H +#define HCF_HKDF_OPENSSL_H + +#include "kdf_spi.h" +#include "params_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif +HcfResult HcfKdfHkdfSpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c b/plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..ebba02e68868e618136445a0fc69c6406b114257 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c @@ -0,0 +1,328 @@ +/* + * 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 "hkdf_openssl.h" + +#include "log.h" +#include "memory.h" +#include "result.h" +#include "securec.h" +#include "utils.h" +#include "openssl_adapter.h" +#include "openssl_common.h" +#include "openssl/kdf.h" +#include "detailed_hkdf_params.h" + +#define HKDF_ALG_NAME "HKDF" + +typedef struct { + unsigned char *salt; + int saltLen; + unsigned char *key; + int keyLen; + unsigned char *info; + int infoLen; + unsigned char *out; + int outLen; +} HcfHkdfData; + +typedef struct { + HcfKdfSpi base; + int digestAlg; + int mode; + HcfHkdfData *kdfData; +} OpensslHkdfSpiImpl; + +static const char *EngineGetKdfClass(void) +{ + return "OpensslHkdf"; +} + +static void HcfClearAndFree(unsigned char *buf, int bufLen) +{ + // when buf == null, bufLen must be 0; in check func, bufLen >= 0 + if (buf == NULL) { + return; + } + (void)memset_s(buf, bufLen, 0, bufLen); + HcfFree(buf); +} + +static void FreeHkdfData(HcfHkdfData **data) +{ + if (data == NULL || *data == NULL) { + return; + } + HcfClearAndFree((*data)->out, (*data)->outLen); + HcfClearAndFree((*data)->salt, (*data)->saltLen); + HcfClearAndFree((*data)->info, (*data)->infoLen); + HcfClearAndFree((*data)->key, (*data)->keyLen); + (void)memset_s(*data, sizeof(HcfHkdfData), 0, sizeof(HcfHkdfData)); + HcfFree(*data); + *data = NULL; +} + +static void EngineDestroyKdf(HcfObjectBase *self) +{ + if (self == NULL) { + LOGE("Self ptr is NULL!"); + return; + } + if (!IsClassMatch(self, EngineGetKdfClass())) { + LOGE("Class is not match."); + return; + } + OpensslHkdfSpiImpl *impl = (OpensslHkdfSpiImpl *)self; + FreeHkdfData(&(impl->kdfData)); + HcfFree(self); +} + +static bool CheckHkdfParams(HcfHkdfParamsSpec *params) +{ + // openssl only support INT and blob attribute is size_t, it should samller than INT_MAX. + if (params->output.len > INT_MAX || params->salt.len > INT_MAX || params->key.len > INT_MAX || + params->info.len > INT_MAX) { + LOGE("beyond the length"); + return false; + } + if (params->key.data == NULL && params->key.len == 0) { + LOGE("check params failed, key is NULL"); + return false; + } + if (params->output.data == NULL || params->output.len == 0) { + LOGE("check params failed, output data is NULL"); + return false; + } + if (params->salt.data == NULL && params->salt.len == 0) { + LOGD("empty salt"); + } + if (params->info.data == NULL && params->info.len == 0) { + LOGD("empty info"); + } + return true; +} + +static bool GetHkdfKeyFromSpec(HcfHkdfData *data, HcfHkdfParamsSpec *params) +{ + data->key = (unsigned char *)HcfMalloc(params->key.len, 0); + if (data->key == NULL) { + return false; + } + (void)memcpy_s(data->key, params->key.len, params->key.data, params->key.len); + data->keyLen = params->key.len; + return true; +} + +static int GetHkdfMode(OpensslHkdfSpiImpl *self) +{ + switch (self->mode) { + case HCF_ALG_MODE_EXTRACT_AND_EXPAND: + return EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; + case HCF_ALG_MODE_EXTRACT_ONLY: + return EVP_KDF_HKDF_MODE_EXTRACT_ONLY; + case HCF_ALG_MODE_EXPAND_ONLY: + return EVP_KDF_HKDF_MODE_EXPAND_ONLY; + default: + return EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; + } +} + +static bool GetHkdfInfoFromSpec(OpensslHkdfSpiImpl *self, HcfHkdfData *data, HcfHkdfParamsSpec *params) +{ + if (self->mode == HCF_ALG_MODE_EXTRACT_ONLY) { + LOGD("EXTRACT_ONLY mode does not require info"); + return true; + } + + if (params->info.len == 0) { + LOGD("info can be empty."); + return true; + } + + data->info = (unsigned char *)HcfMalloc(params->info.len, 0); + if (data->info == NULL) { + return false; + } + (void)memcpy_s(data->info, params->info.len, params->info.data, params->info.len); + data->infoLen = params->info.len; + return true; +} + +static bool GetHkdfSaltFromSpec(OpensslHkdfSpiImpl *self, HcfHkdfData *data, HcfHkdfParamsSpec *params) +{ + if (self->mode == HCF_ALG_MODE_EXPAND_ONLY) { + LOGD("EXPAND_ONLY mode does not require salt"); + return true; + } + + if (params->salt.len == 0) { + LOGD("salt can be empty."); + return true; + } + + data->salt = (unsigned char *)HcfMalloc(params->salt.len, 0); + if (data->salt == NULL) { + return false; + } + (void)memcpy_s(data->salt, params->salt.len, params->salt.data, params->salt.len); + data->saltLen = params->salt.len; + return true; +} + +static HcfResult InitHkdfData(OpensslHkdfSpiImpl *self, HcfHkdfParamsSpec *params) +{ + LOGD("MODE IS %d", self->mode); + HcfHkdfData *data = (HcfHkdfData *)HcfMalloc(sizeof(HcfHkdfData), 0); + do { + if (data == NULL) { + LOGE("malloc data failed"); + break; + } + if (!GetHkdfKeyFromSpec(data, params)) { + LOGE("malloc key failed!"); + break; + } + if (!GetHkdfSaltFromSpec(self, data, params)) { + LOGE("malloc salt failed!"); + break; + } + if (!GetHkdfInfoFromSpec(self, data, params)) { + LOGE("malloc info failed!"); + break; + } + data->out = (unsigned char *)HcfMalloc(params->output.len, 0); + if (data->out == NULL) { + LOGE("malloc out failed!"); + break; + } + data->outLen = params->output.len; + self->kdfData = data; + return HCF_SUCCESS; + } while (0); + FreeHkdfData(&data); + return HCF_ERR_MALLOC; +} + +static char *SwitchMd(OpensslHkdfSpiImpl *self) +{ + switch (self->digestAlg) { + case HCF_OPENSSL_DIGEST_NONE: + return ""; + case HCF_OPENSSL_DIGEST_MD5: + return "MD5"; + case HCF_OPENSSL_DIGEST_SM3: + return "SM3"; + case HCF_OPENSSL_DIGEST_SHA1: + return "SHA1"; + case HCF_OPENSSL_DIGEST_SHA224: + return "SHA224"; + case HCF_OPENSSL_DIGEST_SHA256: + return "SHA256"; + case HCF_OPENSSL_DIGEST_SHA384: + return "SHA384"; + case HCF_OPENSSL_DIGEST_SHA512: + return "SHA512"; + default: + return ""; + } +} + +static HcfResult OpensslHkdf(OpensslHkdfSpiImpl *self, HcfBlob *output) +{ + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *kctx = NULL; + // need set 6 params + OSSL_PARAM params[6] = {}; + OSSL_PARAM *p = params; + + kdf = Openssl_EVP_KDF_fetch(NULL, "HKDF", NULL); + if (kdf == NULL) { + LOGE("kdf fetch failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + kctx = Openssl_EVP_KDF_CTX_new(kdf); + Openssl_EVP_KDF_free(kdf); + if (kctx == NULL) { + LOGE("kdf ctx new failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + int mode = GetHkdfMode(self); + char *digest = SwitchMd(self); + *p++ = Openssl_OSSL_PARAM_construct_utf8_string("digest", digest, 0); + *p++ = Openssl_OSSL_PARAM_construct_octet_string("key", self->kdfData->key, self->kdfData->keyLen); + *p++ = Openssl_OSSL_PARAM_construct_octet_string("info", self->kdfData->info, self->kdfData->infoLen); + *p++ = Openssl_OSSL_PARAM_construct_octet_string("salt", self->kdfData->salt, self->kdfData->saltLen); + *p++ = Openssl_OSSL_PARAM_construct_int("mode", &mode); + *p = Openssl_OSSL_PARAM_construct_end(); + if (Openssl_EVP_KDF_derive(kctx, output->data, output->len, params) <= 0) { + HcfPrintOpensslError(); + LOGE("EVP_KDF_derive failed"); + Openssl_EVP_KDF_CTX_free(kctx); + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_KDF_CTX_free(kctx); + return HCF_SUCCESS; +} + +static HcfResult EngineGenerateSecret(HcfKdfSpi *self, HcfKdfParamsSpec *paramsSpec) +{ + if (self == NULL || paramsSpec == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, EngineGetKdfClass())) { + return HCF_INVALID_PARAMS; + } + OpensslHkdfSpiImpl *hkdfImpl = (OpensslHkdfSpiImpl *)self; + if (paramsSpec->algName == NULL || strcmp(paramsSpec->algName, HKDF_ALG_NAME) != 0) { + LOGE("Not hkdf paramsSpec"); + return HCF_INVALID_PARAMS; + } + HcfHkdfParamsSpec *params = (HcfHkdfParamsSpec *)paramsSpec; + if (!CheckHkdfParams(params)) { + LOGE("params error"); + return HCF_INVALID_PARAMS; + } + HcfResult res = InitHkdfData(hkdfImpl, params); + if (res != HCF_SUCCESS) { + LOGE("InitCipherData failed!"); + return res; + } + res = OpensslHkdf(hkdfImpl, ¶ms->output); + FreeHkdfData(&(hkdfImpl->kdfData)); + return res; +} + +HcfResult HcfKdfHkdfSpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj) +{ + if (params == NULL || spiObj == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + OpensslHkdfSpiImpl *returnSpiImpl = (OpensslHkdfSpiImpl *)HcfMalloc(sizeof(OpensslHkdfSpiImpl), 0); + if (returnSpiImpl == NULL) { + LOGE("Failed to allocate returnImpl memory!"); + return HCF_ERR_MALLOC; + } + returnSpiImpl->base.base.getClass = EngineGetKdfClass; + returnSpiImpl->base.base.destroy = EngineDestroyKdf; + returnSpiImpl->base.generateSecret = EngineGenerateSecret; + returnSpiImpl->digestAlg = params->md; + returnSpiImpl->mode = params->mode; + *spiObj = (HcfKdfSpi *)returnSpiImpl; + return HCF_SUCCESS; +} diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c index cfe10154c3662a0fb7085b77e68cf5e3f3905cb1..223b751bb8b858a7bbe141b37268c94b46e9ee72 100644 --- a/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c +++ b/plugin/openssl_plugin/crypto_operation/signature/src/signature_rsa_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -49,8 +49,12 @@ typedef struct { CryptoStatus initFlag; int32_t saltLen; + + int32_t operation; } HcfSignSpiRsaOpensslImpl; +#define RSA_DIGEST_VERIFY 0 +#define RSA_VERIFY_RECOVER 1 typedef struct { HcfVerifySpi base; @@ -67,6 +71,8 @@ typedef struct { CryptoStatus initFlag; int32_t saltLen; + + int32_t operation; } HcfVerifySpiRsaOpensslImpl; static const char *GetRsaSignClass(void) @@ -111,6 +117,10 @@ static void DestroyRsaVerify(HcfObjectBase *self) HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; Openssl_EVP_MD_CTX_free(impl->mdctx); impl->mdctx = NULL; + if (impl->operation == RSA_VERIFY_RECOVER) { + Openssl_EVP_PKEY_CTX_free(impl->ctx); + impl->ctx = NULL; + } HcfFree(impl); impl = NULL; LOGD("DestroyRsaVerify success."); @@ -184,9 +194,54 @@ static HcfResult SetPaddingAndDigest(EVP_PKEY_CTX *ctx, int32_t hcfPadding, int3 return HCF_SUCCESS; } +static HcfResult SetOnlySignParams(HcfSignSpiRsaOpensslImpl *impl, HcfPriKey *privateKey) +{ + EVP_PKEY *dupKey = InitRsaEvpKey((HcfKey *)privateKey, true); + if (dupKey == NULL) { + LOGD("InitRsaEvpKey fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + EVP_PKEY_CTX *ctx = NULL; + EVP_MD *opensslAlg = NULL; + (void)GetOpensslDigestAlg(impl->md, &opensslAlg); + ctx = Openssl_EVP_PKEY_CTX_new_from_pkey(NULL, dupKey, NULL); + if (ctx == NULL) { + LOGD("Openssl_EVP_PKEY_CTX_new fail."); + Openssl_EVP_PKEY_free(dupKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_sign_init(ctx) != HCF_OPENSSL_SUCCESS) { + LOGD("Openssl_EVP_PKEY_sign_init fail."); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + if (opensslAlg != NULL) { + if (Openssl_EVP_PKEY_CTX_set_signature_md(ctx, opensslAlg) != HCF_OPENSSL_SUCCESS) { + LOGD("Openssl_EVP_PKEY_CTX_set_signature_md fail."); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + } + int32_t opensslPadding = 0; + (void)GetOpensslPadding(impl->padding, &opensslPadding); + if (Openssl_EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { + LOGD("Openssl_EVP_PKEY_CTX_set_rsa_padding fail"); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->ctx = ctx; + Openssl_EVP_PKEY_free(dupKey); + return HCF_SUCCESS; +} static HcfResult SetSignParams(HcfSignSpiRsaOpensslImpl *impl, HcfPriKey *privateKey) { + if (impl->operation == HCF_OPERATIOPN_ONLY_SIGN) { + return SetOnlySignParams(impl, privateKey); + } EVP_PKEY *dupKey = InitRsaEvpKey((HcfKey *)privateKey, true); if (dupKey == NULL) { LOGD("[error] InitRsaEvpKey fail."); @@ -284,6 +339,58 @@ static HcfResult SetVerifyParams(HcfVerifySpiRsaOpensslImpl *impl, HcfPubKey *pu return HCF_SUCCESS; } +static HcfResult SetVerifyRecoverParams(HcfVerifySpiRsaOpensslImpl *impl, HcfPubKey *publicKey) +{ + EVP_PKEY *dupKey = InitRsaEvpKey((HcfKey *)publicKey, false); + if (dupKey == NULL) { + LOGD("[error] InitRsaEvpKey fail."); + return HCF_ERR_CRYPTO_OPERATION; + } + + EVP_PKEY_CTX *ctx = NULL; + ctx = Openssl_EVP_PKEY_CTX_new_from_pkey(NULL, dupKey, NULL); + if (ctx == NULL) { + LOGD("[error] Openssl_EVP_PKEY_CTX_new_from_pkey fail."); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(dupKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_EVP_PKEY_verify_recover_init(ctx) != HCF_OPENSSL_SUCCESS) { + LOGD("[error] Openssl_EVP_PKEY_verify_recover_init fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + + int32_t opensslPadding = 0; + (void)GetOpensslPadding(impl->padding, &opensslPadding); + if (Openssl_EVP_PKEY_CTX_set_rsa_padding(ctx, opensslPadding) != HCF_OPENSSL_SUCCESS) { + LOGD("[error] Openssl_EVP_PKEY_CTX_set_rsa_padding fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + + EVP_MD *opensslAlg = NULL; + (void)GetOpensslDigestAlg(impl->md, &opensslAlg); + if (opensslAlg != NULL) { + if (Openssl_EVP_PKEY_CTX_set_signature_md(ctx, opensslAlg) != HCF_OPENSSL_SUCCESS) { + LOGD("[error] EVP_PKEY_CTX_set_rsa_mgf1_md fail"); + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(dupKey); + Openssl_EVP_PKEY_CTX_free(ctx); + return HCF_ERR_CRYPTO_OPERATION; + } + } + + impl->ctx = ctx; + Openssl_EVP_PKEY_free(dupKey); + return HCF_SUCCESS; +} + static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) { (void)params; @@ -304,10 +411,19 @@ static HcfResult EngineVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, Hcf LOGE("KeyType dismatch."); return HCF_INVALID_PARAMS; } - if (SetVerifyParams(impl, publicKey) != HCF_SUCCESS) { - LOGD("[error] Verify set padding or md fail"); - return HCF_ERR_CRYPTO_OPERATION; + + if (impl->operation == RSA_DIGEST_VERIFY) { + if (SetVerifyParams(impl, publicKey) != HCF_SUCCESS) { + LOGD("[error] Verify set padding or md fail"); + return HCF_ERR_CRYPTO_OPERATION; + } + } else { + if (SetVerifyRecoverParams(impl, publicKey) != HCF_SUCCESS) { + LOGD("[error] VerifyRecover set padding or md fail"); + return HCF_ERR_CRYPTO_OPERATION; + } } + impl->initFlag = INITIALIZED; return HCF_SUCCESS; } @@ -327,6 +443,10 @@ static HcfResult EngineSignUpdate(HcfSignSpi *self, HcfBlob *data) LOGE("The Sign has not been init"); return HCF_INVALID_PARAMS; } + if (impl->operation == HCF_OPERATIOPN_ONLY_SIGN) { + LOGE("Update cannot support in OnlySign"); + return HCF_INVALID_PARAMS; + } if (Openssl_EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { LOGD("[error] Openssl_EVP_DigestSignUpdate fail"); return HCF_ERR_CRYPTO_OPERATION; @@ -349,6 +469,12 @@ static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) LOGE("The Sign has not been init"); return HCF_INVALID_PARAMS; } + + if (impl->operation != RSA_DIGEST_VERIFY) { + LOGE("Invalid digest verify operation."); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { LOGD("[error] Openssl_EVP_DigestSignUpdate fail"); return HCF_ERR_CRYPTO_OPERATION; @@ -356,33 +482,49 @@ static HcfResult EngineVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) return HCF_SUCCESS; } -static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +static HcfResult EnginePkeySign(HcfSignSpiRsaOpensslImpl *impl, HcfBlob *data, HcfBlob *returnSignatureData) { - if (self == NULL || returnSignatureData == NULL) { + if (data == NULL || data->len == 0 || data->data == NULL) { LOGE("Invalid input params."); return HCF_INVALID_PARAMS; } - if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_SIGN_CLASS)) { - LOGE("Class not match."); - return HCF_INVALID_PARAMS; + size_t maxLen; + if (Openssl_EVP_PKEY_sign(impl->ctx, NULL, &maxLen, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_PKEY_sign get maxLen fail"); + return HCF_ERR_CRYPTO_OPERATION; } - HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; - if (impl->initFlag != INITIALIZED) { - LOGE("The Sign has not been init"); - return HCF_INVALID_PARAMS; + LOGD("sign maxLen is %zu", maxLen); + uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0); + if (outData == NULL) { + LOGE("Failed to allocate outData memory!"); + return HCF_ERR_MALLOC; } + size_t actualLen = maxLen; + if (Openssl_EVP_PKEY_sign(impl->ctx, outData, &actualLen, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl_EVP_PKEY_sign fail"); + HcfFree(outData); + return HCF_ERR_CRYPTO_OPERATION; + } + returnSignatureData->data = outData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static HcfResult EngineDigestSign(HcfSignSpiRsaOpensslImpl *impl, HcfBlob *data, HcfBlob *returnSignatureData) +{ if (data != NULL && data->data != NULL) { if (Openssl_EVP_DigestSignUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { LOGD("[error] Dofinal update data fail."); return HCF_ERR_CRYPTO_OPERATION; } } + size_t maxLen; if (Openssl_EVP_DigestSignFinal(impl->mdctx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { LOGD("[error] Openssl_EVP_DigestSignFinal fail"); return HCF_ERR_CRYPTO_OPERATION; } - LOGD("sign maxLen is %d", maxLen); + LOGD("sign maxLen is %zu", maxLen); uint8_t *outData = (uint8_t *)HcfMalloc(maxLen, 0); if (outData == NULL) { LOGE("Failed to allocate outData memory!"); @@ -400,13 +542,37 @@ static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSign HcfFree(outData); return HCF_ERR_CRYPTO_OPERATION; } - returnSignatureData->data = outData; returnSignatureData->len = (uint32_t)actualLen; - return HCF_SUCCESS; } +static HcfResult EngineSign(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if (self == NULL || returnSignatureData == NULL) { + LOGE("Invalid input params."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_SIGN_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfSignSpiRsaOpensslImpl *impl = (HcfSignSpiRsaOpensslImpl *)self; + if (impl->initFlag != INITIALIZED) { + LOGE("The Sign has not been init"); + return HCF_INVALID_PARAMS; + } + + HcfResult ret; + if (impl->operation == HCF_OPERATIOPN_ONLY_SIGN) { + ret = EnginePkeySign(impl, data, returnSignatureData); + } else { + ret = EngineDigestSign(impl, data, returnSignatureData); + } + + return ret; +} + static bool EngineVerify(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) { if (self == NULL || signatureData == NULL || signatureData->data == NULL) { @@ -423,6 +589,12 @@ static bool EngineVerify(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureDa LOGE("The Sign has not been init"); return false; } + + if (impl->operation != RSA_DIGEST_VERIFY) { + LOGE("Invalid digest verify operation."); + return HCF_INVALID_PARAMS; + } + if (data != NULL && data->data != NULL) { if (Openssl_EVP_DigestVerifyUpdate(impl->mdctx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { LOGD("[error] Openssl_EVP_DigestVerifyUpdate fail"); @@ -436,8 +608,82 @@ static bool EngineVerify(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureDa return true; } +static HcfResult EngineRecover(HcfVerifySpi *self, HcfBlob *signatureData, HcfBlob *rawSignatureData) +{ + if (self == NULL || signatureData == NULL || signatureData->data == NULL || rawSignatureData == NULL) { + LOGE("Invalid input params"); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, OPENSSL_RSA_VERIFY_CLASS)) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiRsaOpensslImpl *impl = (HcfVerifySpiRsaOpensslImpl *)self; + if (impl->initFlag != INITIALIZED) { + LOGE("The Sign has not been init."); + return HCF_INVALID_PARAMS; + } + + if (impl->operation != RSA_VERIFY_RECOVER) { + LOGE("Invalid verify recover operation."); + return HCF_INVALID_PARAMS; + } + + size_t bufLen = 0; + if (Openssl_EVP_PKEY_verify_recover(impl->ctx, NULL, &bufLen, signatureData->data, signatureData->len) + != HCF_OPENSSL_SUCCESS) { + LOGE("[error] Openssl_EVP_PKEY_verify_recover get len fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + + uint8_t *buf = (uint8_t *)HcfMalloc((uint32_t)bufLen, 0); + if (buf == NULL) { + LOGE("[error] HcfMalloc fail"); + return HCF_ERR_MALLOC; + } + + if (Openssl_EVP_PKEY_verify_recover(impl->ctx, buf, &bufLen, signatureData->data, signatureData->len) + != HCF_OPENSSL_SUCCESS) { + LOGE("[error] Openssl_EVP_PKEY_verify_recover fail."); + HcfPrintOpensslError(); + HcfFree(buf); + buf = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + + rawSignatureData->data = buf; + rawSignatureData->len = bufLen; + return HCF_SUCCESS; +} + +static HcfResult CheckOnlySignatureParams(HcfSignatureParams *params) +{ + int32_t opensslPadding = 0; + if (GetOpensslPadding(params->padding, &opensslPadding) != HCF_SUCCESS) { + LOGE("getpadding fail."); + return HCF_INVALID_PARAMS; + } + if (opensslPadding != RSA_PKCS1_PADDING && opensslPadding != RSA_NO_PADDING) { + LOGE("only signature cannot use that padding mode."); + return HCF_INVALID_PARAMS; + } + EVP_MD *md = NULL; + HcfResult ret = GetOpensslDigestAlg(params->md, &md); + if (ret != HCF_SUCCESS) { + LOGE("Md is invalid."); + return HCF_INVALID_PARAMS; + } + + return HCF_SUCCESS; +} + static HcfResult CheckSignatureParams(HcfSignatureParams *params) { + if (params->operation == HCF_ALG_ONLY_SIGN) { + return CheckOnlySignatureParams(params); + } int32_t opensslPadding = 0; if (GetOpensslPadding(params->padding, &opensslPadding) != HCF_SUCCESS) { LOGE("getpadding fail."); @@ -731,19 +977,41 @@ HcfResult HcfSignSpiRsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj returnImpl->mdctx = EVP_MD_CTX_create(); returnImpl->initFlag = UNINITIALIZED; returnImpl->saltLen = PSS_SALTLEN_INVALID_INIT; + returnImpl->operation = params->operation == HCF_ALG_ONLY_SIGN ? HCF_OPERATIOPN_ONLY_SIGN : HCF_OPERATION_SIGN; *returnObj = (HcfSignSpi *)returnImpl; return HCF_SUCCESS; } +static HcfResult CheckVerifyRecoverParams(HcfSignatureParams *params) +{ + int32_t opensslPadding = 0; + if (GetOpensslPadding(params->padding, &opensslPadding) != HCF_SUCCESS) { + LOGE("getpadding fail."); + return HCF_INVALID_PARAMS; + } + if (opensslPadding != RSA_PKCS1_PADDING && opensslPadding != RSA_NO_PADDING) { + LOGE("VerifyRecover cannot use that padding mode"); + return HCF_INVALID_PARAMS; + } + return HCF_SUCCESS; +} + HcfResult HcfVerifySpiRsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj) { if (params == NULL || returnObj == NULL) { LOGE("Invalid input parameter."); return HCF_INVALID_PARAMS; } - if (CheckSignatureParams(params) != HCF_SUCCESS) { - return HCF_INVALID_PARAMS; + if (params->operation != HCF_ALG_VERIFY_RECOVER) { + if (CheckSignatureParams(params) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + } else { + if (CheckVerifyRecoverParams(params) != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } } + HcfVerifySpiRsaOpensslImpl *returnImpl = (HcfVerifySpiRsaOpensslImpl *)HcfMalloc( sizeof(HcfVerifySpiRsaOpensslImpl), 0); if (returnImpl == NULL) { @@ -755,16 +1023,22 @@ HcfResult HcfVerifySpiRsaCreate(HcfSignatureParams *params, HcfVerifySpi **retur returnImpl->base.engineInit = EngineVerifyInit; returnImpl->base.engineUpdate = EngineVerifyUpdate; returnImpl->base.engineVerify = EngineVerify; + returnImpl->base.engineRecover = EngineRecover; returnImpl->base.engineSetVerifySpecInt = EngineSetVerifySpecInt; returnImpl->base.engineGetVerifySpecInt = EngineGetVerifySpecInt; returnImpl->base.engineGetVerifySpecString = EngineGetVerifySpecString; returnImpl->base.engineSetVerifySpecUint8Array = EngineSetVerifySpecUint8Array; returnImpl->md = params->md; returnImpl->padding = params->padding; - returnImpl->mgf1md = params->mgf1md; - returnImpl->mdctx = EVP_MD_CTX_create(); + if (params->operation != HCF_ALG_VERIFY_RECOVER) { + returnImpl->mgf1md = params->mgf1md; + returnImpl->mdctx = EVP_MD_CTX_create(); + returnImpl->saltLen = PSS_SALTLEN_INVALID_INIT; + returnImpl->operation = RSA_DIGEST_VERIFY; + } else { + returnImpl->operation = RSA_VERIFY_RECOVER; + } returnImpl->initFlag = UNINITIALIZED; - returnImpl->saltLen = PSS_SALTLEN_INVALID_INIT; *returnObj = (HcfVerifySpi *)returnImpl; return HCF_SUCCESS; } diff --git a/plugin/openssl_plugin/key/asy_key_generator/inc/ecc_common_param_spec_generator_openssl.h b/plugin/openssl_plugin/key/asy_key_generator/inc/ecc_common_param_spec_generator_openssl.h index 8a2808bf0e433cae285f1a5e61726907a2d52ee5..b24446712efb93d698206ed690015a5756876da9 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/inc/ecc_common_param_spec_generator_openssl.h +++ b/plugin/openssl_plugin/key/asy_key_generator/inc/ecc_common_param_spec_generator_openssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -16,6 +16,7 @@ #ifndef HCF_ECC_COMMON_PARAM_SPEC_GENERATOR_OPENSSL_H #define HCF_ECC_COMMON_PARAM_SPEC_GENERATOR_OPENSSL_H +#include "blob.h" #include "ecc_key_util_spi.h" #include "params_parser.h" #include "result.h" @@ -26,6 +27,11 @@ extern "C" { HcfResult HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams *params, HcfEccCommParamsSpecSpi **returnCommonParamSpec); +HcfResult HcfEngineConvertPoint(const int32_t curveNameValue, HcfBlob *pointBlob, HcfPoint *returnPoint); + +HcfResult HcfEngineGetEncodedPoint(const int32_t curveNameValue, HcfPoint *point, + const int32_t formatValue, HcfBlob *returnBlob); + #ifdef __cplusplus } #endif diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/alg_25519_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/alg_25519_asy_key_generator_openssl.c index 3738cb8f1b6e47282460dcdd3ae350d3f6e935fc..3914fc66da8dac854343bce01f82cbeb4eddfaec 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/alg_25519_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/alg_25519_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -409,6 +409,14 @@ static HcfResult GetStrSpecFromAlg25519PriKey(const HcfPriKey *self, const AsyKe return HCF_NOT_SUPPORT; } +static HcfResult GetAlg25519PriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static void ClearAlg25519PriKeyMem(HcfPriKey *self) { if (self == NULL) { @@ -452,6 +460,14 @@ static HcfResult GenerateAlg25519EvpKey(int type, EVP_PKEY **ppkey) return ret; } +static HcfResult GetAlg25519PubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static void FillOpensslAlg25519PubKeyFunc(HcfOpensslAlg25519PubKey *pk) { pk->base.base.base.destroy = DestroyAlg25519PubKey; @@ -462,6 +478,7 @@ static void FillOpensslAlg25519PubKeyFunc(HcfOpensslAlg25519PubKey *pk) pk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromAlg25519PubKey; pk->base.getAsyKeySpecInt = GetIntSpecFromAlg25519PubKey; pk->base.getAsyKeySpecString = GetStrSpecFromAlg25519PubKey; + pk->base.getEncodedDer = GetAlg25519PubKeyEncodedDer; } static void FillOpensslAlg25519PriKeyFunc(HcfOpensslAlg25519PriKey *sk) @@ -474,6 +491,7 @@ static void FillOpensslAlg25519PriKeyFunc(HcfOpensslAlg25519PriKey *sk) sk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromAlg25519PriKey; sk->base.getAsyKeySpecInt = GetIntSpecFromAlg25519PriKey; sk->base.getAsyKeySpecString = GetStrSpecFromAlg25519PriKey; + sk->base.getEncodedDer = GetAlg25519PriKeyEncodedDer; sk->base.clearMem = ClearAlg25519PriKeyMem; } diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/dh_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/dh_asy_key_generator_openssl.c index 3efea48078b66fef79e7cff34be0f404fbefa6e2..d5c08cd2f39de630f519f21ca61ca48b747374a7 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/dh_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/dh_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -384,6 +384,14 @@ static HcfResult GetStrSpecFromDhPriKey(const HcfPriKey *self, const AsyKeySpecI return HCF_NOT_SUPPORT; } +static HcfResult GetDhPriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static void ClearDhPriKeyMem(HcfPriKey *self) { if (self == NULL) { @@ -473,6 +481,14 @@ static HcfResult GenerateDhEvpKey(int32_t dhId, EVP_PKEY **ppkey) return ret; } +static HcfResult GetDhPubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static void FillOpensslDhPubKeyFunc(HcfOpensslDhPubKey *pk) { pk->base.base.base.destroy = DestroyDhPubKey; @@ -483,6 +499,7 @@ static void FillOpensslDhPubKeyFunc(HcfOpensslDhPubKey *pk) pk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDhPubKey; pk->base.getAsyKeySpecInt = GetIntSpecFromDhPubKey; pk->base.getAsyKeySpecString = GetStrSpecFromDhPubKey; + pk->base.getEncodedDer = GetDhPubKeyEncodedDer; } static void FillOpensslDhPriKeyFunc(HcfOpensslDhPriKey *sk) @@ -495,6 +512,7 @@ static void FillOpensslDhPriKeyFunc(HcfOpensslDhPriKey *sk) sk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDhPriKey; sk->base.getAsyKeySpecInt = GetIntSpecFromDhPriKey; sk->base.getAsyKeySpecString = GetStrSpecFromDhPriKey; + sk->base.getEncodedDer = GetDhPriKeyEncodedDer; sk->base.clearMem = ClearDhPriKeyMem; } diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c index d04ce18f5d8cb65807361271af22ece0e33a8101..1aa469f77cd4ef77529b4e2ac6b02b5437e925f1 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -348,6 +348,14 @@ static void ClearDsaPriKeyMem(HcfPriKey *self) impl->sk = NULL; } +static HcfResult GetDsaPriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static HcfResult GenerateDsaEvpKey(int32_t keyLen, EVP_PKEY **ppkey) { EVP_PKEY_CTX *paramsCtx = NULL; @@ -397,6 +405,14 @@ static HcfResult GenerateDsaEvpKey(int32_t keyLen, EVP_PKEY **ppkey) return ret; } +static HcfResult GetDsaPubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static void FillOpensslDsaPubKeyFunc(HcfOpensslDsaPubKey *pk) { pk->base.base.base.destroy = DestroyDsaPubKey; @@ -407,6 +423,7 @@ static void FillOpensslDsaPubKeyFunc(HcfOpensslDsaPubKey *pk) pk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDsaPubKey; pk->base.getAsyKeySpecInt = GetIntSpecFromDsaPubKey; pk->base.getAsyKeySpecString = GetStrSpecFromDsaPubKey; + pk->base.getEncodedDer = GetDsaPubKeyEncodedDer; } static void FillOpensslDsaPriKeyFunc(HcfOpensslDsaPriKey *sk) @@ -420,6 +437,7 @@ static void FillOpensslDsaPriKeyFunc(HcfOpensslDsaPriKey *sk) sk->base.getAsyKeySpecInt = GetIntSpecFromDsaPriKey; sk->base.getAsyKeySpecString = GetStrSpecFromDsaPriKey; sk->base.clearMem = ClearDsaPriKeyMem; + sk->base.getEncodedDer = GetDsaPriKeyEncodedDer; } static HcfResult CreateDsaPubKey(DSA *pk, HcfOpensslDsaPubKey **returnPubKey) diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c index 603a7bf97d16aeeab8b9b661e34655b576df9744..f2a3915b7eefbe82895cfb7d80f6b7d666dc0455 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -22,6 +22,7 @@ #include "log.h" #include "memory.h" #include "openssl_adapter.h" +#include #include "utils.h" #define OPENSSL_ECC_KEY_GENERATOR_CLASS "OPENSSL.ECC.KEY_GENERATOR_CLASS" @@ -37,6 +38,9 @@ #define OPENSSL_ECC512_BITS 512 #define OPENSSL_ECC521_BITS 521 +#define UNCOMPRESSED_FORMAT "UNCOMPRESSED" +#define COMPRESSED_FORMAT "COMPRESSED" + static const char *g_eccGenerateFieldType = "Fp"; typedef struct { @@ -1020,23 +1024,228 @@ static const char *GetEccPriKeyFormat(HcfKey *self) return OPENSSL_ECC_PRI_KEY_FORMAT; } -static HcfResult GetEccPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +static HcfResult CheckAndUpdateEccPubKeyFormat(const char **format) { - if ((self == NULL) || (returnBlob == NULL)) { - LOGE("Invalid input parameter."); + if (format == NULL || *format == NULL) { + LOGE("Invalid format parameter"); return HCF_INVALID_PARAMS; } - if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_ECC_PUB_KEY_CLASS)) { + + const char *x509Str = "X509|"; + + if (strncmp(*format, x509Str, HcfStrlen(x509Str)) != 0) { + LOGE("Invalid x509Str parameter"); return HCF_INVALID_PARAMS; } - HcfOpensslEccPubKey *impl = (HcfOpensslEccPubKey *)self; + const char *formatPtr = *format + HcfStrlen(x509Str); + + if (strcmp(formatPtr, UNCOMPRESSED_FORMAT) == 0 || strcmp(formatPtr, COMPRESSED_FORMAT) == 0) { + *format = formatPtr; + return HCF_SUCCESS; + } else { + LOGE("Invalid formatPtr parameter"); + return HCF_INVALID_PARAMS; + } +} + +static OSSL_PARAM *ConvertHcfBlobToOsslParams(const char *groupName, HcfBlob *pointBlob, const char *format) +{ + OSSL_PARAM_BLD *param_bld = Openssl_OSSL_PARAM_BLD_new(); + if (param_bld == NULL) { + LOGE("param_bld is null"); + return NULL; + } + if (Openssl_OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", groupName, 0) != HCF_OPENSSL_SUCCESS) { + LOGE("Invalid groupName parameter."); + Openssl_OSSL_PARAM_BLD_free(param_bld); + return NULL; + } + if (Openssl_OSSL_PARAM_BLD_push_utf8_string(param_bld, "point-format", format, 0) != HCF_OPENSSL_SUCCESS) { + LOGE("Invalid format parameter."); + Openssl_OSSL_PARAM_BLD_free(param_bld); + return NULL; + } + if (Openssl_OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", pointBlob->data, pointBlob->len) + != HCF_OPENSSL_SUCCESS) { + LOGE("Invalid pointBlob parameter."); + Openssl_OSSL_PARAM_BLD_free(param_bld); + return NULL; + } + OSSL_PARAM *params = Openssl_OSSL_PARAM_BLD_to_param(param_bld); + if (params == NULL) { + LOGE("Failed to convert OSSL_PARAM_BLD to OSSL_PARAM"); + HcfPrintOpensslError(); + Openssl_OSSL_PARAM_BLD_free(param_bld); + return NULL; + } + Openssl_OSSL_PARAM_BLD_free(param_bld); + return params; +} + +static EC_KEY *ConvertOsslParamsToEccPubKey(const char *groupName, int32_t curveId, + HcfBlob *pointBlob, const char *format) +{ + OSSL_PARAM *params = ConvertHcfBlobToOsslParams(groupName, pointBlob, format); + if (params == NULL) { + LOGE("Failed to convert OSSL_PARAM_BLD to OSSL_PARAM"); + return NULL; + } + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + EC_KEY *returnKey = NULL; + do { + ctx = Openssl_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (ctx == NULL) { + LOGE("Failed to create EVP_PKEY_CTX"); + break; + } + if (Openssl_EVP_PKEY_paramgen_init(ctx) <= 0) { + LOGE("Create EVP_PKEY_CTX by curveId fail, curveId is %d", curveId); + break; + } + if (Openssl_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curveId) <= 0) { + LOGE("EVP init curveId fail"); + HcfPrintOpensslError(); + break; + } + if (Openssl_EVP_PKEY_fromdata_init(ctx) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP init fail"); + break; + } + if (Openssl_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP get pkey fail"); + HcfPrintOpensslError(); + break; + } + returnKey = Openssl_EVP_PKEY_get1_EC_KEY(pkey); + if (returnKey == NULL) { + LOGE("Return key is NULL"); + break; + } + } while (0); + Openssl_EVP_PKEY_free(pkey); + Openssl_EVP_PKEY_CTX_free(ctx); + Openssl_OSSL_PARAM_free(params); + return returnKey; +} + +static HcfResult GetCompressedEccPointEncoded(HcfOpensslEccPubKey *impl, HcfBlob *returnBlob) +{ + EC_KEY *ecKey = impl->ecKey; + const EC_GROUP *group = Openssl_EC_KEY_get0_group(ecKey); + if (group == NULL) { + LOGE("Failed to get group."); + return HCF_ERR_CRYPTO_OPERATION; + } + const EC_POINT *point = Openssl_EC_KEY_get0_public_key(ecKey); + if (point == NULL) { + LOGE("Failed to get point."); + return HCF_ERR_CRYPTO_OPERATION; + } + size_t returnDataLen = Openssl_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL); + if (returnDataLen == 0) { + LOGE("Failed to get compressed key length."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *returnData = (uint8_t *)HcfMalloc(returnDataLen, 0); + if (returnData == NULL) { + LOGE("Failed to allocate memory for returnBlob data."); + return HCF_ERR_MALLOC; + } + size_t result = Openssl_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, + returnData, returnDataLen, NULL); + if (result != returnDataLen) { + LOGE("Failed to convert public key to compressed format."); + HcfPrintOpensslError(); + HcfFree(returnData); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = returnDataLen; + return HCF_SUCCESS; +} + +static HcfResult GetDerEccPubKeyEncoded(EC_KEY *ecKey, HcfBlob *returnBlob) +{ + unsigned char *returnData = NULL; + int returnDataLen = Openssl_i2d_EC_PUBKEY(ecKey, &returnData); + if (returnDataLen <= 0) { + LOGE("i2d_EC_PUBKEY fail"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = returnDataLen; + return HCF_SUCCESS; +} + +static void SetEccKeyAsn1Flag(HcfOpensslEccPubKey *impl) +{ if (impl->curveId != 0) { LOGD("have a curveId"); Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); } else { Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); } +} + +static HcfResult GetEccPubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (CheckAndUpdateEccPubKeyFormat(&format) != HCF_SUCCESS) { + LOGE("Invalid format."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_ECC_PUB_KEY_CLASS)) { + LOGE("Invalid input parameter type."); + return HCF_INVALID_PARAMS; + } + HcfOpensslEccPubKey *impl = (HcfOpensslEccPubKey *)self; + SetEccKeyAsn1Flag(impl); + + char *groupName = NULL; + HcfResult ret = GetGroupNameByNid(impl->curveId, &groupName); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get group name."); + return ret; + } + HcfBlob tmpBlob = { .data = NULL, .len = 0 }; + ret = GetCompressedEccPointEncoded(impl, &tmpBlob); + if (ret != HCF_SUCCESS) { + LOGE("Invalid input parameter."); + return ret; + } + EC_KEY *tmpEcKey = ConvertOsslParamsToEccPubKey(groupName, impl->curveId, &tmpBlob, format); + if (tmpEcKey == NULL) { + LOGE("Failed to convert ECC parameters to EC public key."); + HcfBlobDataFree(&tmpBlob); + return HCF_ERR_CRYPTO_OPERATION; + } + ret = GetDerEccPubKeyEncoded(tmpEcKey, returnBlob); + Openssl_EC_KEY_free(tmpEcKey); + HcfBlobDataFree(&tmpBlob); + return ret; +} + +static HcfResult GetEccPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_ECC_PUB_KEY_CLASS)) { + return HCF_INVALID_PARAMS; + } + + HcfOpensslEccPubKey *impl = (HcfOpensslEccPubKey *)self; + SetEccKeyAsn1Flag(impl); unsigned char *returnData = NULL; int returnDataLen = Openssl_i2d_EC_PUBKEY(impl->ecKey, &returnData); @@ -1085,6 +1294,98 @@ static HcfResult GetEccPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) return HCF_SUCCESS; } +static HcfResult ParamCheck(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + if ((self == NULL) || (format == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, HCF_OPENSSL_ECC_PRI_KEY_CLASS)) { + LOGE("Invalid ecc params."); + return HCF_INVALID_PARAMS; + } + if (strcmp(format, "PKCS8") != 0) { + LOGE("Invalid point format."); + return HCF_INVALID_PARAMS; + } + return HCF_SUCCESS; +} + +static HcfResult CopyMemFromBIO(BIO *bio, HcfBlob *returnBlob) +{ + int len = BIO_pending(bio); + if (len <= 0) { + LOGE("Bio len less than 0."); + return HCF_INVALID_PARAMS; + } + HcfBlob tmpBlob; + tmpBlob.len = len; + tmpBlob.data = (uint8_t *)HcfMalloc(sizeof(uint8_t) * len, 0); + if (tmpBlob.data == NULL) { + LOGE("Malloc mem for blob fail."); + return HCF_ERR_MALLOC; + } + if (Openssl_BIO_read(bio, tmpBlob.data, tmpBlob.len) <= 0) { + LOGE("Bio read fail"); + HcfPrintOpensslError(); + HcfFree(tmpBlob.data); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->len = tmpBlob.len; + returnBlob->data = tmpBlob.data; + return HCF_SUCCESS; +} + +static HcfResult GetECPriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + HcfResult ret = ParamCheck(self, format, returnBlob); + if (ret != HCF_SUCCESS) { + return ret; + } + HcfOpensslEccPriKey *impl = (HcfOpensslEccPriKey *)self; + if (impl->curveId != 0) { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_NAMED_CURVE); + } else { + Openssl_EC_KEY_set_asn1_flag(impl->ecKey, OPENSSL_EC_EXPLICIT_CURVE); + } + // keep consistence of 3.2 + Openssl_EC_KEY_set_enc_flags(impl->ecKey, EC_PKEY_NO_PUBKEY); + EVP_PKEY *pkey = Openssl_EVP_PKEY_new(); + if (pkey == NULL) { + HcfPrintOpensslError(); + LOGE("New pKey failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_set1_EC_KEY(pkey, impl->ecKey) != HCF_OPENSSL_SUCCESS) { + Openssl_EVP_PKEY_free(pkey); + HcfPrintOpensslError(); + LOGE("set ec key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + BIO *bio = Openssl_BIO_new(Openssl_BIO_s_mem()); + if (bio == NULL) { + LOGE("BIO new fail."); + HcfPrintOpensslError(); + ret = HCF_ERR_CRYPTO_OPERATION; + goto ERR2; + } + if (Openssl_i2d_PKCS8PrivateKey_bio(bio, pkey, NULL, NULL, 0, NULL, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("i2d privateKey bio fail."); + HcfPrintOpensslError(); + ret = HCF_ERR_CRYPTO_OPERATION; + goto ERR1; + } + ret = CopyMemFromBIO(bio, returnBlob); + if (ret != HCF_SUCCESS) { + LOGE("Copy mem from BIO fail."); + } +ERR1: + Openssl_BIO_free_all(bio); +ERR2: + Openssl_EVP_PKEY_free(pkey); + return ret; +} + static void EccPriKeyClearMem(HcfPriKey *self) { if (self == NULL) { @@ -1320,6 +1621,7 @@ static HcfResult PackEccPubKey(int32_t curveId, EC_KEY *ecKey, const char *field returnPubKey->base.getAsyKeySpecBigInteger = GetECPubKeySpecBigInteger; returnPubKey->base.getAsyKeySpecString = GetECPubKeySpecString; returnPubKey->base.getAsyKeySpecInt = GetECPubKeySpecInt; + returnPubKey->base.getEncodedDer = GetEccPubKeyEncodedDer; returnPubKey->curveId = curveId; returnPubKey->ecKey = ecKey; returnPubKey->fieldType = tmpFieldType; @@ -1362,6 +1664,7 @@ static HcfResult PackEccPriKey(int32_t curveId, EC_KEY *ecKey, const char *field returnPriKey->base.getAsyKeySpecBigInteger = GetECPriKeySpecBigInteger; returnPriKey->base.getAsyKeySpecString = GetECPriKeySpecString; returnPriKey->base.getAsyKeySpecInt = GetECPriKeySpecInt; + returnPriKey->base.getEncodedDer = GetECPriKeyEncodedDer; returnPriKey->curveId = curveId; returnPriKey->ecKey = ecKey; returnPriKey->fieldType = tmpFieldType; @@ -1392,31 +1695,55 @@ static HcfResult ConvertEcPubKey(int32_t curveId, HcfBlob *pubKeyBlob, HcfOpenss const unsigned char *tmpData = (const unsigned char *)(pubKeyBlob->data); EC_KEY *ecKey = Openssl_d2i_EC_PUBKEY(NULL, &tmpData, pubKeyBlob->len); if (ecKey == NULL) { - LOGD("[error] d2i_EC_PUBKEY fail."); + LOGE("d2i_EC_PUBKEY fail."); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } HcfResult res = PackEccPubKey(curveId, ecKey, g_eccGenerateFieldType, returnPubKey); if (res != HCF_SUCCESS) { - LOGD("[error] PackEccPubKey failed."); + LOGE("PackEccPubKey failed."); Openssl_EC_KEY_free(ecKey); return res; + } + return HCF_SUCCESS; +} + +static HcfResult ConvertPriFromEncoded(EC_KEY **eckey, HcfBlob *priKeyBlob) +{ + const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); + EVP_PKEY *pkey = Openssl_d2i_PrivateKey(EVP_PKEY_EC, NULL, &tmpData, priKeyBlob->len); + if (pkey == NULL) { + HcfPrintOpensslError(); + LOGE("d2i pri key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + *eckey = EVP_PKEY_get1_EC_KEY(pkey); + Openssl_EVP_PKEY_free(pkey); + if (*eckey == NULL) { + LOGE("Get eckey failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; } return HCF_SUCCESS; } static HcfResult ConvertEcPriKey(int32_t curveId, HcfBlob *priKeyBlob, HcfOpensslEccPriKey **returnPriKey) { - const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); - EC_KEY *ecKey = Openssl_d2i_ECPrivateKey(NULL, &tmpData, priKeyBlob->len); + EC_KEY *ecKey = NULL; + HcfResult res = ConvertPriFromEncoded(&ecKey, priKeyBlob); + if (res != HCF_SUCCESS) { + LOGE("i2d for private key failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } if (ecKey == NULL) { - LOGD("[error] d2i_ECPrivateKey fail"); + LOGE("d2i ec private key fail"); HcfPrintOpensslError(); return HCF_ERR_CRYPTO_OPERATION; } - HcfResult res = PackEccPriKey(curveId, ecKey, g_eccGenerateFieldType, returnPriKey); + res = PackEccPriKey(curveId, ecKey, g_eccGenerateFieldType, returnPriKey); if (res != HCF_SUCCESS) { - LOGD("[error] PackEccPriKey failed."); + LOGE("Pack ec pri key failed."); Openssl_EC_KEY_free(ecKey); return res; } diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_common_param_spec_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_common_param_spec_generator_openssl.c index 7b66f56b6320a8591424c1e106fe4300845e1ca0..44bc82fc2176b2b7350062a01586e1b80af58fb3 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/ecc_common_param_spec_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/ecc_common_param_spec_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -277,3 +277,195 @@ HcfResult HcfECCCommonParamSpecCreate(HcfAsyKeyGenParams *params, HcfEccCommPara Openssl_EC_GROUP_free(ecGroup); return HCF_SUCCESS; } + +static HcfResult InitEccPoint(const int32_t curveNameValue, EC_GROUP **ecGroup, + EC_POINT **ecPoint, BIGNUM **x, BIGNUM **y) +{ + int32_t nid = 0; + if (GetNidByCurveNameValue(curveNameValue, &nid) != HCF_SUCCESS) { + LOGE("Failed to get curveNameValue."); + return HCF_INVALID_PARAMS; + } + *ecGroup = Openssl_EC_GROUP_new_by_curve_name(nid); + if (*ecGroup == NULL) { + LOGE("Failed to create EC group with nid %d.", nid); + return HCF_ERR_CRYPTO_OPERATION; + } + *ecPoint = Openssl_EC_POINT_new(*ecGroup); + if (*ecPoint == NULL) { + LOGE("Failed to allocate memory for EC_POINT."); + Openssl_EC_GROUP_free(*ecGroup); + *ecGroup = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + *x = Openssl_BN_new(); + if (*x == NULL) { + LOGE("Failed to allocate memory for BIGNUM x."); + Openssl_EC_GROUP_free(*ecGroup); + *ecGroup = NULL; + Openssl_EC_POINT_free(*ecPoint); + *ecPoint = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + *y = Openssl_BN_new(); + if (*y == NULL) { + LOGE("Failed to allocate memory for BIGNUM y."); + Openssl_BN_free(*x); + *x = NULL; + Openssl_EC_GROUP_free(*ecGroup); + *ecGroup = NULL; + Openssl_EC_POINT_free(*ecPoint); + *ecPoint = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static void FreeHcfBigInteger(HcfBigInteger *bigInt) +{ + HcfFree(bigInt->data); + bigInt->data = NULL; + bigInt->len = 0; +} + +static HcfResult ConvertBigNumToEccPoint(const BIGNUM *x, const BIGNUM *y, + HcfBigInteger *bigIntX, HcfBigInteger *bigIntY) +{ + HcfResult ret = BigNumToBigInteger(x, bigIntX); + if (ret != HCF_SUCCESS) { + LOGE("Failed to convert XBIGNUM to HcfBigInteger."); + return ret; + } + ret = BigNumToBigInteger(y, bigIntY); + if (ret != HCF_SUCCESS) { + LOGE("Failed to convert YBIGNUM to HcfBigInteger."); + FreeHcfBigInteger(bigIntX); + return ret; + } + return HCF_SUCCESS; +} + +static HcfResult GetECCPointEncoded(const int32_t formatValue, EC_GROUP *ecGroup, + EC_POINT *ecPoint, HcfBlob *returnBlob) +{ + int32_t formatType = 0; + if (GetFormatTypeByFormatValue(formatValue, &formatType) != HCF_SUCCESS) { + LOGE("Failed to get formatType."); + return HCF_INVALID_PARAMS; + } + + size_t returnDataLen = Openssl_EC_POINT_point2oct(ecGroup, ecPoint, formatType, NULL, 0, NULL); + if (returnDataLen == 0) { + LOGE("Failed to get encoded point length."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + + uint8_t *returnData = (uint8_t *)HcfMalloc(returnDataLen, 0); + if (returnData == NULL) { + LOGE("Failed to allocate memory for encoded point data."); + return HCF_ERR_MALLOC; + } + size_t result = Openssl_EC_POINT_point2oct(ecGroup, ecPoint, formatType, returnData, returnDataLen, NULL); + if (result != returnDataLen) { + LOGE("Failed to get ECC point encoding."); + HcfPrintOpensslError(); + HcfFree(returnData); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = returnDataLen; + return HCF_SUCCESS; +} + +HcfResult HcfEngineConvertPoint(const int32_t curveNameValue, HcfBlob *pointBlob, HcfPoint *returnPoint) +{ + if ((curveNameValue == 0) || !IsBlobValid(pointBlob) || (returnPoint == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + EC_GROUP *ecGroup = NULL; + EC_POINT *ecPoint = NULL; + BIGNUM *x = NULL; + BIGNUM *y = NULL; + HcfBigInteger tmpBigIntX = { .data = NULL, .len = 0 }; + HcfBigInteger tmpBigIntY = { .data = NULL, .len = 0 }; + HcfResult ret = HCF_SUCCESS; + do { + ret = InitEccPoint(curveNameValue, &ecGroup, &ecPoint, &x, &y); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get EccPoint."); + break; + } + if (!Openssl_EC_POINT_oct2point(ecGroup, ecPoint, pointBlob->data, pointBlob->len, NULL)) { + LOGE("Failed to convert pointBlob data to EC_POINT."); + HcfPrintOpensslError(); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (!Openssl_EC_POINT_get_affine_coordinates(ecGroup, ecPoint, x, y, NULL)) { + LOGE("Failed to get affine coordinates from EC_POINT."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + ret = ConvertBigNumToEccPoint(x, y, &tmpBigIntX, &tmpBigIntY); + if (ret != HCF_SUCCESS) { + LOGE("Failed to convert BIGNUMs to HcfBigIntegers."); + break; + } + returnPoint->x = tmpBigIntX; + returnPoint->y = tmpBigIntY; + } while (0); + Openssl_EC_GROUP_free(ecGroup); + Openssl_EC_POINT_free(ecPoint); + Openssl_BN_free(x); + Openssl_BN_free(y); + return ret; +} + +HcfResult HcfEngineGetEncodedPoint(const int32_t curveNameValue, HcfPoint *point, + const int32_t formatValue, HcfBlob *returnBlob) +{ + if ((curveNameValue == 0) || (point == NULL) || (formatValue == 0) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + EC_GROUP *ecGroup = NULL; + EC_POINT *ecPoint = NULL; + BIGNUM *bnX = NULL; + BIGNUM *bnY = NULL; + HcfResult ret = HCF_SUCCESS; + do { + ret = InitEccPoint(curveNameValue, &ecGroup, &ecPoint, &bnX, &bnY); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get EccPoint."); + break; + } + ret = BigIntegerToBigNum(&(point->x), &bnX); + if (ret != HCF_SUCCESS) { + LOGE("Failed to convert HcfBigInteger to XBIGNUMs."); + break; + } + ret = BigIntegerToBigNum(&(point->y), &bnY); + if (ret != HCF_SUCCESS) { + LOGE("Failed to convert HcfBigInteger to YBIGNUMs."); + break; + } + if (Openssl_EC_POINT_set_affine_coordinates(ecGroup, ecPoint, bnX, bnY, NULL) != HCF_OPENSSL_SUCCESS) { + LOGE("Failed to set point coordinates."); + HcfPrintOpensslError(); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + ret = GetECCPointEncoded(formatValue, ecGroup, ecPoint, returnBlob); + if (ret != HCF_SUCCESS) { + LOGE("Failed to get EccPointEncoded."); + break; + } + } while (0); + Openssl_EC_GROUP_free(ecGroup); + Openssl_EC_POINT_free(ecPoint); + Openssl_BN_free(bnX); + Openssl_BN_free(bnY); + return ret; +} diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c index 762bb6e73706d56bce132eeeebbcb80528d7b64e..3015582b0e496831a80e06a551e5f3fb64c36f6c 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/rsa_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -153,6 +153,13 @@ static HcfResult GetRsaPriKeySpecInt(const HcfPriKey *self, const AsyKeySpecItem LOGE("Rsa has no integer attribute"); return HCF_NOT_SUPPORT; } +static HcfResult GetRsaPriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} static HcfResult GetRsaPriKeySpecBigInteger(const HcfPriKey *self, const AsyKeySpecItem item, HcfBigInteger *returnBigInteger) @@ -505,6 +512,14 @@ static void ClearPriKeyMem(HcfPriKey *self) impl->sk = NULL; } +static HcfResult GetRsaPubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static HcfResult PackPubKey(RSA *rsaPubKey, HcfOpensslRsaPubKey **retPubKey) { if (retPubKey == NULL || rsaPubKey == NULL) { @@ -526,6 +541,7 @@ static HcfResult PackPubKey(RSA *rsaPubKey, HcfOpensslRsaPubKey **retPubKey) (*retPubKey)->base.getAsyKeySpecBigInteger = GetRsaPubKeySpecBigInteger; (*retPubKey)->base.getAsyKeySpecString = GetRsaPubKeySpecString; (*retPubKey)->base.getAsyKeySpecInt = GetRsaPubKeySpecInt; + (*retPubKey)->base.getEncodedDer = GetRsaPubKeyEncodedDer; return HCF_SUCCESS; } @@ -552,6 +568,7 @@ static HcfResult PackPriKey(RSA *rsaPriKey, HcfOpensslRsaPriKey **retPriKey) (*retPriKey)->base.getAsyKeySpecBigInteger = GetRsaPriKeySpecBigInteger; (*retPriKey)->base.getAsyKeySpecString = GetRsaPriKeySpecString; (*retPriKey)->base.getAsyKeySpecInt = GetRsaPriKeySpecInt; + (*retPriKey)->base.getEncodedDer = GetRsaPriKeyEncodedDer; return HCF_SUCCESS; } diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c index 4b052c476a1adfd52fbdf98c3ab032bd1264c5a2..6645c675f57f85419a0c4570e719e1906a66e7ae 100644 --- a/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c +++ b/plugin/openssl_plugin/key/asy_key_generator/src/sm2_asy_key_generator_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -720,6 +720,14 @@ static HcfResult GetSm2PriKeySpecInt(const HcfPriKey *self, const AsyKeySpecItem return GetSm2KeySpecInt((HcfKey *)self, item, returnInt); } +static HcfResult GetSm2PubKeyEncodedDer(const HcfPubKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static HcfResult PackSm2PubKey(int32_t curveId, EC_KEY *ecKey, const char *fieldType, HcfOpensslSm2PubKey **returnObj) { @@ -753,6 +761,7 @@ static HcfResult PackSm2PubKey(int32_t curveId, EC_KEY *ecKey, const char *field returnPubKey->base.getAsyKeySpecBigInteger = GetSm2PubKeySpecBigInteger; returnPubKey->base.getAsyKeySpecString = GetSm2PubKeySpecString; returnPubKey->base.getAsyKeySpecInt = GetSm2PubKeySpecInt; + returnPubKey->base.getEncodedDer = GetSm2PubKeyEncodedDer; returnPubKey->curveId = curveId; returnPubKey->ecKey = ecKey; returnPubKey->fieldType = tmpFieldType; @@ -761,6 +770,14 @@ static HcfResult PackSm2PubKey(int32_t curveId, EC_KEY *ecKey, const char *field return HCF_SUCCESS; } +static HcfResult GetSm2PriKeyEncodedDer(const HcfPriKey *self, const char *format, HcfBlob *returnBlob) +{ + (void)self; + (void)format; + (void)returnBlob; + return HCF_INVALID_PARAMS; +} + static HcfResult PackSm2PriKey(int32_t curveId, EC_KEY *ecKey, const char *fieldType, HcfOpensslSm2PriKey **returnObj) { @@ -795,6 +812,7 @@ static HcfResult PackSm2PriKey(int32_t curveId, EC_KEY *ecKey, const char *field returnPriKey->base.getAsyKeySpecString = GetSm2PriKeySpecString; returnPriKey->base.getAsyKeySpecInt = GetSm2PriKeySpecInt; returnPriKey->base.clearMem = Sm2PriKeyClearMem; + returnPriKey->base.getEncodedDer = GetSm2PriKeyEncodedDer; returnPriKey->curveId = curveId; returnPriKey->ecKey = ecKey; returnPriKey->fieldType = tmpFieldType; diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 4ed4b8da42e1b783ba2b0a1dfe34cc1e18da0836..8a18e7fd4724e4e49bcaff0b76e6d8eb1333c900 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Huawei Device Co., Ltd. +# Copyright (C) 2022-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 @@ -75,6 +75,7 @@ plugin_cipher_files = [ "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_aes_common.c", "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_sm4_openssl.c", "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/cipher/src/cipher_sm2_crypto_util_openssl.c", ] plugin_hmac_files = @@ -88,6 +89,7 @@ plugin_md_files = plugin_kdf_files = [ "${plugin_path}/openssl_plugin/crypto_operation/kdf/src/pbkdf2_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c", ] plugin_files = plugin_asy_key_generator_files + plugin_key_agreement_files + diff --git a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn index d89b33d2b96bdf9fea4c990fe1beb3a277ff30da..2f7cfeb67fd1a98ddec8143f485bba08fcc28fda 100755 --- a/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfciphercreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfCipherCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfciphercreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/crypto_operation/hcfkeyagreementcreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfkeyagreementcreate_fuzzer/BUILD.gn index e48b5d8ec03bfe467c40d695c2564727a8f2b856..d8d13c041d2913cc375b76c8c7843522f46d8adb 100755 --- a/test/fuzztest/crypto_operation/hcfkeyagreementcreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfkeyagreementcreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfKeyAgreementCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfkeyagreementcreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/crypto_operation/hcfmaccreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfmaccreate_fuzzer/BUILD.gn index 38ee25f164630f6721bca1bccc5232b7dcb52f3e..41edf5024e758e52205165426c2ad8b3d30c1b54 100755 --- a/test/fuzztest/crypto_operation/hcfmaccreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfmaccreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfMacCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfmaccreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/crypto_operation/hcfmdcreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfmdcreate_fuzzer/BUILD.gn index d06021944b1835c127b80248d631bcb957878a4c..05ff22eacd91da9cfe24eb22cc5c8eabad10e110 100755 --- a/test/fuzztest/crypto_operation/hcfmdcreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfmdcreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfMdCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfmdcreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/crypto_operation/hcfsigncreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfsigncreate_fuzzer/BUILD.gn index d372f01b59c17106749ec4eb2773efa063d56c08..4518a51b6b646d3b7909ba17c6e38343c5c5eb34 100755 --- a/test/fuzztest/crypto_operation/hcfsigncreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfsigncreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfSignCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfsigncreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/crypto_operation/hcfverifycreate_fuzzer/BUILD.gn b/test/fuzztest/crypto_operation/hcfverifycreate_fuzzer/BUILD.gn index 5a683630b3d3bb6a1c6cbb5d1892b4fbfa45532a..682dd6f75aa68c9bec3e58f76a0791b38250853c 100755 --- a/test/fuzztest/crypto_operation/hcfverifycreate_fuzzer/BUILD.gn +++ b/test/fuzztest/crypto_operation/hcfverifycreate_fuzzer/BUILD.gn @@ -30,9 +30,9 @@ ohos_fuzztest("HcfVerifyCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfverifycreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/fuzztest/key/asykeygenerator_fuzzer/BUILD.gn b/test/fuzztest/key/asykeygenerator_fuzzer/BUILD.gn index f9921c5a2511fca789e6006428adf607f2e13ca4..6d62911e551e6b45e45410ae1bce7cb77cb4c675 100644 --- a/test/fuzztest/key/asykeygenerator_fuzzer/BUILD.gn +++ b/test/fuzztest/key/asykeygenerator_fuzzer/BUILD.gn @@ -31,16 +31,14 @@ ohos_fuzztest("AsyKeyGeneratorFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "asykeygenerator_fuzzer.cpp" ] - deps = [ - "../../../../plugin:crypto_openssl_plugin_lib", - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/openssl:libcrypto_shared", - ] + deps = [ "../../../../plugin:crypto_openssl_plugin_lib" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", + "openssl:libcrypto_shared", ] } diff --git a/test/fuzztest/key/dhkeyutil_fuzzer/BUILD.gn b/test/fuzztest/key/dhkeyutil_fuzzer/BUILD.gn index 58007cad3e55b03270bc0450da1d0610572a2a8c..5c91360ed51b224650e75c79be5b44d0d0b5048b 100644 --- a/test/fuzztest/key/dhkeyutil_fuzzer/BUILD.gn +++ b/test/fuzztest/key/dhkeyutil_fuzzer/BUILD.gn @@ -32,15 +32,13 @@ ohos_fuzztest("DhKeyUtilFuzzTest") { ] sources = [ "dhkeyutil_fuzzer.cpp" ] - deps = [ - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/openssl:libcrypto_shared", - ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", + "openssl:libcrypto_shared", ] } diff --git a/test/fuzztest/key/ecckeyutil_fuzzer/BUILD.gn b/test/fuzztest/key/ecckeyutil_fuzzer/BUILD.gn index d932eb1439118a2645a244e5b8f2bb8479993940..4ecbd1b715833f099e136f9c18557c78601a4170 100644 --- a/test/fuzztest/key/ecckeyutil_fuzzer/BUILD.gn +++ b/test/fuzztest/key/ecckeyutil_fuzzer/BUILD.gn @@ -32,15 +32,13 @@ ohos_fuzztest("EccKeyUtilFuzzTest") { ] sources = [ "ecckeyutil_fuzzer.cpp" ] - deps = [ - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/openssl:libcrypto_shared", - ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", + "openssl:libcrypto_shared", ] } diff --git a/test/fuzztest/key/symkeygenerator_fuzzer/BUILD.gn b/test/fuzztest/key/symkeygenerator_fuzzer/BUILD.gn index 4bf656ba8ed2c00d9be0023acaf6b60eebc60d94..3ba1371f72e9ce94b2d6dc1f49c080a39ef13d1b 100755 --- a/test/fuzztest/key/symkeygenerator_fuzzer/BUILD.gn +++ b/test/fuzztest/key/symkeygenerator_fuzzer/BUILD.gn @@ -25,10 +25,6 @@ ohos_fuzztest("SymKeyGeneratorFuzzTest") { module_out_path = module_output_path fuzz_config_file = "//base/security/crypto_framework/test/fuzztest/key/symkeygenerator_fuzzer" include_dirs = [ "./include" ] - include_dirs += [ - "//commonlibrary/c_utils/base/include", - "//third_party/openssl/include/", - ] include_dirs += framework_inc_path + plugin_inc_path sources = [ "symkeygenerator_fuzzer.cpp" ] cflags = [ @@ -42,15 +38,12 @@ ohos_fuzztest("SymKeyGeneratorFuzzTest") { cflags += [ "-DBINDER_IPC_32BIT" ] } - deps = [ - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/openssl:libcrypto_shared", - ] - external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", + "openssl:libcrypto_shared", ] } diff --git a/test/fuzztest/rand/hcfrandcreate_fuzzer/BUILD.gn b/test/fuzztest/rand/hcfrandcreate_fuzzer/BUILD.gn index 49cae7a72253f78a241be0a9333678781623898e..746fa6998e3e69418cb3e2e251fe42e146f283c5 100755 --- a/test/fuzztest/rand/hcfrandcreate_fuzzer/BUILD.gn +++ b/test/fuzztest/rand/hcfrandcreate_fuzzer/BUILD.gn @@ -32,9 +32,9 @@ ohos_fuzztest("HcfRandCreateFuzzTest") { "-fno-omit-frame-pointer", ] sources = [ "hcfrandcreate_fuzzer.cpp" ] - deps = [ "//third_party/bounds_checking_function:libsec_shared" ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "crypto_framework:crypto_framework_lib", "hilog:libhilog", diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index ddcfd68a7ebe412ff6a1088edbfa26f3c48555d0..a2b59086d03f55577856ae87c0b2bc00c7c5faa3 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -24,8 +24,6 @@ ohos_unittest("crypto_framework_test") { include_dirs = [ "./include" ] include_dirs += [ - "//commonlibrary/c_utils/base/include", - "//third_party/openssl/include/", "../../plugin/openssl_plugin/key/asy_key_generator/src", "../../plugin/openssl_plugin/crypto_operation/signature/src", "../../interfaces/innerkits/key/", @@ -66,6 +64,7 @@ ohos_unittest("crypto_framework_test") { "src/crypto_ed25519_asy_key_generator_test.cpp", "src/crypto_ed25519_sign_test.cpp", "src/crypto_ed25519_verify_test.cpp", + "src/crypto_hkdf_test.cpp", "src/crypto_mac_test.cpp", "src/crypto_md_sm3_test.cpp", "src/crypto_md_test.cpp", @@ -82,6 +81,7 @@ ohos_unittest("crypto_framework_test") { "src/crypto_rsa_asy_key_generator_test.cpp", "src/crypto_rsa_cipher_sub_test.cpp", "src/crypto_rsa_cipher_test.cpp", + "src/crypto_rsa_only_sign_and_verify_recover_test.cpp", "src/crypto_rsa_sign_test.cpp", "src/crypto_rsa_verify_test.cpp", "src/crypto_signature_exception_test.cpp", @@ -102,6 +102,7 @@ ohos_unittest("crypto_framework_test") { "src/ecc/crypto_ecc_asy_key_generator_by_spec_sub_three_test.cpp", "src/ecc/crypto_ecc_asy_key_generator_by_spec_sub_two_test.cpp", "src/ecc/crypto_ecc_asy_key_generator_by_spec_test.cpp", + "src/ecc/crypto_ecc_ecdh_pub_test.cpp", "src/ecc/crypto_ecc_no_length_sign_sub_test.cpp", "src/ecc/crypto_ecc_no_length_sign_test.cpp", "src/ecc/crypto_ecc_no_length_verify_sub_test.cpp", @@ -112,6 +113,7 @@ ohos_unittest("crypto_framework_test") { "src/ecc/crypto_ecc_verify_test.cpp", "src/sm2/crypto_sm2_asy_key_generator_by_spec_sub_test.cpp", "src/sm2/crypto_sm2_asy_key_generator_by_spec_test.cpp", + "src/sm2/crypto_sm2_util_test.cpp", ] sources += framework_files + plugin_files @@ -124,7 +126,6 @@ ohos_unittest("crypto_framework_test") { "//base/security/crypto_framework/common/src/blob.c", "//base/security/crypto_framework/common/src/hcf_parcel.c", "//base/security/crypto_framework/common/src/hcf_string.c", - "//base/security/crypto_framework/common/src/log.c", "//base/security/crypto_framework/common/src/object_base.c", "//base/security/crypto_framework/common/src/params_parser.c", "//base/security/crypto_framework/common/src/utils.c", @@ -141,11 +142,7 @@ ohos_unittest("crypto_framework_test") { cflags += [ "-DBINDER_IPC_32BIT" ] } - deps = [ - "../../plugin:crypto_openssl_plugin_lib", - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/openssl:libcrypto_shared", - ] + deps = [ "../../plugin:crypto_openssl_plugin_lib" ] defines = [ "HILOG_ENABLE", @@ -153,7 +150,9 @@ ohos_unittest("crypto_framework_test") { ] external_deps = [ + "bounds_checking_function:libsec_shared", "c_utils:utils", "hilog:libhilog", + "openssl:libcrypto_shared", ] } diff --git a/test/unittest/src/crypto_ecc_asy_key_generator_test.cpp b/test/unittest/src/crypto_ecc_asy_key_generator_test.cpp index 48a7b78712bb3c1e821c1f030c0b58ec7507ad7f..068c8c80cc6c894f7cb7839ac0af4f2d9df2b08c 100644 --- a/test/unittest/src/crypto_ecc_asy_key_generator_test.cpp +++ b/test/unittest/src/crypto_ecc_asy_key_generator_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -2343,4 +2343,52 @@ HWTEST_F(CryptoEccAsyKeyGeneratorTest, CryptoEccAsyKeyGeneratorTest702, TestSize EndRecordOpensslCallNum(); } + +HWTEST_F(CryptoEccAsyKeyGeneratorTest, CryptoEccPrvKeyDerConvertTest801, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + int32_t res = HcfAsyKeyGeneratorCreate("ECC224", &generator); + const char *wrongFormat = "PKCS7"; + const char *format = "PKCS8"; + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + + ASSERT_EQ(res, HCF_SUCCESS); + ASSERT_NE(keyPair, nullptr); + + HcfBlob pubKeyBlob = { .data = nullptr, .len = 0 }; + res = keyPair->pubKey->base.getEncoded(&(keyPair->pubKey->base), &pubKeyBlob); + ASSERT_EQ(res, HCF_SUCCESS); + ASSERT_NE(pubKeyBlob.data, nullptr); + ASSERT_NE(pubKeyBlob.len, 0); + + HcfBlob priKeyBlob = { .data = nullptr, .len = 0 }; + res = keyPair->priKey->getEncodedDer(keyPair->priKey, wrongFormat, &priKeyBlob); + ASSERT_EQ(res, HCF_INVALID_PARAMS); + ASSERT_EQ(priKeyBlob.data, nullptr); + ASSERT_EQ(priKeyBlob.len, 0); + + res = keyPair->priKey->getEncodedDer(nullptr, format, nullptr); + ASSERT_EQ(res, HCF_INVALID_PARAMS); + ASSERT_EQ(priKeyBlob.data, nullptr); + ASSERT_EQ(priKeyBlob.len, 0); + + res = keyPair->priKey->getEncodedDer(keyPair->priKey, format, &priKeyBlob); + ASSERT_EQ(res, HCF_SUCCESS); + ASSERT_NE(priKeyBlob.data, nullptr); + ASSERT_NE(priKeyBlob.len, 0); + + HcfKeyPair *outKeyPair = nullptr; + res = generator->convertKey(generator, nullptr, &pubKeyBlob, &priKeyBlob, &outKeyPair); + ASSERT_EQ(res, HCF_SUCCESS); + + HcfFree(pubKeyBlob.data); + HcfFree(priKeyBlob.data); + HcfObjDestroy(outKeyPair); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + + EndRecordMallocNum(); +} + } diff --git a/test/unittest/src/crypto_hkdf_test.cpp b/test/unittest/src/crypto_hkdf_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..659bd819b3c46ec9d7d0dc7db3b67be8e278551a --- /dev/null +++ b/test/unittest/src/crypto_hkdf_test.cpp @@ -0,0 +1,546 @@ +/* + * 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 "hkdf_openssl.h" + +#include +#include "securec.h" + +#include "detailed_hkdf_params.h" +#include "kdf.h" +#include "log.h" +#include "memory.h" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoHkdfTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoHkdfTest::SetUpTestCase() {} +void CryptoHkdfTest::TearDownTestCase() {} + +void CryptoHkdfTest::SetUp() // add init here, this will be called before test. +{ +} + +void CryptoHkdfTest::TearDown() // add destroy here, this will be called when test case done. +{ +} + +static const char *KEY_DATA = "012345678901234567890123456789"; +static const char *INFO_DATA = "infostring"; +static const char *SALT_DATA = "saltstring"; + + +constexpr uint32_t OUT_PUT_MAX_LENGTH = 128; +constexpr uint32_t OUT_PUT_NORMAL_LENGTH = 32; + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest1, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest2, TestSize.Level0) +{ + // mode is default, info data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = nullptr, .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest3, TestSize.Level0) +{ + // default mode is EXTRACT_AND_EXPAND + HcfKdf *generator = nullptr; + HcfKdf *generator1 = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfResult ret1 = HcfKdfCreate("HKDF|SHA256|EXTRACT_AND_EXPAND", &generator1); + EXPECT_EQ(ret1, HCF_SUCCESS); + + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfHkdfParamsSpec params1 = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret1 = generator->generateSecret(generator, &(params1.base)); + EXPECT_EQ(ret1, HCF_SUCCESS); + EXPECT_EQ(params.output.data, params1.output.data); + + HcfObjDestroy(generator); + HcfObjDestroy(generator1); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest4, TestSize.Level0) +{ + // mode is EXTRACT_ONLY + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256|EXTRACT_ONLY", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest5, TestSize.Level0) +{ + // mode is EXPAND_ONLY + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256|EXPAND_ONLY", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest6, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest7, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA384", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest8, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA512", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest9, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SM3", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTest10, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA224", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = reinterpret_cast(const_cast(KEY_DATA)), + .len = strlen(KEY_DATA)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError1, TestSize.Level1) +{ + // mode is EXPAND_ONLY, salt data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256|EXPAND_ONLY", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob info = {.data = nullptr, .len = 0}; + HcfBlob key = {.data = nullptr, .len = 0}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError2, TestSize.Level1) +{ + // mode is EXTRACT_ONLY, salt data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256|EXTRACT_ONLY", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = nullptr, .len = 0}; + HcfBlob key = {.data = nullptr, .len = 0}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError3, TestSize.Level1) +{ + // mode is default, data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = nullptr, .len = 0}; + HcfBlob key = {.data = nullptr, .len = 0}; + HcfBlob info = {.data = nullptr, .len = 0}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError4, TestSize.Level1) +{ + // mode is default, key data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[OUT_PUT_MAX_LENGTH] = {0}; + HcfBlob output = {.data = out, .len = OUT_PUT_NORMAL_LENGTH}; + HcfBlob salt = {.data = reinterpret_cast(const_cast(SALT_DATA)), + .len = strlen(SALT_DATA)}; + HcfBlob key = {.data = nullptr, .len = 0}; + HcfBlob info = {.data = reinterpret_cast(const_cast(INFO_DATA)), + .len = strlen(INFO_DATA)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError5, TestSize.Level1) +{ + // use basic params + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfKdfParamsSpec params = { + .algName = "HKDF", + }; + ret = generator->generateSecret(generator, ¶ms); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError6, TestSize.Level1) +{ + // use nullptr params + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = generator->generateSecret(generator, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError7, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|abcd", &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError8, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("ABCD|SM3", &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError9, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate(nullptr, &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestError10, TestSize.Level1) +{ + HcfResult ret = HcfKdfCreate(nullptr, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestVectors1, TestSize.Level1) +{ + uint8_t keyData[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }; + uint8_t infoData[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 }; + uint8_t saltData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c }; + uint8_t expectSecret[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, + 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, + 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, + 0x65 }; + + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[42] = {0}; + HcfBlob output = {.data = out, .len = 42}; + HcfBlob salt = {.data = saltData, .len = sizeof(saltData)}; + HcfBlob key = {.data = keyData, .len = sizeof(keyData)}; + HcfBlob info = {.data = infoData, .len = sizeof(infoData)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_EQ(memcmp(params.output.data, expectSecret, sizeof(expectSecret)), 0); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoHkdfTest, CryptoHkdfTestVectors2, TestSize.Level1) +{ + uint8_t keyData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f }; + uint8_t infoData[] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, + 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, + 0xfd, 0xfe, 0xff }; + uint8_t saltData[] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, + 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf }; + uint8_t expectSecret[] = { 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c, + 0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8, 0xa0, 0x50, 0xcc, 0x4c, + 0x19, 0xaf, 0xa9, 0x7c, 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72, 0x71, 0xcb, 0x41, 0xc6, + 0x5e, 0x59, 0x0e, 0x09, 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8, 0x36, 0x77, 0x93, 0xa9, + 0xac, 0xa3, 0xdb, 0x71, 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87, 0xc1, 0x4c, 0x01, 0xd5, + 0xc1, 0xf3, 0x43, 0x4f, 0x1d, 0x87 }; + + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("HKDF|SHA256|EXTRACT_AND_EXPAND", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[82] = {0}; + HcfBlob output = {.data = out, .len = 82}; + HcfBlob salt = {.data = saltData, .len = sizeof(saltData)}; + HcfBlob key = {.data = keyData, .len = sizeof(keyData)}; + HcfBlob info = {.data = infoData, .len = sizeof(infoData)}; + HcfHkdfParamsSpec params = { + .base = { .algName = "HKDF", }, + .key = key, + .salt = salt, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_EQ(memcmp(params.output.data, expectSecret, sizeof(expectSecret)), 0); + HcfObjDestroy(generator); +} +} diff --git a/test/unittest/src/crypto_mac_test.cpp b/test/unittest/src/crypto_mac_test.cpp index c64b59960ceb678c648524ce438ab16021df3b96..03f788e22625c95fba42ba5ea93ec9f728b51082 100644 --- a/test/unittest/src/crypto_mac_test.cpp +++ b/test/unittest/src/crypto_mac_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2023-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 @@ -43,6 +43,7 @@ constexpr uint32_t SHA224_LEN = 28; constexpr uint32_t SHA256_LEN = 32; constexpr uint32_t SHA384_LEN = 48; constexpr uint32_t SHA512_LEN = 64; +constexpr uint32_t MD5_LEN = 16; static char g_testBigData[] = "VqRH5dzdeeturr5zN5vE77DtqjV7kNKbDJqk4mNqyYRTXymhjR\r\n" "Yz8c2pNvJiCxyFwvLvWfPh2Y2eDAuxbdm2Dt4UzKJtNqEpNYKVZLiyH4a4MhR4BpFhvhJVHy2ALbYq2rW\r\n" @@ -910,4 +911,36 @@ HWTEST_F(CryptoMacTest, InvalidSpiClassMacTest001, TestSize.Level0) HcfObjDestroy(key); HcfObjDestroy(generator); } + +HWTEST_F(CryptoMacTest, CryptoFrameworkHmacAlgoTest012, TestSize.Level0) +{ + HcfMac *macObj = nullptr; + HcfResult ret = HcfMacCreate("MD5", &macObj); + EXPECT_EQ(ret, HCF_SUCCESS); + // create a symKey generator + HcfSymKeyGenerator *generator = nullptr; + ret = HcfSymKeyGeneratorCreate("HMAC|MD5", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfSymKey *key = nullptr; + generator->generateSymKey(generator, &key); + // set input and output blob + uint8_t testData[] = "My test data"; + HcfBlob inBlob = {.data = reinterpret_cast(testData), .len = sizeof(testData)}; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + // test api funcitons + ret = macObj->init(macObj, key); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->update(macObj, &inBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = macObj->doFinal(macObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = macObj->getMacLength(macObj); + EXPECT_EQ(len, MD5_LEN); + // destroy the API obj and blob data + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(macObj); + HcfObjDestroy(key); + HcfObjDestroy(generator); +} + } \ No newline at end of file diff --git a/test/unittest/src/crypto_rsa_only_sign_and_verify_recover_test.cpp b/test/unittest/src/crypto_rsa_only_sign_and_verify_recover_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c50c7a379fbb0fb9a8b0e1b36a94a62d9d7383a4 --- /dev/null +++ b/test/unittest/src/crypto_rsa_only_sign_and_verify_recover_test.cpp @@ -0,0 +1,760 @@ +/* + * 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 "cstring" +#include "securec.h" +#include "asy_key_generator.h" +#include "blob.h" +#include "detailed_rsa_key_params.h" +#include "memory.h" +#include "openssl_common.h" +#include "md.h" +#include "signature.h" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoRsaOnlySignAndVerifyRecoverTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoRsaOnlySignAndVerifyRecoverTest::SetUp() {} +void CryptoRsaOnlySignAndVerifyRecoverTest::TearDown() {} +void CryptoRsaOnlySignAndVerifyRecoverTest::SetUpTestCase() {} +void CryptoRsaOnlySignAndVerifyRecoverTest::TearDownTestCase() {} + +static void RsaOnlySignCreateTest(const char *algoName) +{ + HcfResult res = HCF_SUCCESS; + HcfSign *sign = nullptr; + res = HcfSignCreate(algoName, &sign); + EXPECT_EQ(res, HCF_SUCCESS); + EXPECT_NE(sign, nullptr); + EXPECT_NE(sign->base.getClass(), nullptr); + EXPECT_NE(sign->base.destroy, nullptr); + EXPECT_NE(sign->init, nullptr); + EXPECT_NE(sign->update, nullptr); + EXPECT_NE(sign->sign, nullptr); + HcfObjDestroy(sign); +} + +static void RsaOnlySignCreateIncorrectTest(const char *algoName, HcfResult ret) +{ + HcfResult res = HCF_SUCCESS; + HcfSign *sign = nullptr; + res = HcfSignCreate(algoName, &sign); + EXPECT_EQ(res, ret); + EXPECT_EQ(sign, nullptr); +} + +static void RsaOnlySignTest(const char *keyAlgoName, const char *algoName, const char *plan) +{ + HcfResult res = HCF_SUCCESS; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate(keyAlgoName, &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen(plan)}; + HcfBlob verifyData = {.data = nullptr, .len = 0}; + HcfSign *sign = nullptr; + res = HcfSignCreate(algoName, &sign); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, &input, &verifyData); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfObjDestroy(sign); + HcfFree(verifyData.data); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +static void RsaOnlySignIncorrectTest(const char *keyAlgoName, const char *algoName, const char *plan) +{ + HcfResult res = HCF_SUCCESS; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate(keyAlgoName, &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen(plan)}; + HcfBlob verifyData = {.data = nullptr, .len = 0}; + HcfSign *sign = nullptr; + res = HcfSignCreate(algoName, &sign); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, &input, &verifyData); + EXPECT_EQ(res, HCF_ERR_CRYPTO_OPERATION); + + HcfObjDestroy(sign); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// HcfSignCreate OnlySign correct_case +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest100, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA512|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA512|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA512|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA512|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA512|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA512|PKCS1|SHA384|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest110, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA768|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA768|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest120, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA1024|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA1024|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest130, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA2048|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA2048|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest140, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA3072|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA3072|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest150, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA4096|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA4096|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest160, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA8192|PKCS1|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|MD5|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|SHA1|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|SHA224|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|SHA256|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|SHA384|OnlySign"); + RsaOnlySignCreateTest("RSA8192|PKCS1|SHA512|OnlySign"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest170, TestSize.Level0) +{ + RsaOnlySignCreateTest("RSA512|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA768|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA1024|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA2048|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA3072|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA4096|NoPadding|NoHash|OnlySign"); + RsaOnlySignCreateTest("RSA8192|NoPadding|NoHash|OnlySign"); +} + +// HcfSignCreate OnlySign Incorrect case +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest180, TestSize.Level0) +{ + RsaOnlySignCreateIncorrectTest("RSA1024aa|PKCS1|SHA256|OnlySign", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("RSA1024|PKCS1aa|SHA256|OnlySign", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("RSA1024|PKCS1|SHA256aa|OnlySign", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("RSA1024|PKCS1|SHA256|OnlySignaa", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("RSA1024|PKCS1|SHA256|123123123123123123212312312321" + "123123123123213asdasdasdasdasdasdasdasdasdasdasdasdasdsasdasds12|OnlySign", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("RSA1024|PSS|SHA256|MGF1_SHA256|OnlySign", HCF_INVALID_PARAMS); + RsaOnlySignCreateIncorrectTest("DSA1024|PKCS1|SHA256|OnlySign", HCF_NOT_SUPPORT); +} + +// incorrect case : OnlySign init signer with nullptr private key. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest270, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|NoHash|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + + res = sign->init(sign, nullptr, nullptr); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); +} + +// incorrect case : OnlySign init signer with public Key. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest280, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|NoHash|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPubKey *pubKey = keyPair->pubKey; + + res = sign->init(sign, nullptr, (HcfPriKey *)pubKey); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); + HcfObjDestroy(generator); + HcfObjDestroy(keyPair); +} + +// incorrect case : OnlySign use update function. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest290, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|NoHash|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + uint8_t plan[] = "this is rsa verify test."; + HcfBlob input = {.data = plan, .len = strlen((char *)plan)}; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->update(sign, &input); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// incorrect case : use OnlySign sign function before intialize. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest291, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|NoHash|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + + uint8_t plan[] = "this is rsa verify test."; + HcfBlob input = {.data = plan, .len = strlen((char *)plan)}; + HcfBlob signatureData = {.data = nullptr, .len = 0}; + res = sign->sign(sign, &input, &signatureData); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); +} + +// incorrect case : OnlySign sign with nullptr outputBlob. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest292, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|NoHash|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, nullptr, nullptr); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// correct case: OnlySign init and sign +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest300, TestSize.Level0) +{ + RsaOnlySignTest("RSA512|PRIMES_2", "RSA512|PKCS1|NoHash|OnlySign", "01234567890123456789"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|NoHash|OnlySign", "01234567890123456789"); + RsaOnlySignTest("RSA2048|PRIMES_2", "RSA2048|PKCS1|NoHash|OnlySign", "01234567890123456789"); + RsaOnlySignTest("RSA4096|PRIMES_2", "RSA4096|PKCS1|NoHash|OnlySign", "01234567890123456789"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest310, TestSize.Level0) +{ + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|NoPadding|NoHash|OnlySign", + "0123456789012345678901234567890123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789012345678901234567"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest320, TestSize.Level0) +{ + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|MD5|OnlySign", "0123456789012345"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA1|OnlySign", "01234567890123456789"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA224|OnlySign", + "0123456789012345678901234567"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA256|OnlySign", + "01234567890123456789012345678901"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA384|OnlySign", + "012345678901234567890123456789012345678901234567"); + RsaOnlySignTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA512|OnlySign", + "0123456789012345678901234567890123456789012345678901234567890123"); +} + +// incorrect case: OnlySign init and sign +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest330, TestSize.Level0) +{ + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|MD5|OnlySign", "012345678901234"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|MD5|OnlySign", "01234567890123456"); + + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA1|OnlySign", "0123456789012345678"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA1|OnlySign", "012345678901234567890"); + + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA224|OnlySign", + "012345678901234567890123456"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA224|OnlySign", + "01234567890123456789012345678"); + + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA256|OnlySign", + "0123456789012345678901234567890"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA256|OnlySign", + "012345678901234567890123456789012"); + + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA384|OnlySign", + "01234567890123456789012345678901234567890123456"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA384|OnlySign", + "0123456789012345678901234567890123456789012345678"); + + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA512|OnlySign", + "012345678901234567890123456789012345678901234567890123456789012"); + RsaOnlySignIncorrectTest("RSA1024|PRIMES_2", "RSA1024|PKCS1|SHA512|OnlySign", + "01234567890123456789012345678901234567890123456789012345678901234"); +} + +// incorrect case: OnlySign double init sign +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaOnlySignTest500, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfResult res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|SHA512|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(sign); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +static void CryptoRsaVerifyRecoverCreateTest(const char *algoName) +{ + HcfResult res = HCF_SUCCESS; + HcfVerify *verify = nullptr; + res = HcfVerifyCreate(algoName, &verify); + EXPECT_EQ(res, HCF_SUCCESS); + EXPECT_NE(verify, nullptr); + EXPECT_NE(verify->base.getClass(), nullptr); + EXPECT_NE(verify->base.destroy, nullptr); + EXPECT_NE(verify->init, nullptr); + EXPECT_NE(verify->update, nullptr); + EXPECT_NE(verify->verify, nullptr); + EXPECT_NE(verify->recover, nullptr); + HcfObjDestroy(verify); +} + +static void RsaVerifyRecoverIncorrectTest(const char *algoName, HcfResult ret) +{ + HcfResult res = HCF_SUCCESS; + HcfVerify *verify = nullptr; + res = HcfVerifyCreate(algoName, &verify); + EXPECT_EQ(res, ret); + EXPECT_EQ(verify, nullptr); +} + +// HcfVerifyCreate Recover correct_case +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest100, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA512|PKCS1|SHA384|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest110, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest120, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest130, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest140, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest150, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest160, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|MD5|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|SHA1|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|SHA224|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|SHA256|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|SHA384|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|PKCS1|SHA512|Recover"); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest170, TestSize.Level0) +{ + CryptoRsaVerifyRecoverCreateTest("RSA512|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA768|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA1024|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA2048|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA3072|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA4096|NoPadding|NoHash|Recover"); + CryptoRsaVerifyRecoverCreateTest("RSA8192|NoPadding|NoHash|Recover"); +} + +// HcfVerifyCreate OnlySign Incorrect case +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest180, TestSize.Level0) +{ + RsaVerifyRecoverIncorrectTest("RSA1024aa|PKCS1|SHA256|Recover", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("RSA1024|PKCS1aa|SHA256|Recover", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("RSA1024|PKCS1|SHA256aa|Recover", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("RSA1024|PKCS1|SHA256|Recoveraa", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("RSA1024|PKCS1|SHA256|123123123123123123212312312321" + "123123123123213asdasdasdasdasdasdasdasdasdasdasdasdasdsasdasds12|Recover", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("RSA1024|PSS|SHA256|MGF1_SHA256|Recover", HCF_INVALID_PARAMS); + RsaVerifyRecoverIncorrectTest("DSA1024|PKCS1|SHA256|Recover", HCF_NOT_SUPPORT); +} + +// incorrect case : Recover init signer with nullptr public key. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest270, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|NoHash|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + + res = verify->init(verify, nullptr, nullptr); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(verify); +} + +// incorrect case : Recover init verifyer with private Key. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest280, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|NoHash|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *priKey = keyPair->priKey; + + res = verify->init(verify, nullptr, (HcfPubKey *)priKey); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(verify); + HcfObjDestroy(generator); + HcfObjDestroy(keyPair); +} + +// incorrect case : use Recover recover function before intialize. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest291, TestSize.Level0) +{ + uint8_t plan[] = "01234567890123456789012345678901"; + HcfAsyKeyGenerator *generator = nullptr; + int32_t res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPriKey *prikey = keyPair->priKey; + + HcfBlob input = {.data = plan, .len = strlen((char *)plan)}; + HcfBlob verifyData = {.data = nullptr, .len = 0}; + HcfBlob rawSignatureData = {.data = nullptr, .len = 0}; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|SHA256|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, &input, &verifyData); + EXPECT_EQ(res, HCF_SUCCESS); + HcfObjDestroy(sign); + + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|SHA256|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->recover(verify, &verifyData, &rawSignatureData); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(verify); + HcfFree(verifyData.data); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// incorrect case : Recover recover with nullptr outputBlob. +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest292, TestSize.Level0) +{ + HcfResult res = HCF_SUCCESS; + HcfAsyKeyGenerator *generator = nullptr; + res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPubKey *pubkey = keyPair->pubKey; + + HcfBlob rawSignatureData = {.data = nullptr, .len = 0}; + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|SHA256|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->init(verify, nullptr, pubkey); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->recover(verify, nullptr, &rawSignatureData); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(verify); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// incorrect case: recover double init verify +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest293, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfResult res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPubKey *pubkey = keyPair->pubKey; + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|SHA256|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + + res = verify->init(verify, nullptr, pubkey); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->init(verify, nullptr, pubkey); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + + HcfObjDestroy(verify); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +// correct case : sign and recover +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest300, TestSize.Level0) +{ + uint8_t plan[] = "01234567890123456789012345678901"; + HcfAsyKeyGenerator *generator = nullptr; + int32_t res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPubKey *pubkey = keyPair->pubKey; + HcfPriKey *prikey = keyPair->priKey; + + HcfBlob input = {.data = plan, .len = strlen((char *)plan)}; + HcfBlob verifyData = {.data = nullptr, .len = 0}; + HcfBlob rawSignatureData = {.data = nullptr, .len = 0}; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|SHA256|OnlySign", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, &input, &verifyData); + EXPECT_EQ(res, HCF_SUCCESS); + HcfObjDestroy(sign); + + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|SHA256|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->init(verify, nullptr, pubkey); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->recover(verify, &verifyData, &rawSignatureData); + EXPECT_EQ(res, HCF_SUCCESS); + HcfObjDestroy(verify); + int resCmp = memcmp(input.data, rawSignatureData.data, rawSignatureData.len); + EXPECT_EQ(resCmp, HCF_SUCCESS); + + HcfFree(verifyData.data); + HcfFree(rawSignatureData.data); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoRsaOnlySignAndVerifyRecoverTest, CryptoRsaVerifyRecoverTest310, TestSize.Level0) +{ + uint8_t plan[] = "01234567890123456789012345678901"; + HcfAsyKeyGenerator *generator = nullptr; + int32_t res = HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_2", &generator); + + HcfKeyPair *keyPair = nullptr; + res = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(res, HCF_SUCCESS); + + HcfPubKey *pubkey = keyPair->pubKey; + HcfPriKey *prikey = keyPair->priKey; + + HcfBlob input = {.data = plan, .len = strlen((char *)plan)}; + HcfBlob verifyData = {.data = nullptr, .len = 0}; + HcfBlob rawSignatureData = {.data = nullptr, .len = 0}; + HcfSign *sign = nullptr; + res = HcfSignCreate("RSA1024|PKCS1|SHA256", &sign); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->init(sign, nullptr, prikey); + EXPECT_EQ(res, HCF_SUCCESS); + res = sign->sign(sign, &input, &verifyData); + EXPECT_EQ(res, HCF_SUCCESS); + HcfObjDestroy(sign); + + HcfVerify *verify = nullptr; + res = HcfVerifyCreate("RSA1024|PKCS1|SHA256|Recover", &verify); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->init(verify, nullptr, pubkey); + EXPECT_EQ(res, HCF_SUCCESS); + res = verify->recover(verify, &verifyData, &rawSignatureData); + EXPECT_EQ(res, HCF_SUCCESS); + HcfObjDestroy(verify); + + uint32_t SHA256_LEN = 32; + HcfMd *mdObj = nullptr; + HcfResult ret = HcfMdCreate("SHA256", &mdObj); + ASSERT_EQ(ret, HCF_SUCCESS); + struct HcfBlob outBlob = { .data = nullptr, .len = 0 }; + ret = mdObj->update(mdObj, &input); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = mdObj->doFinal(mdObj, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + uint32_t len = mdObj->getMdLength(mdObj); + EXPECT_EQ(len, SHA256_LEN); + + int resCmp = memcmp(outBlob.data, rawSignatureData.data, rawSignatureData.len); + EXPECT_EQ(resCmp, HCF_SUCCESS); + + HcfObjDestroy(mdObj); + HcfFree(verifyData.data); + HcfFree(rawSignatureData.data); + HcfBlobDataClearAndFree(&outBlob); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} +} diff --git a/test/unittest/src/crypto_sm2_cipher_test.cpp b/test/unittest/src/crypto_sm2_cipher_test.cpp index 836b0dd255cd7990e7941d920fe4f1e531090a4e..3c4ad1e1f2cdbad4d5adba3987c37612646a1944 100644 --- a/test/unittest/src/crypto_sm2_cipher_test.cpp +++ b/test/unittest/src/crypto_sm2_cipher_test.cpp @@ -312,7 +312,7 @@ HWTEST_F(CryptoSm2CipherTest, CryptoSm2CipherTest015, TestSize.Level0) res = generator->generateKeyPair(generator, nullptr, &keyPair); EXPECT_EQ(res, HCF_SUCCESS); - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; HcfBlob encoutput = {.data = nullptr, .len = 0}; HcfCipher *cipher = nullptr; res = HcfCipherCreate("SM2|SM3", &cipher); @@ -343,7 +343,7 @@ HWTEST_F(CryptoSm2CipherTest, CryptoSm2CipherTest016, TestSize.Level0) EXPECT_NE(keyPair->priKey, nullptr); EXPECT_NE(keyPair->pubKey, nullptr); - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; HcfBlob encoutput = {.data = nullptr, .len = 0}; HcfCipher *cipher = nullptr; res = HcfCipherCreate("SM2|SM3", &cipher); @@ -399,7 +399,7 @@ HWTEST_F(CryptoSm2CipherTest, CryptoSm2CipherTest017, TestSize.Level0) HcfObjDestroy(generator); HcfObjDestroy(keyPair); - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; HcfBlob encoutput = {.data = nullptr, .len = 0}; HcfCipher *cipher = nullptr; res = HcfCipherCreate("SM2|SM3", &cipher); @@ -633,7 +633,7 @@ HWTEST_F(CryptoSm2CipherTest, CryptoSm2CipherTest026, TestSize.Level0) HcfCipher *cipher = nullptr; res = HcfCipherCreate("SM2|SM3", &cipher); EXPECT_EQ(res, HCF_SUCCESS); - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; res = cipher->init(cipher, ENCRYPT_MODE, (HcfKey *)keyPair->pubKey, nullptr); EXPECT_EQ(res, HCF_SUCCESS); res = cipher->doFinal(nullptr, &input, &encoutput); @@ -1179,7 +1179,7 @@ HWTEST_F(CryptoSm2CipherTest, CryptoSm2CipherTest058, TestSize.Level0) EXPECT_NE(keyPair->priKey, nullptr); EXPECT_NE(keyPair->pubKey, nullptr); - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; HcfBlob encoutput = {.data = nullptr, .len = 0}; HcfCipherGeneratorSpi *cipher = nullptr; CipherAttr params = { diff --git a/test/unittest/src/ecc/crypto_ecc_ecdh_pub_test.cpp b/test/unittest/src/ecc/crypto_ecc_ecdh_pub_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a6bbf87fe504419f94ebc5c46896205fa5135a7 --- /dev/null +++ b/test/unittest/src/ecc/crypto_ecc_ecdh_pub_test.cpp @@ -0,0 +1,1914 @@ +/* + * 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 "securec.h" + +#include "asy_key_generator.h" +#include "blob.h" +#include "detailed_ecc_key_params.h" +#include "ecc_key_util.h" +#include "ecc_common_param_spec_generator_openssl.h" +#include "key_agreement.h" +#include "memory.h" +#include "signature.h" +#include "openssl_class.h" + + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoEccEcdhPubTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoEccEcdhPubTest::SetUpTestCase() {} + +void CryptoEccEcdhPubTest::TearDownTestCase() {} + +void CryptoEccEcdhPubTest::SetUp() {} + +void CryptoEccEcdhPubTest::TearDown() {} + +static const char *PUB_KEY_COMPRESSED_FORMAT = "X509|COMPRESSED"; +static const char *PUB_KEY_UNCOMPRESSED_FORMAT = "X509|UNCOMPRESSED"; +static const char *POINT_COMPRESSED_FORMAT = "COMPRESSED"; +static const char *POINT_UNCOMPRESSED_FORMAT = "UNCOMPRESSED"; + +// uncompressed point data size +constexpr size_t SECP224R1_POINT_UNCOMPRESSED_SIZE = 57; +constexpr size_t PRIME256V1_POINT_UNCOMPRESSED_SIZE = 65; +constexpr size_t SECP384R1_POINT_UNCOMPRESSED_SIZE = 97; +constexpr size_t SECP521R1_POINT_UNCOMPRESSED_SIZE = 133; +constexpr size_t P160R1_POINT_UNCOMPRESSED_SIZE = 41; +constexpr size_t P160T1_POINT_UNCOMPRESSED_SIZE = 41; +constexpr size_t P192R1_POINT_UNCOMPRESSED_SIZE = 49; +constexpr size_t P192T1_POINT_UNCOMPRESSED_SIZE = 49; +constexpr size_t P224R1_POINT_UNCOMPRESSED_SIZE = 57; +constexpr size_t P224T1_POINT_UNCOMPRESSED_SIZE = 57; +constexpr size_t P256R1_POINT_UNCOMPRESSED_SIZE = 65; +constexpr size_t P256T1_POINT_UNCOMPRESSED_SIZE = 65; +constexpr size_t P320R1_POINT_UNCOMPRESSED_SIZE = 81; +constexpr size_t P320T1_POINT_UNCOMPRESSED_SIZE = 81; +constexpr size_t P384R1_POINT_UNCOMPRESSED_SIZE = 97; +constexpr size_t P384T1_POINT_UNCOMPRESSED_SIZE = 97; +constexpr size_t P512R1_POINT_UNCOMPRESSED_SIZE = 129; +constexpr size_t P512T1_POINT_UNCOMPRESSED_SIZE = 129; + +// uncompressed point data +static uint8_t g_secp224r1PointUncompressedBlobData[] = { 4, 56, 90, 25, 144, 206, 229, 109, 59, 65, 62, 249, 113, + 247, 239, 20, 63, 107, 72, 217, 43, 12, 124, 241, 209, 32, 66, 134, 239, 169, 154, 59, 182, 106, 163, 190, + 214, 232, 213, 73, 97, 57, 163, 137, 66, 59, 238, 12, 142, 87, 37, 182, 22, 60, 106, 235, 237 }; + +static uint8_t g_prime256v1PointUncompressedBlobData[] = { 4, 153, 228, 156, 119, 184, 185, 120, 237, 233, 181, + 77, 70, 183, 30, 68, 2, 70, 37, 251, 5, 22, 199, 84, 87, 222, 65, 103, 8, 26, 255, 137, 206, 80, 159, 163, + 46, 22, 104, 156, 169, 14, 149, 199, 35, 201, 3, 160, 81, 251, 235, 236, 75, 137, 196, 253, 200, 116, 167, + 59, 153, 241, 99, 90, 90 }; + +static uint8_t g_secp384r1PointUncompressedBlobData[] = { 4, 246, 157, 255, 226, 94, 109, 16, 243, 109, 34, 121, + 62, 12, 160, 181, 60, 89, 27, 60, 236, 118, 93, 113, 123, 64, 220, 231, 248, 113, 220, 130, 75, 164, 174, 128, + 84, 135, 212, 122, 99, 97, 167, 89, 56, 162, 60, 50, 185, 154, 231, 102, 187, 58, 105, 237, 215, 53, 88, 253, + 33, 45, 36, 25, 176, 112, 110, 132, 39, 33, 56, 224, 21, 225, 8, 108, 81, 106, 157, 33, 210, 105, 138, 130, 163, + 96, 112, 183, 179, 241, 25, 188, 121, 68, 180, 169, 149 }; + +static uint8_t g_secp521r1PointUncompressedBlobData[] = { 4, 0, 234, 87, 65, 173, 170, 194, 156, 174, 174, + 229, 236, 236, 195, 107, 24, 24, 169, 187, 160, 28, 11, 239, 70, 163, 131, 233, 157, 104, 41, 202, 208, + 166, 209, 217, 39, 225, 163, 33, 17, 134, 48, 150, 111, 225, 193, 219, 232, 234, 117, 100, 27, 169, 172, + 60, 186, 69, 246, 244, 218, 249, 188, 96, 49, 247, 125, 0, 70, 67, 187, 0, 72, 109, 99, 50, 173, 42, 250, + 10, 89, 166, 85, 64, 28, 145, 30, 130, 174, 147, 22, 232, 37, 17, 158, 165, 178, 11, 34, 58, 98, 98, 43, 32, + 146, 102, 178, 198, 176, 41, 150, 37, 43, 132, 232, 32, 98, 143, 125, 255, 173, 158, 227, 4, 238, 168, 113, + 194, 162, 74, 234, 239, 102 }; + +static uint8_t g_p160r1PointUncompressedBlobData[] = { 4, 162, 100, 90, 91, 16, 253, 183, 186, 164, 222, 247, + 223, 75, 228, 92, 253, 253, 250, 38, 30, 125, 172, 62, 13, 109, 61, 63, 160, 20, 103, 94, 7, 68, 115, 202, + 170, 157, 244, 174, 26 }; + +static uint8_t g_p160t1PointUncompressedBlobData[] = { 4, 73, 116, 114, 251, 6, 125, 11, 84, 159, 140, 0, 164, + 101, 40, 147, 227, 28, 143, 224, 160, 217, 185, 12, 197, 39, 34, 91, 119, 135, 123, 80, 45, 26, 156, 221, + 2, 79, 242, 45, 24 }; + +static uint8_t g_p192r1PointUncompressedBlobData[] = { 4, 72, 15, 250, 255, 107, 128, 70, 56, 144, 154, 23, + 141, 54, 19, 255, 134, 235, 12, 187, 128, 121, 41, 255, 141, 69, 81, 100, 94, 238, 15, 166, 184, 1, 214, + 220, 222, 12, 239, 145, 184, 143, 146, 165, 9, 107, 74, 199, 1 }; + +static uint8_t g_p192t1PointUncompressedBlobData[] = { 4, 131, 174, 50, 196, 198, 2, 164, 255, 193, 233, 237, 217, + 47, 191, 35, 6, 166, 69, 42, 38, 128, 134, 29, 97, 23, 242, 82, 96, 164, 135, 108, 120, 179, 105, 10, 32, 90, + 152, 99, 10, 2, 220, 184, 207, 8, 65, 168, 95 }; + +static uint8_t g_p224r1PointUncompressedBlobData[] = { 4, 179, 154, 82, 152, 164, 40, 37, 88, 133, 242, 75, 160, + 244, 155, 186, 103, 163, 44, 100, 137, 114, 124, 28, 27, 187, 99, 235, 123, 46, 127, 137, 234, 188, 6, 91, 68, + 250, 89, 231, 62, 179, 47, 119, 221, 5, 73, 128, 12, 241, 57, 101, 15, 9, 95, 11, 101 }; + +static uint8_t g_p224t1PointUncompressedBlobData[] = { 4, 187, 42, 38, 78, 26, 235, 23, 233, 222, 133, 167, 236, + 86, 95, 104, 44, 160, 133, 41, 92, 214, 174, 194, 43, 214, 123, 12, 188, 210, 117, 152, 50, 0, 136, 6, 92, 57, + 236, 246, 150, 145, 249, 150, 185, 255, 116, 28, 111, 22, 173, 25, 205, 96, 251, 61, 238 }; + +static uint8_t g_p256r1PointUncompressedBlobData[] = { 4, 0, 181, 254, 30, 31, 239, 138, 26, 134, 97, 46, 250, 9, 142, + 148, 201, 217, 224, 223, 68, 54, 180, 157, 30, 98, 140, 81, 237, 29, 242, 108, 3, 100, 127, 165, 176, 53, 73, 197, + 151, 79, 219, 204, 98, 116, 71, 97, 1, 127, 216, 38, 84, 18, 157, 250, 240, 109, 251, 105, 243, 73, 17, 153, 138 }; + +static uint8_t g_p256t1PointUncompressedBlobData[] = { 4, 134, 165, 93, 7, 187, 30, 225, 62, 157, 177, 229, 63, 104, + 217, 148, 68, 85, 152, 34, 185, 100, 81, 111, 233, 193, 108, 198, 74, 37, 188, 46, 19, 136, 157, 88, 166, 194, + 167, 157, 163, 173, 69, 7, 153, 48, 246, 3, 54, 127, 113, 145, 17, 128, 250, 210, 218, 249, 150, 249, 243, 178, + 136, 112, 192 }; + +static uint8_t g_p320r1PointUncompressedBlobData[] = { 4, 117, 229, 73, 102, 77, 218, 200, 35, 245, 163, 23, 219, + 50, 180, 7, 60, 219, 87, 135, 67, 214, 34, 71, 1, 75, 227, 143, 253, 203, 40, 246, 249, 210, 64, 255, 186, 202, + 161, 214, 203, 91, 159, 114, 252, 134, 230, 86, 188, 103, 223, 217, 12, 238, 118, 6, 232, 161, 198, 195, 139, 62, + 36, 98, 212, 129, 215, 178, 83, 137, 164, 95, 239, 238, 216, 222, 125, 246, 105, 66, 164 }; + +static uint8_t g_p320t1PointUncompressedBlobData[] = { 4, 188, 215, 24, 76, 167, 218, 220, 193, 3, 105, 145, 175, + 125, 17, 15, 227, 69, 120, 196, 97, 151, 3, 116, 23, 83, 71, 204, 133, 13, 225, 88, 31, 11, 168, 66, 57, 64, 233, + 125, 156, 12, 28, 241, 242, 224, 110, 133, 157, 230, 106, 16, 126, 66, 37, 8, 235, 230, 90, 20, 253, 2, 223, 157, + 135, 71, 161, 64, 111, 50, 212, 125, 187, 44, 181, 211, 76, 217, 53, 94, 162 }; + +static uint8_t g_p384r1PointUncompressedBlobData[] = { 4, 24, 149, 106, 30, 33, 152, 247, 126, 23, 231, 139, 197, + 240, 145, 3, 6, 38, 168, 157, 60, 153, 95, 41, 184, 110, 135, 222, 237, 86, 132, 255, 180, 245, 49, 41, 3, 223, + 122, 210, 203, 213, 55, 108, 251, 65, 181, 168, 25, 69, 50, 124, 233, 124, 121, 89, 187, 238, 186, 163, 169, 88, + 48, 7, 108, 206, 228, 141, 162, 127, 232, 67, 175, 95, 220, 178, 28, 152, 254, 148, 123, 46, 132, 222, 124, 11, + 51, 152, 113, 44, 14, 222, 126, 142, 114, 10, 124 }; + +static uint8_t g_p384t1PointUncompressedBlobData[] = { 4, 64, 192, 12, 47, 160, 35, 23, 244, 163, 108, 172, 235, + 185, 100, 0, 180, 112, 85, 105, 29, 120, 105, 164, 148, 59, 168, 183, 168, 142, 141, 14, 121, 240, 132, 168, 4, + 208, 142, 24, 226, 75, 169, 249, 46, 63, 61, 129, 154, 41, 6, 34, 81, 246, 230, 4, 227, 103, 106, 107, 216, 130, + 58, 248, 156, 101, 96, 85, 109, 43, 233, 229, 96, 165, 188, 222, 226, 113, 17, 213, 194, 57, 142, 117, 129, 151, + 187, 235, 43, 253, 132, 151, 96, 49, 85, 37, 101 }; + +static uint8_t g_p512r1PointUncompressedBlobData[] = { 4, 18, 25, 192, 69, 115, 54, 110, 174, 51, 48, 253, 129, 31, + 118, 237, 38, 1, 174, 8, 111, 74, 249, 149, 154, 119, 114, 59, 51, 160, 206, 70, 199, 202, 42, 98, 245, 170, 251, + 154, 22, 243, 137, 182, 239, 219, 166, 28, 202, 183, 229, 2, 83, 16, 244, 211, 100, 30, 179, 251, 17, 52, 117, 55, + 70, 114, 203, 60, 190, 163, 132, 156, 63, 246, 140, 173, 122, 80, 68, 155, 60, 74, 199, 248, 71, 134, 52, 228, 28, + 122, 72, 100, 26, 36, 148, 20, 187, 59, 137, 98, 191, 165, 174, 43, 2, 68, 222, 184, 34, 108, 8, 155, 150, 12, + 101, 120, 155, 164, 200, 52, 206, 240, 116, 158, 207, 180, 124, 210, 62 }; + +static uint8_t g_p512t1PointUncompressedBlobData[] = { 4, 119, 56, 81, 46, 40, 173, 156, 49, 235, 26, 193, 122, 32, + 201, 88, 18, 90, 55, 144, 84, 125, 90, 106, 169, 66, 124, 90, 44, 145, 100, 224, 192, 22, 241, 38, 185, 93, 163, + 146, 221, 126, 222, 57, 95, 136, 139, 231, 85, 250, 133, 140, 81, 138, 66, 148, 253, 192, 217, 210, 33, 157, 60, + 5, 113, 151, 65, 106, 113, 44, 250, 237, 139, 172, 190, 154, 142, 17, 77, 228, 232, 223, 31, 208, 83, 231, 120, + 127, 36, 129, 82, 186, 219, 207, 87, 130, 231, 224, 111, 210, 88, 19, 147, 0, 37, 194, 9, 217, 191, 162, 77, + 165, 32, 78, 141, 227, 44, 70, 156, 13, 250, 36, 93, 226, 178, 165, 61, 33, 63 }; + +static HcfBlob g_secp224r1PointUncompressedBlob = { + .data = g_secp224r1PointUncompressedBlobData, + .len = SECP224R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_prime256v1PointUncompressedBlob = { + .data = g_prime256v1PointUncompressedBlobData, + .len = PRIME256V1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_secp384r1PointUncompressedBlob = { + .data = g_secp384r1PointUncompressedBlobData, + .len = SECP384R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_secp521r1PointUncompressedBlob = { + .data = g_secp521r1PointUncompressedBlobData, + .len = SECP521R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p160r1PointUncompressedBlob = { + .data = g_p160r1PointUncompressedBlobData, + .len = P160R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p160t1PointUncompressedBlob = { + .data = g_p160t1PointUncompressedBlobData, + .len = P160T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p192r1PointUncompressedBlob = { + .data = g_p192r1PointUncompressedBlobData, + .len = P192R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p192t1PointUncompressedBlob = { + .data = g_p192t1PointUncompressedBlobData, + .len = P192T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p224r1PointUncompressedBlob = { + .data = g_p224r1PointUncompressedBlobData, + .len = P224R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p224t1PointUncompressedBlob = { + .data = g_p224t1PointUncompressedBlobData, + .len = P224T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p256r1PointUncompressedBlob = { + .data = g_p256r1PointUncompressedBlobData, + .len = P256R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p256t1PointUncompressedBlob = { + .data = g_p256t1PointUncompressedBlobData, + .len = P256T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p320r1PointUncompressedBlob = { + .data = g_p320r1PointUncompressedBlobData, + .len = P320R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p320t1PointUncompressedBlob = { + .data = g_p320t1PointUncompressedBlobData, + .len = P320T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p384r1PointUncompressedBlob = { + .data = g_p384r1PointUncompressedBlobData, + .len = P384R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p384t1PointUncompressedBlob = { + .data = g_p384t1PointUncompressedBlobData, + .len = P384T1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p512r1PointUncompressedBlob = { + .data = g_p512r1PointUncompressedBlobData, + .len = P512R1_POINT_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p512t1PointUncompressedBlob = { + .data = g_p512t1PointUncompressedBlobData, + .len = P512T1_POINT_UNCOMPRESSED_SIZE +}; + +// compressed point data size +constexpr size_t SECP224R1_POINT_COMPRESSED_SIZE = 29; +constexpr size_t PRIME256V1_POINT_COMPRESSED_SIZE = 33; +constexpr size_t SECP384R1_POINT_COMPRESSED_SIZE = 49; +constexpr size_t SECP521R1_POINT_COMPRESSED_SIZE = 67; +constexpr size_t P160R1_POINT_COMPRESSED_SIZE = 21; +constexpr size_t P160T1_POINT_COMPRESSED_SIZE = 21; +constexpr size_t P192R1_POINT_COMPRESSED_SIZE = 25; +constexpr size_t P192T1_POINT_COMPRESSED_SIZE = 25; +constexpr size_t P224R1_POINT_COMPRESSED_SIZE = 29; +constexpr size_t P224T1_POINT_COMPRESSED_SIZE = 29; +constexpr size_t P256R1_POINT_COMPRESSED_SIZE = 33; +constexpr size_t P256T1_POINT_COMPRESSED_SIZE = 33; +constexpr size_t P320R1_POINT_COMPRESSED_SIZE = 41; +constexpr size_t P320T1_POINT_COMPRESSED_SIZE = 41; +constexpr size_t P384R1_POINT_COMPRESSED_SIZE = 49; +constexpr size_t P384T1_POINT_COMPRESSED_SIZE = 49; +constexpr size_t P512R1_POINT_COMPRESSED_SIZE = 65; +constexpr size_t P512T1_POINT_COMPRESSED_SIZE = 65; + +// compressed point data +static uint8_t g_secp224r1PointCompressedBlobData[] = { 3, 56, 90, 25, 144, 206, 229, 109, 59, 65, 62, 249, 113, + 247, 239, 20, 63, 107, 72, 217, 43, 12, 124, 241, 209, 32, 66, 134, 239 }; + +static uint8_t g_prime256v1PointCompressedBlobData[] = { 2, 153, 228, 156, 119, 184, 185, 120, 237, 233, 181, 77, + 70, 183, 30, 68, 2, 70, 37, 251, 5, 22, 199, 84, 87, 222, 65, 103, 8, 26, 255, 137, 206 }; + +static uint8_t g_secp384r1PointCompressedBlobData[] = { 3, 246, 157, 255, 226, 94, 109, 16, 243, 109, 34, 121, 62, + 12, 160, 181, 60, 89, 27, 60, 236, 118, 93, 113, 123, 64, 220, 231, 248, 113, 220, 130, 75, 164, 174, 128, + 84, 135, 212, 122, 99, 97, 167, 89, 56, 162, 60, 50, 185 }; + +static uint8_t g_secp521r1PointCompressedBlobData[] = { 2, 0, 234, 87, 65, 173, 170, 194, 156, 174, 174, 229, 236, + 236, 195, 107, 24, 24, 169, 187, 160, 28, 11, 239, 70, 163, 131, 233, 157, 104, 41, 202, 208, 166, 209, 217, 39, + 225, 163, 33, 17, 134, 48, 150, 111, 225, 193, 219, 232, 234, 117, 100, 27, 169, 172, 60, 186, 69, 246, 244, 218, + 249, 188, 96, 49, 247, 125 }; + +static uint8_t g_p160r1PointCompressedBlobData[] = { 2, 162, 100, 90, 91, 16, 253, 183, 186, 164, 222, 247, 223, + 75, 228, 92, 253, 253, 250, 38, 30 }; + +static uint8_t g_p160t1PointCompressedBlobData[] = { 2, 73, 116, 114, 251, 6, 125, 11, 84, 159, 140, 0, 164, 101, + 40, 147, 227, 28, 143, 224, 160 }; + +static uint8_t g_p192r1PointCompressedBlobData[] = { 3, 72, 15, 250, 255, 107, 128, 70, 56, 144, 154, 23, 141, 54, + 19, 255, 134, 235, 12, 187, 128, 121, 41, 255, 141 }; + +static uint8_t g_p192t1PointCompressedBlobData[] = { 3, 131, 174, 50, 196, 198, 2, 164, 255, 193, 233, 237, 217, 47, + 191, 35, 6, 166, 69, 42, 38, 128, 134, 29, 97 }; + +static uint8_t g_p224r1PointCompressedBlobData[] = { 3, 179, 154, 82, 152, 164, 40, 37, 88, 133, 242, 75, 160, 244, + 155, 186, 103, 163, 44, 100, 137, 114, 124, 28, 27, 187, 99, 235, 123 }; + +static uint8_t g_p224t1PointCompressedBlobData[] = { 2, 187, 42, 38, 78, 26, 235, 23, 233, 222, 133, 167, 236, 86, + 95, 104, 44, 160, 133, 41, 92, 214, 174, 194, 43, 214, 123, 12, 188 }; + +static uint8_t g_p256r1PointCompressedBlobData[] = { 2, 0, 181, 254, 30, 31, 239, 138, 26, 134, 97, 46, 250, 9, + 142, 148, 201, 217, 224, 223, 68, 54, 180, 157, 30, 98, 140, 81, 237, 29, 242, 108, 3 }; + +static uint8_t g_p256t1PointCompressedBlobData[] = { 2, 134, 165, 93, 7, 187, 30, 225, 62, 157, 177, 229, 63, 104, + 217, 148, 68, 85, 152, 34, 185, 100, 81, 111, 233, 193, 108, 198, 74, 37, 188, 46, 19 }; + +static uint8_t g_p320r1PointCompressedBlobData[] = { 2, 117, 229, 73, 102, 77, 218, 200, 35, 245, 163, 23, 219, + 50, 180, 7, 60, 219, 87, 135, 67, 214, 34, 71, 1, 75, 227, 143, 253, 203, 40, 246, 249, 210, 64, 255, + 186, 202, 161, 214, 203 }; + +static uint8_t g_p320t1PointCompressedBlobData[] = { 2, 188, 215, 24, 76, 167, 218, 220, 193, 3, 105, 145, 175, + 125, 17, 15, 227, 69, 120, 196, 97, 151, 3, 116, 23, 83, 71, 204, 133, 13, 225, 88, 31, 11, 168, + 66, 57, 64, 233, 125, 156 }; + +static uint8_t g_p384r1PointCompressedBlobData[] = { 2, 24, 149, 106, 30, 33, 152, 247, 126, 23, 231, 139, 197, + 240, 145, 3, 6, 38, 168, 157, 60, 153, 95, 41, 184, 110, 135, 222, 237, 86, 132, 255, 180, 245, 49, 41, 3, + 223, 122, 210, 203, 213, 55, 108, 251, 65, 181, 168, 25 }; + +static uint8_t g_p384t1PointCompressedBlobData[] = { 3, 64, 192, 12, 47, 160, 35, 23, 244, 163, 108, 172, 235, + 185, 100, 0, 180, 112, 85, 105, 29, 120, 105, 164, 148, 59, 168, 183, 168, 142, 141, 14, 121, 240, 132, 168, + 4, 208, 142, 24, 226, 75, 169, 249, 46, 63, 61, 129, 154 }; + +static uint8_t g_p512r1PointCompressedBlobData[] = { 2, 18, 25, 192, 69, 115, 54, 110, 174, 51, 48, 253, 129, + 31, 118, 237, 38, 1, 174, 8, 111, 74, 249, 149, 154, 119, 114, 59, 51, 160, 206, 70, 199, 202, 42, 98, 245, + 170, 251, 154, 22, 243, 137, 182, 239, 219, 166, 28, 202, 183, 229, 2, 83, 16, 244, 211, 100, 30, 179, 251, 17, + 52, 117, 55, 70 }; + +static uint8_t g_p512t1PointCompressedBlobData[] = { 3, 119, 56, 81, 46, 40, 173, 156, 49, 235, 26, 193, 122, 32, + 201, 88, 18, 90, 55, 144, 84, 125, 90, 106, 169, 66, 124, 90, 44, 145, 100, 224, 192, 22, 241, 38, 185, 93, + 163, 146, 221, 126, 222, 57, 95, 136, 139, 231, 85, 250, 133, 140, 81, 138, 66, 148, 253, 192, 217, 210, 33, + 157, 60, 5, 113 }; + +static HcfBlob g_secp224r1PointCompressedBlob = { + .data = g_secp224r1PointCompressedBlobData, + .len = SECP224R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_prime256v1PointCompressedBlob = { + .data = g_prime256v1PointCompressedBlobData, + .len = PRIME256V1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_secp384r1PointCompressedBlob = { + .data = g_secp384r1PointCompressedBlobData, + .len = SECP384R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_secp521r1PointCompressedBlob = { + .data = g_secp521r1PointCompressedBlobData, + .len = SECP521R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p160r1PointCompressedBlob = { + .data = g_p160r1PointCompressedBlobData, + .len = P160R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p160t1PointCompressedBlob = { + .data = g_p160t1PointCompressedBlobData, + .len = P160T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p192r1PointCompressedBlob = { + .data = g_p192r1PointCompressedBlobData, + .len = P192R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p192t1PointCompressedBlob = { + .data = g_p192t1PointCompressedBlobData, + .len = P192T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p224r1PointCompressedBlob = { + .data = g_p224r1PointCompressedBlobData, + .len = P224R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p224t1PointCompressedBlob = { + .data = g_p224t1PointCompressedBlobData, + .len = P224T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p256r1PointCompressedBlob = { + .data = g_p256r1PointCompressedBlobData, + .len = P256R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p256t1PointCompressedBlob = { + .data = g_p256t1PointCompressedBlobData, + .len = P256T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p320r1PointCompressedBlob = { + .data = g_p320r1PointCompressedBlobData, + .len = P320R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p320t1PointCompressedBlob = { + .data = g_p320t1PointCompressedBlobData, + .len = P320T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p384r1PointCompressedBlob = { + .data = g_p384r1PointCompressedBlobData, + .len = P384R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p384t1PointCompressedBlob = { + .data = g_p384t1PointCompressedBlobData, + .len = P384T1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p512r1PointCompressedBlob = { + .data = g_p512r1PointCompressedBlobData, + .len = P512R1_POINT_COMPRESSED_SIZE +}; + +static HcfBlob g_p512t1PointCompressedBlob = { + .data = g_p512t1PointCompressedBlobData, + .len = P512T1_POINT_COMPRESSED_SIZE +}; + +typedef struct { + const char *curveName; + HcfBlob *pointUncompressedBlob; + HcfBlob *pointCompressedBlob; +} PointData; + +static const PointData POINT_DATA_MAP[] = { + { "NID_secp224r1", &g_secp224r1PointUncompressedBlob, &g_secp224r1PointCompressedBlob }, + { "NID_X9_62_prime256v1", &g_prime256v1PointUncompressedBlob, &g_prime256v1PointCompressedBlob }, + { "NID_secp384r1", &g_secp384r1PointUncompressedBlob, &g_secp384r1PointCompressedBlob }, + { "NID_secp521r1", &g_secp521r1PointUncompressedBlob, &g_secp521r1PointCompressedBlob }, + { "NID_brainpoolP160r1", &g_p160r1PointUncompressedBlob, &g_p160r1PointCompressedBlob }, + { "NID_brainpoolP160t1", &g_p160t1PointUncompressedBlob, &g_p160t1PointCompressedBlob }, + { "NID_brainpoolP192r1", &g_p192r1PointUncompressedBlob, &g_p192r1PointCompressedBlob }, + { "NID_brainpoolP192t1", &g_p192t1PointUncompressedBlob, &g_p192t1PointCompressedBlob }, + { "NID_brainpoolP224r1", &g_p224r1PointUncompressedBlob, &g_p224r1PointCompressedBlob }, + { "NID_brainpoolP224t1", &g_p224t1PointUncompressedBlob, &g_p224t1PointCompressedBlob }, + { "NID_brainpoolP256r1", &g_p256r1PointUncompressedBlob, &g_p256r1PointCompressedBlob }, + { "NID_brainpoolP256t1", &g_p256t1PointUncompressedBlob, &g_p256t1PointCompressedBlob }, + { "NID_brainpoolP320r1", &g_p320r1PointUncompressedBlob, &g_p320r1PointCompressedBlob }, + { "NID_brainpoolP320t1", &g_p320t1PointUncompressedBlob, &g_p320t1PointCompressedBlob }, + { "NID_brainpoolP384r1", &g_p384r1PointUncompressedBlob, &g_p384r1PointCompressedBlob }, + { "NID_brainpoolP384t1", &g_p384t1PointUncompressedBlob, &g_p384t1PointCompressedBlob }, + { "NID_brainpoolP512r1", &g_p512r1PointUncompressedBlob, &g_p512r1PointCompressedBlob }, + { "NID_brainpoolP512t1", &g_p512t1PointUncompressedBlob, &g_p512t1PointCompressedBlob } +}; + +// uncompressed pubkey data size +constexpr size_t SECP224R1_PUBKEY_UNCOMPRESSED_SIZE = 80; +constexpr size_t PRIME256V1_PUBKEY_UNCOMPRESSED_SIZE = 91; +constexpr size_t SECP384R1_PUBKEY_UNCOMPRESSED_SIZE = 120; +constexpr size_t SECP521R1_PUBKEY_UNCOMPRESSED_SIZE = 158; +constexpr size_t P160R1_PUBKEY_UNCOMPRESSED_SIZE = 68; +constexpr size_t P160T1_PUBKEY_UNCOMPRESSED_SIZE = 68; +constexpr size_t P192R1_PUBKEY_UNCOMPRESSED_SIZE = 76; +constexpr size_t P192T1_PUBKEY_UNCOMPRESSED_SIZE = 76; +constexpr size_t P224R1_PUBKEY_UNCOMPRESSED_SIZE = 84; +constexpr size_t P224T1_PUBKEY_UNCOMPRESSED_SIZE = 84; +constexpr size_t P256R1_PUBKEY_UNCOMPRESSED_SIZE = 92; +constexpr size_t P256T1_PUBKEY_UNCOMPRESSED_SIZE = 92; +constexpr size_t P320R1_PUBKEY_UNCOMPRESSED_SIZE = 108; +constexpr size_t P320T1_PUBKEY_UNCOMPRESSED_SIZE = 108; +constexpr size_t P384R1_PUBKEY_UNCOMPRESSED_SIZE = 124; +constexpr size_t P384T1_PUBKEY_UNCOMPRESSED_SIZE = 124; +constexpr size_t P512R1_PUBKEY_UNCOMPRESSED_SIZE = 158; +constexpr size_t P512T1_PUBKEY_UNCOMPRESSED_SIZE = 158; + +// uncompressed pubkey data +static uint8_t g_secp224r1PubKeyUncompressedBlobData[] = { 48, 78, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, + 129, 4, 0, 33, 3, 58, 0, 4, 56, 90, 25, 144, 206, 229, 109, 59, 65, 62, 249, 113, 247, 239, 20, 63, 107, 72, 217, + 43, 12, 124, 241, 209, 32, 66, 134, 239, 169, 154, 59, 182, 106, 163, 190, 214, 232, 213, 73, 97, 57, 163, 137, + 66, 59, 238, 12, 142, 87, 37, 182, 22, 60, 106, 235, 237 }; + +static uint8_t g_prime256v1PubKeyUncompressedBlobData[] = { 48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, + 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 153, 228, 156, 119, 184, 185, 120, 237, 233, 181, 77, 70, 183, 30, + 68, 2, 70, 37, 251, 5, 22, 199, 84, 87, 222, 65, 103, 8, 26, 255, 137, 206, 80, 159, 163, 46, 22, 104, 156, 169, + 14, 149, 199, 35, 201, 3, 160, 81, 251, 235, 236, 75, 137, 196, 253, 200, 116, 167, 59, 153, 241, 99, 90, 90 }; + +static uint8_t g_secp384r1PubKeyUncompressedBlobData[] = { 48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, + 43, 129, 4, 0, 34, 3, 98, 0, 4, 246, 157, 255, 226, 94, 109, 16, 243, 109, 34, 121, 62, 12, 160, 181, 60, 89, 27, + 60, 236, 118, 93, 113, 123, 64, 220, 231, 248, 113, 220, 130, 75, 164, 174, 128, 84, 135, 212, 122, 99, 97, 167, + 89, 56, 162, 60, 50, 185, 154, 231, 102, 187, 58, 105, 237, 215, 53, 88, 253, 33, 45, 36, 25, 176, 112, 110, 132, + 39, 33, 56, 224, 21, 225, 8, 108, 81, 106, 157, 33, 210, 105, 138, 130, 163, 96, 112, 183, 179, 241, 25, 188, + 121, 68, 180, 169, 149 }; + +static uint8_t g_secp521r1PubKeyUncompressedBlobData[] = { 48, 129, 155, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, + 5, 43, 129, 4, 0, 35, 3, 129, 134, 0, 4, 0, 234, 87, 65, 173, 170, 194, 156, 174, 174, 229, 236, 236, 195, 107, + 24, 24, 169, 187, 160, 28, 11, 239, 70, 163, 131, 233, 157, 104, 41, 202, 208, 166, 209, 217, 39, 225, 163, 33, + 17, 134, 48, 150, 111, 225, 193, 219, 232, 234, 117, 100, 27, 169, 172, 60, 186, 69, 246, 244, 218, 249, 188, 96, + 49, 247, 125, 0, 70, 67, 187, 0, 72, 109, 99, 50, 173, 42, 250, 10, 89, 166, 85, 64, 28, 145, 30, 130, 174, 147, + 22, 232, 37, 17, 158, 165, 178, 11, 34, 58, 98, 98, 43, 32, 146, 102, 178, 198, 176, 41, 150, 37, 43, 132, 232, + 32, 98, 143, 125, 255, 173, 158, 227, 4, 238, 168, 113, 194, 162, 74, 234, 239, 102 }; + +static uint8_t g_p160r1PubKeyUncompressedBlobData[] = { 48, 66, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 1, 3, 42, 0, 4, 162, 100, 90, 91, 16, 253, 183, 186, 164, 222, 247, 223, 75, 228, 92, 253, + 253, 250, 38, 30, 125, 172, 62, 13, 109, 61, 63, 160, 20, 103, 94, 7, 68, 115, 202, 170, 157, 244, 174, 26 }; + +static uint8_t g_p160t1PubKeyUncompressedBlobData[] = { 48, 66, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 2, 3, 42, 0, 4, 73, 116, 114, 251, 6, 125, 11, 84, 159, 140, 0, 164, 101, 40, 147, 227, 28, + 143, 224, 160, 217, 185, 12, 197, 39, 34, 91, 119, 135, 123, 80, 45, 26, 156, 221, 2, 79, 242, 45, 24 }; + +static uint8_t g_p192r1PubKeyUncompressedBlobData[] = { 48, 74, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 3, 3, 50, 0, 4, 72, 15, 250, 255, 107, 128, 70, 56, 144, 154, 23, 141, 54, 19, 255, 134, + 235, 12, 187, 128, 121, 41, 255, 141, 69, 81, 100, 94, 238, 15, 166, 184, 1, 214, 220, 222, 12, 239, 145, 184, + 143, 146, 165, 9, 107, 74, 199, 1 }; + +static uint8_t g_p192t1PubKeyUncompressedBlobData[] = { 48, 74, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 4, 3, 50, 0, 4, 131, 174, 50, 196, 198, 2, 164, 255, 193, 233, 237, 217, 47, 191, 35, 6, + 166, 69, 42, 38, 128, 134, 29, 97, 23, 242, 82, 96, 164, 135, 108, 120, 179, 105, 10, 32, 90, 152, 99, 10, 2, + 220, 184, 207, 8, 65, 168, 95 }; + +static uint8_t g_p224r1PubKeyUncompressedBlobData[] = { 48, 82, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 5, 3, 58, 0, 4, 179, 154, 82, 152, 164, 40, 37, 88, 133, 242, 75, 160, 244, 155, 186, 103, + 163, 44, 100, 137, 114, 124, 28, 27, 187, 99, 235, 123, 46, 127, 137, 234, 188, 6, 91, 68, 250, 89, 231, 62, + 179, 47, 119, 221, 5, 73, 128, 12, 241, 57, 101, 15, 9, 95, 11, 101 }; + +static uint8_t g_p224t1PubKeyUncompressedBlobData[] = { 48, 82, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 6, 3, 58, 0, 4, 187, 42, 38, 78, 26, 235, 23, 233, 222, 133, 167, 236, 86, 95, 104, 44, + 160, 133, 41, 92, 214, 174, 194, 43, 214, 123, 12, 188, 210, 117, 152, 50, 0, 136, 6, 92, 57, 236, 246, 150, 145, + 249, 150, 185, 255, 116, 28, 111, 22, 173, 25, 205, 96, 251, 61, 238 }; + +static uint8_t g_p256r1PubKeyUncompressedBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 7, 3, 66, 0, 4, 0, 181, 254, 30, 31, 239, 138, 26, 134, 97, 46, 250, 9, 142, 148, 201, + 217, 224, 223, 68, 54, 180, 157, 30, 98, 140, 81, 237, 29, 242, 108, 3, 100, 127, 165, 176, 53, 73, 197, 151, + 79, 219, 204, 98, 116, 71, 97, 1, 127, 216, 38, 84, 18, 157, 250, 240, 109, 251, 105, 243, 73, 17, 153, 138 }; + +static uint8_t g_p256t1PubKeyUncompressedBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 8, 3, 66, 0, 4, 134, 165, 93, 7, 187, 30, 225, 62, 157, 177, 229, 63, 104, 217, 148, 68, + 85, 152, 34, 185, 100, 81, 111, 233, 193, 108, 198, 74, 37, 188, 46, 19, 136, 157, 88, 166, 194, 167, 157, 163, + 173, 69, 7, 153, 48, 246, 3, 54, 127, 113, 145, 17, 128, 250, 210, 218, 249, 150, 249, 243, 178, 136, 112, 192 }; + +static uint8_t g_p320r1PubKeyUncompressedBlobData[] = { 48, 106, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 9, 3, 82, 0, 4, 117, 229, 73, 102, 77, 218, 200, 35, 245, 163, 23, 219, 50, 180, 7, 60, + 219, 87, 135, 67, 214, 34, 71, 1, 75, 227, 143, 253, 203, 40, 246, 249, 210, 64, 255, 186, 202, 161, 214, 203, + 91, 159, 114, 252, 134, 230, 86, 188, 103, 223, 217, 12, 238, 118, 6, 232, 161, 198, 195, 139, 62, 36, 98, 212, + 129, 215, 178, 83, 137, 164, 95, 239, 238, 216, 222, 125, 246, 105, 66, 164 }; + +static uint8_t g_p320t1PubKeyUncompressedBlobData[] = { 48, 106, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 10, 3, 82, 0, 4, 188, 215, 24, 76, 167, 218, 220, 193, 3, 105, 145, 175, 125, 17, 15, 227, + 69, 120, 196, 97, 151, 3, 116, 23, 83, 71, 204, 133, 13, 225, 88, 31, 11, 168, 66, 57, 64, 233, 125, 156, 12, 28, + 241, 242, 224, 110, 133, 157, 230, 106, 16, 126, 66, 37, 8, 235, 230, 90, 20, 253, 2, 223, 157, 135, 71, 161, 64, + 111, 50, 212, 125, 187, 44, 181, 211, 76, 217, 53, 94, 162 }; + +static uint8_t g_p384r1PubKeyUncompressedBlobData[] = { 48, 122, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 11, 3, 98, 0, 4, 24, 149, 106, 30, 33, 152, 247, 126, 23, 231, 139, 197, 240, 145, 3, 6, 38, + 168, 157, 60, 153, 95, 41, 184, 110, 135, 222, 237, 86, 132, 255, 180, 245, 49, 41, 3, 223, 122, 210, 203, 213, + 55, 108, 251, 65, 181, 168, 25, 69, 50, 124, 233, 124, 121, 89, 187, 238, 186, 163, 169, 88, 48, 7, 108, 206, + 228, 141, 162, 127, 232, 67, 175, 95, 220, 178, 28, 152, 254, 148, 123, 46, 132, 222, 124, 11, 51, 152, 113, + 44, 14, 222, 126, 142, 114, 10, 124 }; + +static uint8_t g_p384t1PubKeyUncompressedBlobData[] = { 48, 122, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 12, 3, 98, 0, 4, 64, 192, 12, 47, 160, 35, 23, 244, 163, 108, 172, 235, 185, 100, 0, 180, + 112, 85, 105, 29, 120, 105, 164, 148, 59, 168, 183, 168, 142, 141, 14, 121, 240, 132, 168, 4, 208, 142, 24, 226, + 75, 169, 249, 46, 63, 61, 129, 154, 41, 6, 34, 81, 246, 230, 4, 227, 103, 106, 107, 216, 130, 58, 248, 156, 101, + 96, 85, 109, 43, 233, 229, 96, 165, 188, 222, 226, 113, 17, 213, 194, 57, 142, 117, 129, 151, 187, 235, 43, 253, + 132, 151, 96, 49, 85, 37, 101 }; + +static uint8_t g_p512r1PubKeyUncompressedBlobData[] = { 48, 129, 155, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, + 43, 36, 3, 3, 2, 8, 1, 1, 13, 3, 129, 130, 0, 4, 18, 25, 192, 69, 115, 54, 110, 174, 51, 48, 253, 129, 31, 118, + 237, 38, 1, 174, 8, 111, 74, 249, 149, 154, 119, 114, 59, 51, 160, 206, 70, 199, 202, 42, 98, 245, 170, 251, 154, + 22, 243, 137, 182, 239, 219, 166, 28, 202, 183, 229, 2, 83, 16, 244, 211, 100, 30, 179, 251, 17, 52, 117, 55, 70, + 114, 203, 60, 190, 163, 132, 156, 63, 246, 140, 173, 122, 80, 68, 155, 60, 74, 199, 248, 71, 134, 52, 228, 28, + 122, 72, 100, 26, 36, 148, 20, 187, 59, 137, 98, 191, 165, 174, 43, 2, 68, 222, 184, 34, 108, 8, 155, 150, 12, + 101, 120, 155, 164, 200, 52, 206, 240, 116, 158, 207, 180, 124, 210, 62 }; + +static uint8_t g_p512t1PubKeyUncompressedBlobData[] = { 48, 129, 155, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, + 43, 36, 3, 3, 2, 8, 1, 1, 14, 3, 129, 130, 0, 4, 119, 56, 81, 46, 40, 173, 156, 49, 235, 26, 193, 122, 32, 201, + 88, 18, 90, 55, 144, 84, 125, 90, 106, 169, 66, 124, 90, 44, 145, 100, 224, 192, 22, 241, 38, 185, 93, 163, 146, + 221, 126, 222, 57, 95, 136, 139, 231, 85, 250, 133, 140, 81, 138, 66, 148, 253, 192, 217, 210, 33, 157, 60, 5, + 113, 151, 65, 106, 113, 44, 250, 237, 139, 172, 190, 154, 142, 17, 77, 228, 232, 223, 31, 208, 83, 231, 120, + 127, 36, 129, 82, 186, 219, 207, 87, 130, 231, 224, 111, 210, 88, 19, 147, 0, 37, 194, 9, 217, 191, 162, 77, + 165, 32, 78, 141, 227, 44, 70, 156, 13, 250, 36, 93, 226, 178, 165, 61, 33, 63 }; + +static HcfBlob g_secp224r1PubKeyUncompressedBlob = { + .data = g_secp224r1PubKeyUncompressedBlobData, + .len = SECP224R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_prime256v1PubKeyUncompressedBlob = { + .data = g_prime256v1PubKeyUncompressedBlobData, + .len = PRIME256V1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_secp384r1PubKeyUncompressedBlob = { + .data = g_secp384r1PubKeyUncompressedBlobData, + .len = SECP384R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_secp521r1PubKeyUncompressedBlob = { + .data = g_secp521r1PubKeyUncompressedBlobData, + .len = SECP521R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p160r1PubKeyUncompressedBlob = { + .data = g_p160r1PubKeyUncompressedBlobData, + .len = P160R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p160t1PubKeyUncompressedBlob = { + .data = g_p160t1PubKeyUncompressedBlobData, + .len = P160T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p192r1PubKeyUncompressedBlob = { + .data = g_p192r1PubKeyUncompressedBlobData, + .len = P192R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p192t1PubKeyUncompressedBlob = { + .data = g_p192t1PubKeyUncompressedBlobData, + .len = P192T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p224r1PubKeyUncompressedBlob = { + .data = g_p224r1PubKeyUncompressedBlobData, + .len = P224R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p224t1PubKeyUncompressedBlob = { + .data = g_p224t1PubKeyUncompressedBlobData, + .len = P224T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p256r1PubKeyUncompressedBlob = { + .data = g_p256r1PubKeyUncompressedBlobData, + .len = P256R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p256t1PubKeyUncompressedBlob = { + .data = g_p256t1PubKeyUncompressedBlobData, + .len = P256T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p320r1PubKeyUncompressedBlob = { + .data = g_p320r1PubKeyUncompressedBlobData, + .len = P320R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p320t1PubKeyUncompressedBlob = { + .data = g_p320t1PubKeyUncompressedBlobData, + .len = P320T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p384r1PubKeyUncompressedBlob = { + .data = g_p384r1PubKeyUncompressedBlobData, + .len = P384R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p384t1PubKeyUncompressedBlob = { + .data = g_p384t1PubKeyUncompressedBlobData, + .len = P384T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p512r1PubKeyUncompressedBlob = { + .data = g_p512r1PubKeyUncompressedBlobData, + .len = P512R1_PUBKEY_UNCOMPRESSED_SIZE +}; + +static HcfBlob g_p512t1PubKeyUncompressedBlob = { + .data = g_p512t1PubKeyUncompressedBlobData, + .len = P512T1_PUBKEY_UNCOMPRESSED_SIZE +}; + +// compressed pubkey data size +constexpr size_t SECP224R1_PUBKEY_COMPRESSED_SIZE = 52; +constexpr size_t PRIME256V1_PUBKEY_COMPRESSED_SIZE = 59; +constexpr size_t SECP384R1_PUBKEY_COMPRESSED_SIZE = 72; +constexpr size_t SECP521R1_PUBKEY_COMPRESSED_SIZE = 90; +constexpr size_t P160R1_PUBKEY_COMPRESSED_SIZE = 48; +constexpr size_t P160T1_PUBKEY_COMPRESSED_SIZE = 48; +constexpr size_t P192R1_PUBKEY_COMPRESSED_SIZE = 52; +constexpr size_t P192T1_PUBKEY_COMPRESSED_SIZE = 52; +constexpr size_t P224R1_PUBKEY_COMPRESSED_SIZE = 56; +constexpr size_t P224T1_PUBKEY_COMPRESSED_SIZE = 56; +constexpr size_t P256R1_PUBKEY_COMPRESSED_SIZE = 60; +constexpr size_t P256T1_PUBKEY_COMPRESSED_SIZE = 60; +constexpr size_t P320R1_PUBKEY_COMPRESSED_SIZE = 68; +constexpr size_t P320T1_PUBKEY_COMPRESSED_SIZE = 68; +constexpr size_t P384R1_PUBKEY_COMPRESSED_SIZE = 76; +constexpr size_t P384T1_PUBKEY_COMPRESSED_SIZE = 76; +constexpr size_t P512R1_PUBKEY_COMPRESSED_SIZE = 92; +constexpr size_t P512T1_PUBKEY_COMPRESSED_SIZE = 92; + +// compressed pubkey data +static uint8_t g_secp224r1PubKeyCompressedBlobData[] = { 48, 50, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, + 129, 4, 0, 33, 3, 30, 0, 3, 56, 90, 25, 144, 206, 229, 109, 59, 65, 62, 249, 113, 247, 239, 20, 63, 107, 72, + 217, 43, 12, 124, 241, 209, 32, 66, 134, 239 }; + +static uint8_t g_prime256v1PubKeyCompressedBlobData[] = { 48, 57, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, + 42, 134, 72, 206, 61, 3, 1, 7, 3, 34, 0, 2, 153, 228, 156, 119, 184, 185, 120, 237, 233, 181, 77, 70, 183, 30, + 68, 2, 70, 37, 251, 5, 22, 199, 84, 87, 222, 65, 103, 8, 26, 255, 137, 206 }; + +static uint8_t g_secp384r1PubKeyCompressedBlobData[] = { 48, 70, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, + 129, 4, 0, 34, 3, 50, 0, 3, 246, 157, 255, 226, 94, 109, 16, 243, 109, 34, 121, 62, 12, 160, 181, 60, 89, 27, 60, + 236, 118, 93, 113, 123, 64, 220, 231, 248, 113, 220, 130, 75, 164, 174, 128, 84, 135, 212, 122, 99, 97, 167, + 89, 56, 162, 60, 50, 185 }; + +static uint8_t g_secp521r1PubKeyCompressedBlobData[] = { 48, 88, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, + 129, 4, 0, 35, 3, 68, 0, 2, 0, 234, 87, 65, 173, 170, 194, 156, 174, 174, 229, 236, 236, 195, 107, 24, 24, 169, + 187, 160, 28, 11, 239, 70, 163, 131, 233, 157, 104, 41, 202, 208, 166, 209, 217, 39, 225, 163, 33, 17, 134, 48, + 150, 111, 225, 193, 219, 232, 234, 117, 100, 27, 169, 172, 60, 186, 69, 246, 244, 218, 249, 188, 96, 49, 247, 125 }; + +static uint8_t g_p160r1PubKeyCompressedBlobData[] = { 48, 46, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 1, 3, 22, 0, 2, 162, 100, 90, 91, 16, 253, 183, 186, 164, 222, 247, 223, 75, 228, 92, + 253, 253, 250, 38, 30 }; + +static uint8_t g_p160t1PubKeyCompressedBlobData[] = { 48, 46, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 2, 3, 22, 0, 2, 73, 116, 114, 251, 6, 125, 11, 84, 159, 140, 0, 164, 101, 40, 147, 227, + 28, 143, 224, 160 }; + +static uint8_t g_p192r1PubKeyCompressedBlobData[] = { 48, 50, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 3, 3, 26, 0, 3, 72, 15, 250, 255, 107, 128, 70, 56, 144, 154, 23, 141, 54, 19, 255, 134, + 235, 12, 187, 128, 121, 41, 255, 141 }; + +static uint8_t g_p192t1PubKeyCompressedBlobData[] = { 48, 50, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 4, 3, 26, 0, 3, 131, 174, 50, 196, 198, 2, 164, 255, 193, 233, 237, 217, 47, 191, 35, 6, + 166, 69, 42, 38, 128, 134, 29, 97 }; + +static uint8_t g_p224r1PubKeyCompressedBlobData[] = { 48, 54, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 5, 3, 30, 0, 3, 179, 154, 82, 152, 164, 40, 37, 88, 133, 242, 75, 160, 244, 155, 186, 103, + 163, 44, 100, 137, 114, 124, 28, 27, 187, 99, 235, 123 }; + +static uint8_t g_p224t1PubKeyCompressedBlobData[] = { 48, 54, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 6, 3, 30, 0, 2, 187, 42, 38, 78, 26, 235, 23, 233, 222, 133, 167, 236, 86, 95, 104, 44, + 160, 133, 41, 92, 214, 174, 194, 43, 214, 123, 12, 188 }; + +static uint8_t g_p256r1PubKeyCompressedBlobData[] = { 48, 58, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 7, 3, 34, 0, 2, 0, 181, 254, 30, 31, 239, 138, 26, 134, 97, 46, 250, 9, 142, 148, 201, 217, 224, + 223, 68, 54, 180, 157, 30, 98, 140, 81, 237, 29, 242, 108, 3 }; + +static uint8_t g_p256t1PubKeyCompressedBlobData[] = { 48, 58, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 8, 3, 34, 0, 2, 134, 165, 93, 7, 187, 30, 225, 62, 157, 177, 229, 63, 104, 217, 148, 68, 85, + 152, 34, 185, 100, 81, 111, 233, 193, 108, 198, 74, 37, 188, 46, 19 }; + +static uint8_t g_p320r1PubKeyCompressedBlobData[] = { 48, 66, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 9, 3, 42, 0, 2, 117, 229, 73, 102, 77, 218, 200, 35, 245, 163, 23, 219, 50, 180, 7, 60, 219, + 87, 135, 67, 214, 34, 71, 1, 75, 227, 143, 253, 203, 40, 246, 249, 210, 64, 255, 186, 202, 161, 214, 203 }; + +static uint8_t g_p320t1PubKeyCompressedBlobData[] = { 48, 66, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 10, 3, 42, 0, 2, 188, 215, 24, 76, 167, 218, 220, 193, 3, 105, 145, 175, 125, 17, 15, 227, 69, + 120, 196, 97, 151, 3, 116, 23, 83, 71, 204, 133, 13, 225, 88, 31, 11, 168, 66, 57, 64, 233, 125, 156 }; + +static uint8_t g_p384r1PubKeyCompressedBlobData[] = { 48, 74, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 11, 3, 50, 0, 2, 24, 149, 106, 30, 33, 152, 247, 126, 23, 231, 139, 197, 240, 145, 3, 6, 38, + 168, 157, 60, 153, 95, 41, 184, 110, 135, 222, 237, 86, 132, 255, 180, 245, 49, 41, 3, 223, 122, 210, 203, 213, + 55, 108, 251, 65, 181, 168, 25 }; + +static uint8_t g_p384t1PubKeyCompressedBlobData[] = { 48, 74, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 12, 3, 50, 0, 3, 64, 192, 12, 47, 160, 35, 23, 244, 163, 108, 172, 235, 185, 100, 0, 180, 112, + 85, 105, 29, 120, 105, 164, 148, 59, 168, 183, 168, 142, 141, 14, 121, 240, 132, 168, 4, 208, 142, 24, 226, 75, + 169, 249, 46, 63, 61, 129, 154 }; + +static uint8_t g_p512r1PubKeyCompressedBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, + 3, 3, 2, 8, 1, 1, 13, 3, 66, 0, 2, 18, 25, 192, 69, 115, 54, 110, 174, 51, 48, 253, 129, 31, 118, 237, 38, 1, 174, + 8, 111, 74, 249, 149, 154, 119, 114, 59, 51, 160, 206, 70, 199, 202, 42, 98, 245, 170, 251, 154, 22, 243, 137, + 182, 239, 219, 166, 28, 202, 183, 229, 2, 83, 16, 244, 211, 100, 30, 179, 251, 17, 52, 117, 55, 70 }; + +static uint8_t g_p512t1PubKeyCompressedBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, + 36, 3, 3, 2, 8, 1, 1, 14, 3, 66, 0, 3, 119, 56, 81, 46, 40, 173, 156, 49, 235, 26, 193, 122, 32, 201, 88, 18, 90, + 55, 144, 84, 125, 90, 106, 169, 66, 124, 90, 44, 145, 100, 224, 192, 22, 241, 38, 185, 93, 163, 146, 221, 126, + 222, 57, 95, 136, 139, 231, 85, 250, 133, 140, 81, 138, 66, 148, 253, 192, 217, 210, 33, 157, 60, 5, 113 }; + +static HcfBlob g_secp224r1PubKeyCompressedBlob = { + .data = g_secp224r1PubKeyCompressedBlobData, + .len = SECP224R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_prime256v1PubKeyCompressedBlob = { + .data = g_prime256v1PubKeyCompressedBlobData, + .len = PRIME256V1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_secp384r1PubKeyCompressedBlob = { + .data = g_secp384r1PubKeyCompressedBlobData, + .len = SECP384R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_secp521r1PubKeyCompressedBlob = { + .data = g_secp521r1PubKeyCompressedBlobData, + .len = SECP521R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p160r1PubKeyCompressedBlob = { + .data = g_p160r1PubKeyCompressedBlobData, + .len = P160R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p160t1PubKeyCompressedBlob = { + .data = g_p160t1PubKeyCompressedBlobData, + .len = P160T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p192r1PubKeyCompressedBlob = { + .data = g_p192r1PubKeyCompressedBlobData, + .len = P192R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p192t1PubKeyCompressedBlob = { + .data = g_p192t1PubKeyCompressedBlobData, + .len = P192T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p224r1PubKeyCompressedBlob = { + .data = g_p224r1PubKeyCompressedBlobData, + .len = P224R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p224t1PubKeyCompressedBlob = { + .data = g_p224t1PubKeyCompressedBlobData, + .len = P224T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p256r1PubKeyCompressedBlob = { + .data = g_p256r1PubKeyCompressedBlobData, + .len = P256R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p256t1PubKeyCompressedBlob = { + .data = g_p256t1PubKeyCompressedBlobData, + .len = P256T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p320r1PubKeyCompressedBlob = { + .data = g_p320r1PubKeyCompressedBlobData, + .len = P320R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p320t1PubKeyCompressedBlob = { + .data = g_p320t1PubKeyCompressedBlobData, + .len = P320T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p384r1PubKeyCompressedBlob = { + .data = g_p384r1PubKeyCompressedBlobData, + .len = P384R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p384t1PubKeyCompressedBlob = { + .data = g_p384t1PubKeyCompressedBlobData, + .len = P384T1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p512r1PubKeyCompressedBlob = { + .data = g_p512r1PubKeyCompressedBlobData, + .len = P512R1_PUBKEY_COMPRESSED_SIZE +}; + +static HcfBlob g_p512t1PubKeyCompressedBlob = { + .data = g_p512t1PubKeyCompressedBlobData, + .len = P512T1_PUBKEY_COMPRESSED_SIZE +}; + +typedef struct { + const char *algoName; + HcfBlob *pubKeyUncompressedBlob; + HcfBlob *pubKeyCompressedBlob; +} PubKeyData; + +static const PubKeyData PUBKEY_DATA_MAP[] = { + { "ECC224", &g_secp224r1PubKeyUncompressedBlob, &g_secp224r1PubKeyCompressedBlob }, + { "ECC256", &g_prime256v1PubKeyUncompressedBlob, &g_prime256v1PubKeyCompressedBlob }, + { "ECC384", &g_secp384r1PubKeyUncompressedBlob, &g_secp384r1PubKeyCompressedBlob }, + { "ECC521", &g_secp521r1PubKeyUncompressedBlob, &g_secp521r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP160r1", &g_p160r1PubKeyUncompressedBlob, &g_p160r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP160t1", &g_p160t1PubKeyUncompressedBlob, &g_p160t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP192r1", &g_p192r1PubKeyUncompressedBlob, &g_p192r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP192t1", &g_p192t1PubKeyUncompressedBlob, &g_p192t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP224r1", &g_p224r1PubKeyUncompressedBlob, &g_p224r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP224t1", &g_p224t1PubKeyUncompressedBlob, &g_p224t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP256r1", &g_p256r1PubKeyUncompressedBlob, &g_p256r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP256t1", &g_p256t1PubKeyUncompressedBlob, &g_p256t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP320r1", &g_p320r1PubKeyUncompressedBlob, &g_p320r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP320t1", &g_p320t1PubKeyUncompressedBlob, &g_p320t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP384r1", &g_p384r1PubKeyUncompressedBlob, &g_p384r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP384t1", &g_p384t1PubKeyUncompressedBlob, &g_p384t1PubKeyCompressedBlob }, + { "ECC_BrainPoolP512r1", &g_p512r1PubKeyUncompressedBlob, &g_p512r1PubKeyCompressedBlob }, + { "ECC_BrainPoolP512t1", &g_p512t1PubKeyUncompressedBlob, &g_p512t1PubKeyCompressedBlob } +}; + +static HcfResult CompareBlobEqual(const HcfBlob *returnBlob, const HcfBlob *dataBlob) +{ + if (returnBlob->len != dataBlob->len) { + return HCF_INVALID_PARAMS; + } + for (size_t i = 0; i < returnBlob->len; ++i) { + if (returnBlob->data[i] != dataBlob->data[i]) { + return HCF_INVALID_PARAMS; + } + } + return HCF_SUCCESS; +} + +static const char *INPUT_MESSAGE_ONE = "This is Sign test plan1"; +static const char *INPUT_MESSAGE_TWO = "This is Sign test plan2"; + +static HcfBlob g_inputOne = { + .data = (uint8_t *)INPUT_MESSAGE_ONE, + .len = 24 +}; + +static HcfBlob g_inputTwo = { + .data = (uint8_t *)INPUT_MESSAGE_TWO, + .len = 24 +}; + +// SM2_256 point data +constexpr size_t SM2_POINT_UNCOMPRESSED_SIZE = 65; +constexpr size_t SM2_POINT_COMPRESSED_SIZE = 33; + +static uint8_t g_sm2PointUncompressedBlobData[] = { 4, 232, 131, 204, 172, 46, 67, 127, 51, 64, 4, 236, 190, 110, 155, + 221, 220, 226, 224, 249, 236, 223, 146, 39, 255, 109, 226, 6, 209, 45, 202, 86, 181, 160, 40, 124, 221, 226, 118, + 123, 183, 204, 45, 101, 225, 70, 63, 119, 206, 144, 7, 150, 144, 217, 99, 86, 72, 5, 201, 78, 229, + 209, 108, 112, 143 }; + +static HcfBlob g_sm2PointUncompressedBlob = { + .data = g_sm2PointUncompressedBlobData, + .len = SM2_POINT_UNCOMPRESSED_SIZE +}; + +static uint8_t g_sm2PointCompressedBlobData[] = { 3, 232, 131, 204, 172, 46, 67, 127, 51, 64, 4, 236, 190, 110, 155, + 221, 220, 226, 224, 249, 236, 223, 146, 39, 255, 109, 226, 6, 209, 45, 202, 86, 181 }; + +static HcfBlob g_sm2PointCompressedBlob = { + .data = g_sm2PointCompressedBlobData, + .len = SM2_POINT_COMPRESSED_SIZE +}; + +// ECC_BrainPoolP256r1 public and private key data +constexpr size_t P256R1_PUBKEY_DATA_SIZE = 92; +constexpr size_t P256R1_PRIKEY_DATA_SIZE = 52; +constexpr size_t P256R1_POINT_DATA_SIZE = 65; + +static uint8_t g_p256r1PubKeyBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, 3, 3, 2, + 8, 1, 1, 7, 3, 66, 0, 4, 143, 39, 57, 249, 145, 50, 63, 222, 35, 70, 178, 121, 202, 154, 21, 146, 129, 75, 76, 63, + 8, 195, 157, 111, 40, 217, 215, 148, 120, 224, 205, 82, 83, 92, 185, 21, 211, 184, 5, 19, 114, 33, 86, 85, 228, + 123, 242, 206, 200, 98, 178, 184, 130, 35, 232, 45, 5, 202, 189, 11, 46, 163, 156, 152 }; + +static uint8_t g_p256r1PriKeyBlobData[] = { 48, 50, 2, 1, 1, 4, 32, 165, 118, 226, 8, 158, 142, 142, 244, 62, 181, + 245, 172, 27, 114, 153, 198, 201, 164, 46, 69, 119, 172, 231, 66, 110, 83, 17, 161, 225, 119, 127, 126, 160, 11, + 6, 9, 43, 36, 3, 3, 2, 8, 1, 1, 7 }; + +// Modify the first parameter of the x coordinate +static uint8_t g_p256r1ModifyPubKeyBlobData[] = { 48, 90, 48, 20, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 9, 43, 36, 3, + 3, 2, 8, 1, 1, 7, 3, 66, 0, 4, 3, 39, 57, 249, 145, 50, 63, 222, 35, 70, 178, 121, 202, 154, 21, 146, 129, 75, + 76, 63, 8, 195, 157, 111, 40, 217, 215, 148, 120, 224, 205, 82, 83, 92, 185, 21, 211, 184, 5, 19, 114, 33, 86, + 85, 228, 123, 242, 206, 200, 98, 178, 184, 130, 35, 232, 45, 5, 202, 189, 11, 46, 163, 156, 152 }; + +static uint8_t g_p256r1ModifyPointBlobData[] = { 4, 3, 39, 57, 249, 145, 50, 63, 222, 35, 70, 178, 121, 202, 154, + 21, 146, 129, 75, 76, 63, 8, 195, 157, 111, 40, 217, 215, 148, 120, 224, 205, 82, 83, 92, 185, 21, 211, 184, 5, + 19, 114, 33, 86, 85, 228, 123, 242, 206, 200, 98, 178, 184, 130, 35, 232, 45, 5, 202, 189, 11, 46, 163, 156, 152 }; + +static HcfBlob g_p256r1PubKeyBlob = { + .data = g_p256r1PubKeyBlobData, + .len = P256R1_PUBKEY_DATA_SIZE +}; + +static HcfBlob g_p256r1PriKeyBlob = { + .data = g_p256r1PriKeyBlobData, + .len = P256R1_PRIKEY_DATA_SIZE +}; + +static HcfBlob g_p256r1ModifyPubKeyBlob = { + .data = g_p256r1ModifyPubKeyBlobData, + .len = P256R1_PUBKEY_DATA_SIZE +}; + +static HcfBlob g_p256r1ModifyPointBlob = { + .data = g_p256r1ModifyPointBlobData, + .len = P256R1_POINT_DATA_SIZE +}; + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest001, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfSign *sign = nullptr; + HcfVerify *verify = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + + ret = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP256r1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, &g_p256r1PubKeyBlob, &g_p256r1PriKeyBlob, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = HcfSignCreate("ECC_BrainPoolP256r1|SHA256", &sign); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(sign, nullptr); + + ret = sign->init(sign, nullptr, keyPair->priKey); + EXPECT_EQ(ret, HCF_SUCCESS); + + ret = sign->update(sign, &g_inputOne); + EXPECT_EQ(ret, HCF_SUCCESS); + + ret = sign->sign(sign, &g_inputTwo, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = HcfVerifyCreate("ECC_BrainPoolP256r1|SHA256", &verify); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(verify, nullptr); + + ret = verify->init(verify, nullptr, keyPair->pubKey); + EXPECT_EQ(ret, HCF_SUCCESS); + + ret = verify->update(verify, &g_inputOne); + bool flag = verify->verify(verify, &g_inputTwo, &returnBlob); + EXPECT_EQ(flag, true); + + HcfObjDestroy(generator); + HcfObjDestroy(sign); + HcfObjDestroy(verify); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest002, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyAgreement *keyAgreement = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfKeyPair *outKeyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfBlob outBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP256r1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, &g_p256r1PubKeyBlob, &g_p256r1PriKeyBlob, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &outKeyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outKeyPair, nullptr); + + ret = HcfKeyAgreementCreate("ECC_BrainPoolP256r1", &keyAgreement); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyAgreement, nullptr); + + ret = keyAgreement->generateSecret(keyAgreement, outKeyPair->priKey, keyPair->pubKey, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = keyAgreement->generateSecret(keyAgreement, keyPair->priKey, outKeyPair->pubKey, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, &outBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(outKeyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + HcfBlobDataFree(&outBlob); + HcfObjDestroy(keyAgreement); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest003, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfConvertPoint("NID_sm2", &g_sm2PointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint("NID_sm2", &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, &g_sm2PointCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest004, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfConvertPoint("NID_sm2", &g_sm2PointCompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint("NID_sm2", &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, &g_sm2PointUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest005, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest006, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest007, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointCompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest008, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointCompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest009, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfPoint outPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, &returnBlob, &outPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outPoint.x.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + FreeEcPointMem(&outPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest010, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfPoint outPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, &returnBlob, &outPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outPoint.x.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + FreeEcPointMem(&outPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest011, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfKeyPair *outKeyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = generator->convertKey(generator, nullptr, &returnBlob, nullptr, &outKeyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outKeyPair, nullptr); + + HcfObjDestroy(outKeyPair); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest012, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfKeyPair *outKeyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = generator->convertKey(generator, nullptr, &returnBlob, nullptr, &outKeyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(outKeyPair, nullptr); + + HcfObjDestroy(outKeyPair); + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest013, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest014, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest015, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest016, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest017, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest018, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest019, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointCompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest020, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + AsyKeySpecItem itemPkX = ECC_PK_X_BN; + AsyKeySpecItem itemPkY = ECC_PK_Y_BN; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, PUBKEY_DATA_MAP[i].pubKeyCompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkX, &(returnPoint.x)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = keyPair->pubKey->getAsyKeySpecBigInteger(keyPair->pubKey, itemPkY, &(returnPoint.y)); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.y.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnBlob.len, 0); + + ret = CompareBlobEqual(&returnBlob, POINT_DATA_MAP[i].pointUncompressedBlob); + EXPECT_EQ(ret, HCF_SUCCESS); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +// Invalid input parameter +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest031, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP256r1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(nullptr, nullptr, &g_p256r1PubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(keyPair, nullptr); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest032, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("RSA512", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest033, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("DSA1024", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest034, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(nullptr, PUB_KEY_COMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest035, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(PUBKEY_DATA_MAP) / sizeof(PUBKEY_DATA_MAP[0]); i++) { + ret = HcfAsyKeyGeneratorCreate(PUBKEY_DATA_MAP[i].algoName, &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->generateKeyPair(generator, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, nullptr, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest036, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP256r1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, &g_p256r1ModifyPubKeyBlob, nullptr, &keyPair); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(keyPair, nullptr); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest037, TestSize.Level0) +{ + HcfAsyKeyGenerator *generator = nullptr; + HcfKeyPair *keyPair = nullptr; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfAsyKeyGeneratorCreate("ECC_BrainPoolP256r1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(generator, nullptr); + + ret = generator->convertKey(generator, nullptr, &g_p256t1PubKeyUncompressedBlob, nullptr, &keyPair); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(keyPair, nullptr); + + ret = keyPair->pubKey->getEncodedDer(keyPair->pubKey, PUB_KEY_UNCOMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + HcfObjDestroy(keyPair); + HcfObjDestroy(generator); + HcfBlobDataFree(&returnBlob); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest038, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfConvertPoint("NID_brainpoolP256r1", &g_p256r1ModifyPointBlob, &returnPoint); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnPoint.x.len, 0); + + FreeEcPointMem(&returnPoint); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest039, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfConvertPoint("NID_brainpoolP256t1", &g_p256r1PointUncompressedBlob, &returnPoint); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnPoint.x.len, 0); + + FreeEcPointMem(&returnPoint); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest040, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfResult ret = HCF_INVALID_PARAMS; + ret = HcfConvertPoint("NID_brainpoolP256t1", &g_p256r1PointCompressedBlob, &returnPoint); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnPoint.x.len, 0); + + FreeEcPointMem(&returnPoint); +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest041, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(PUBKEY_DATA_MAP[i].algoName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnPoint.x.len, 0); + + FreeEcPointMem(&returnPoint); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest042, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, PUBKEY_DATA_MAP[i].pubKeyUncompressedBlob, &returnPoint); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnPoint.x.len, 0); + + FreeEcPointMem(&returnPoint); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest043, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(PUBKEY_DATA_MAP[i].algoName, &returnPoint, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest044, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, "compress", &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest045, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, nullptr, POINT_COMPRESSED_FORMAT, &returnBlob); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +HWTEST_F(CryptoEccEcdhPubTest, CryptoEccEcdhPubTest046, TestSize.Level0) +{ + HcfPoint returnPoint = { .x = { .data = nullptr, .len = 0 }, .y = { .data = nullptr, .len = 0 } }; + HcfBlob returnBlob = { .data = nullptr, .len = 0 }; + HcfResult ret = HCF_INVALID_PARAMS; + for (uint32_t i = 0; i < sizeof(POINT_DATA_MAP) / sizeof(POINT_DATA_MAP[0]); i++) { + ret = HcfConvertPoint(POINT_DATA_MAP[i].curveName, POINT_DATA_MAP[i].pointUncompressedBlob, &returnPoint); + EXPECT_EQ(ret, HCF_SUCCESS); + EXPECT_NE(returnPoint.x.len, 0); + + ret = HcfGetEncodedPoint(POINT_DATA_MAP[i].curveName, &returnPoint, POINT_COMPRESSED_FORMAT, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + EXPECT_EQ(returnBlob.len, 0); + + FreeEcPointMem(&returnPoint); + HcfBlobDataFree(&returnBlob); + } +} + +} \ No newline at end of file diff --git a/test/unittest/src/ecc/ecc_asy_key_common.cpp b/test/unittest/src/ecc/ecc_asy_key_common.cpp index 9b104fcc75534ca05358bf7bde5fe97b0ed4ea4d..5abf90631f4abe5da2e092d1478b58627e908709 100644 --- a/test/unittest/src/ecc/ecc_asy_key_common.cpp +++ b/test/unittest/src/ecc/ecc_asy_key_common.cpp @@ -16,7 +16,6 @@ #include #include "securec.h" - #include "asy_key_generator.h" #include "detailed_ecc_key_params.h" #include "ecc_asy_key_common.h" diff --git a/test/unittest/src/openssl_adapter_mock.c b/test/unittest/src/openssl_adapter_mock.c index 295932207a63a80d01fbb8e5963f2cbb1f089f9e..0bab033436d334017b27d0929355069e61739d08 100644 --- a/test/unittest/src/openssl_adapter_mock.c +++ b/test/unittest/src/openssl_adapter_mock.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2022-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 @@ -15,6 +15,7 @@ #include "openssl_adapter.h" #include "openssl_adapter_mock.h" +#include #include "log.h" #include "result.h" @@ -1842,6 +1843,14 @@ int Openssl_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, pbits); } +int Openssl_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + if (Is_Need_Mock()) { + return -1; + } + return EVP_PKEY_CTX_set_signature_md(ctx, md); +} + int Openssl_DH_up_ref(DH *r) { if (Is_Need_Mock()) { @@ -1866,3 +1875,115 @@ int Openssl_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) return DH_set0_key(dh, pub_key, priv_key); } +size_t Openssl_EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + if (Is_Need_Mock()) { + return -1; + } + return EC_POINT_point2oct(group, p, form, buf, len, ctx); +} + +OSSL_PARAM_BLD *Openssl_OSSL_PARAM_BLD_new(void) +{ + if (Is_Need_Mock()) { + return NULL; + } + return OSSL_PARAM_BLD_new(); +} + +void Openssl_OSSL_PARAM_BLD_free(OSSL_PARAM_BLD *bld) +{ + if (bld != NULL) { + OSSL_PARAM_BLD_free(bld); + } +} + +OSSL_PARAM *Openssl_OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld) +{ + if (Is_Need_Mock()) { + return NULL; + } + return OSSL_PARAM_BLD_to_param(bld); +} + +int Openssl_OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key, const char *buf, size_t bsize) +{ + if (Is_Need_Mock()) { + return -1; + } + return OSSL_PARAM_BLD_push_utf8_string(bld, key, buf, bsize); +} + +int Openssl_OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD *bld, const char *key, const void *buf, size_t bsize) +{ + if (Is_Need_Mock()) { + return -1; + } + return OSSL_PARAM_BLD_push_octet_string(bld, key, buf, bsize); +} + +int Openssl_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) +{ + if (Is_Need_Mock()) { + return -1; + } + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); +} + +int Openssl_EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx) +{ + if (Is_Need_Mock()) { + return -1; + } + return EVP_PKEY_fromdata_init(ctx); +} + +int Openssl_EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection, OSSL_PARAM params[]) +{ + if (Is_Need_Mock()) { + return -1; + } + return EVP_PKEY_fromdata(ctx, ppkey, selection, params); +} + +EC_KEY *Openssl_EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + if (Is_Need_Mock()) { + return NULL; + } + return EVP_PKEY_get1_EC_KEY(pkey); +} + +void Openssl_OSSL_PARAM_free(OSSL_PARAM *params) +{ + if (params != NULL) { + OSSL_PARAM_free(params); + } +} + +int Openssl_EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + if (Is_Need_Mock()) { + return -1; + } + return EC_POINT_oct2point(group, p, buf, len, ctx); +} + +int Openssl_EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) +{ + if (Is_Need_Mock()) { + return -1; + } + return EC_POINT_set_affine_coordinates(group, p, x, y, ctx); +} + +int Openssl_EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) +{ + if (Is_Need_Mock()) { + return -1; + } + return EC_POINT_get_affine_coordinates(group, p, x, y, ctx); +} \ No newline at end of file diff --git a/test/unittest/src/sm2/crypto_sm2_asy_key_generator_by_spec_sub_test.cpp b/test/unittest/src/sm2/crypto_sm2_asy_key_generator_by_spec_sub_test.cpp index d37d92f7ccefec042bf356c48fdc49a7fba60cd3..9d9e456d2b812f371eff81ae7469f89b460c5284 100644 --- a/test/unittest/src/sm2/crypto_sm2_asy_key_generator_by_spec_sub_test.cpp +++ b/test/unittest/src/sm2/crypto_sm2_asy_key_generator_by_spec_sub_test.cpp @@ -774,7 +774,7 @@ HWTEST_F(CryptoSm2AsyKeyGeneratorBySpecSubTest, CryptoSm2AsyKeyGeneratorBySpecTe ASSERT_NE(keyPair, nullptr); uint8_t plan[] = "this is sm2 cipher test!\0"; - HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan)}; + HcfBlob input = {.data = (uint8_t *)plan, .len = strlen((char *)plan) + 1}; HcfBlob encoutput = {.data = nullptr, .len = 0}; HcfCipher *cipher = nullptr; res = HcfCipherCreate("SM2|SM3", &cipher); diff --git a/test/unittest/src/sm2/crypto_sm2_util_test.cpp b/test/unittest/src/sm2/crypto_sm2_util_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10dd410f0f683216a3b21f6f88a20386348800e1 --- /dev/null +++ b/test/unittest/src/sm2/crypto_sm2_util_test.cpp @@ -0,0 +1,582 @@ +/* + * 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 "securec.h" +#include "blob.h" +#include "cipher_sm2_crypto_util_openssl.h" +#include "sm2_crypto_util.h" +#include "log.h" +#include "memory.h" +#include "cstring" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoSm2UtilTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoSm2UtilTest::SetUp() {} +void CryptoSm2UtilTest::TearDown() {} +void CryptoSm2UtilTest::SetUpTestCase() {} +void CryptoSm2UtilTest::TearDownTestCase() {} + +static const char *g_sm2ModeC1C3C2 = "C1C3C2"; +static const char *g_sm2ModeError = "C1C2C2"; +static const int CORRECT_INPUT_LEN = 121; +static const int ERROR_INPUT_LEN = 12; +static const int INPUT_LEN_ZERO = 0; +static uint8_t g_mockCorrectInput[CORRECT_INPUT_LEN] = { + 48, 119, 2, 33, 0, 183, 70, 70, 149, 188, 64, 6, 110, 236, 85, 149, 216, 224, 102, 95, 92, 41, 105, 232, 5, + 248, 122, 21, 174, 43, 226, 221, 104, 82, 88, 153, 45, 2, 32, 96, 229, 78, 209, 233, 110, 5, 149, 91, 110, + 109, 181, 17, 75, 109, 146, 128, 170, 113, 205, 158, 193, 156, 90, 110, 40, 18, 119, 247, 198, 93, 107, 4, + 32, 87, 167, 167, 247, 88, 146, 203, 234, 83, 126, 117, 129, 52, 142, 82, 54, 152, 226, 201, 111, 143, 115, + 169, 125, 128, 42, 157, 31, 114, 198, 109, 244, 4, 14, 100, 227, 78, 195, 249, 179, 43, 70, 242, 69, 169, 10, + 65, 123 +}; +static HcfBlob g_correctInput = { + .data = g_mockCorrectInput, + .len = CORRECT_INPUT_LEN +}; +static HcfBlob g_errorInput = { + .data = g_mockCorrectInput, + .len = ERROR_INPUT_LEN +}; +static const int X_COORDINATE_LEN = 32; +static unsigned char g_xCoordinate[] = { + 45, 153, 88, 82, 104, 221, 226, 43, 174, 21, 122, 248, 5, 232, 105, 41, 92, 95, 102, 224, 216, 149, 85, 236, + 110, 6, 64, 188, 149, 70, 70, 183 +}; +static const int Y_COORDINATE_LEN = 32; +static unsigned char g_yCoordinate[] = { + 107, 93, 198, 247, 119, 18, 40, 110, 90, 156, 193, 158, 205, 113, 170, 128, 146, 109, 75, 17, 181, 109, 110, + 91, 149, 5, 110, 233, 209, 78, 229, 96 +}; +static const int HASH_DATA_LEN = 32; +static const int ERROR_HASH_DATA_LEN = 15; +static unsigned char g_hashData[] = { + 87, 167, 167, 247, 88, 146, 203, 234, 83, 126, 117, 129, 52, 142, 82, 54, 152, 226, 201, 111, 143, 115, 169, + 125, 128, 42, 157, 31, 114, 198, 109, 244 +}; +static const int CIPHER_TEXT_DATA_LEN = 14; +static unsigned char g_cipherTextData[] = { + 100, 227, 78, 195, 249, 179, 43, 70, 242, 69, 169, 10, 65, 123 +}; + +HcfResult ConstructCorrectSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructMissYErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructMissXErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructMissHashDataErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructMissCipherDataErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructLenErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + // hashData.len != 32 + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = ERROR_HASH_DATA_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructLenZeroXSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = INPUT_LEN_ZERO; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructLenZeroYSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = INPUT_LEN_ZERO; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructLenZeroCipherDataSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = INPUT_LEN_ZERO; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = HASH_DATA_LEN; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructLenZeroHashDataSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + tempSpec->xCoordinate.data = g_xCoordinate; + tempSpec->xCoordinate.len = X_COORDINATE_LEN; + tempSpec->yCoordinate.data = g_yCoordinate; + tempSpec->yCoordinate.len = Y_COORDINATE_LEN; + tempSpec->cipherTextData.data = g_cipherTextData; + tempSpec->cipherTextData.len = CIPHER_TEXT_DATA_LEN; + tempSpec->hashData.data = g_hashData; + tempSpec->hashData.len = INPUT_LEN_ZERO; + *spec = tempSpec; + return HCF_SUCCESS; +} + +HcfResult ConstructMissErrorSm2CipherTextSpec(Sm2CipherTextSpec **spec) +{ + Sm2CipherTextSpec *tempSpec = static_cast(HcfMalloc(sizeof(Sm2CipherTextSpec), 0)); + if (tempSpec == nullptr) { + return HCF_ERR_MALLOC; + } + *spec = tempSpec; + return HCF_SUCCESS; +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest001, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec success, case mode = C1C3C2 + int res = 0; + Sm2CipherTextSpec *spec = nullptr; + res = ConstructCorrectSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_SUCCESS); + res = memcmp(output.data, g_correctInput.data, g_correctInput.len); + HcfBlobDataFree(&output); + HcfFree(spec); + EXPECT_EQ(res, 0); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest002, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec success, case mode = null + int res = 0; + Sm2CipherTextSpec *spec = nullptr; + res = ConstructCorrectSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, NULL, &output); + EXPECT_EQ(res, HCF_SUCCESS); + res = memcmp(output.data, g_correctInput.data, g_correctInput.len); + HcfBlobDataFree(&output); + HcfFree(spec); + EXPECT_EQ(res, 0); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest003, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case mode = C1C2C2 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructCorrectSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeError, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest004, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec miss yCoordinate + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissYErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest005, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec hashData.len != 32 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructLenErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest006, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec miss xCoordinate + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissXErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest007, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec miss hashData + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissHashDataErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest008, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec miss cipherData + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissCipherDataErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest009, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case output is null + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructCorrectSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, NULL); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest010, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec is null + HcfBlob output = { .data = nullptr, .len = 0 }; + HcfResult res = HcfGenCipherTextBySpec(nullptr, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest011, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec xCoordinate.len = 0 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructLenZeroXSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest012, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec yCoordinate.len = 0 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructLenZeroYSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest013, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec cipherTextData.len = 0 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructLenZeroCipherDataSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest014, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec hashData.len = 0 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructLenZeroHashDataSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest015, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case spec null construct + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfGenCipherTextBySpec(spec, g_sm2ModeC1C3C2, &output); + EXPECT_EQ(res, HCF_INVALID_PARAMS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest101, TestSize.Level0) +{ + // test HcfGetCipherTextSpec success, case mode = C1C3C2 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfGetCipherTextSpec(&g_correctInput, g_sm2ModeC1C3C2, &spec); + EXPECT_EQ(res, HCF_SUCCESS); + DestroySm2CipherTextSpec(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest102, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec success, case mode = null + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfGetCipherTextSpec(&g_correctInput, NULL, &spec); + EXPECT_EQ(res, HCF_SUCCESS); + DestroySm2CipherTextSpec(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest103, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec error, case mode = C1C2C2 + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfGetCipherTextSpec(&g_correctInput, g_sm2ModeError, &spec); + EXPECT_EQ(res, HCF_INVALID_PARAMS); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest104, TestSize.Level0) +{ + // test HcfGetCipherTextSpec error, case input null + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfGetCipherTextSpec(NULL, g_sm2ModeC1C3C2, &spec); + EXPECT_EQ(res, HCF_INVALID_PARAMS); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest105, TestSize.Level0) +{ + // test HcfGetCipherTextSpec error, case input error len + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfGetCipherTextSpec(&g_errorInput, g_sm2ModeC1C3C2, &spec); + EXPECT_EQ(res, HCF_ERR_CRYPTO_OPERATION); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest106, TestSize.Level0) +{ + // test HcfGetCipherTextSpec error, case returnSpec is null + HcfResult res = HcfGetCipherTextSpec(&g_correctInput, g_sm2ModeC1C3C2, NULL); + EXPECT_EQ(res, HCF_INVALID_PARAMS); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest201, TestSize.Level0) +{ + // test HcfSm2SpecToAsn1 success + int res = 0; + Sm2CipherTextSpec *spec = nullptr; + res = ConstructCorrectSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfSm2SpecToAsn1(spec, &output); + EXPECT_EQ(res, HCF_SUCCESS); + res = memcmp(output.data, g_correctInput.data, g_correctInput.len); + HcfBlobDataFree(&output); + HcfFree(spec); + EXPECT_EQ(res, 0); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest202, TestSize.Level0) +{ + // test HcfSm2SpecToAsn1 success, case spec miss yCoordinate + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissYErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfSm2SpecToAsn1(spec, &output); + EXPECT_EQ(res, HCF_SUCCESS); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest203, TestSize.Level0) +{ + // test HcfSm2SpecToAsn1 success, case spec miss xCoordinate + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissXErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfSm2SpecToAsn1(spec, &output); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlobDataFree(&output); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest204, TestSize.Level0) +{ + // test HcfSm2SpecToAsn1 success, case spec miss hashData + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissHashDataErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfSm2SpecToAsn1(spec, &output); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlobDataFree(&output); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest205, TestSize.Level0) +{ + // test HcfGenCipherTextBySpec success, case spec miss cipherData + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = ConstructMissCipherDataErrorSm2CipherTextSpec(&spec); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlob output = { .data = nullptr, .len = 0 }; + res = HcfSm2SpecToAsn1(spec, &output); + EXPECT_EQ(res, HCF_SUCCESS); + HcfBlobDataFree(&output); + HcfFree(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest301, TestSize.Level0) +{ + // test HcfAsn1ToSm2Spec success + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfAsn1ToSm2Spec(&g_correctInput, &spec); + EXPECT_EQ(res, HCF_SUCCESS); + DestroySm2CipherTextSpec(spec); +} + +HWTEST_F(CryptoSm2UtilTest, CryptoSm2UtilTest305, TestSize.Level0) +{ + // test HcfAsn1ToSm2Spec error, case input error len + Sm2CipherTextSpec *spec = nullptr; + HcfResult res = HcfAsn1ToSm2Spec(&g_errorInput, &spec); + EXPECT_EQ(res, HCF_ERR_CRYPTO_OPERATION); +} +} \ No newline at end of file