diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index d51625a2be67463518f7118580fd01afd9eb114b..15b9fd621b858f83b7a1975841f5714979c6f383 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -49,6 +49,7 @@ typedef enum { HCF_ALG_DH, HCF_ALG_HKDF, HCF_ALG_SCRYPT, + HCF_ALG_X963KDF, } HcfAlgValue; typedef enum { @@ -180,6 +181,7 @@ typedef enum { // key derivation function, HKDF HCF_ALG_HKDF_DEFAULT, HCF_ALG_SCRYPT_DEFAULT, + HCF_ALG_X963KDF_DEFAULT, // hkdf mode HCF_ALG_MODE_EXTRACT_AND_EXPAND, diff --git a/common/src/params_parser.c b/common/src/params_parser.c index 07da92623143f0e72dc5db88eb652a7696d79bbf..6731f450c27b21b9de17980703469d4fcec58d02 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -114,6 +114,7 @@ static const HcfParaConfig PARAM_CONFIG[] = { {"PBKDF2", HCF_ALG_TYPE, HCF_ALG_PBKDF2_DEFAULT}, {"HKDF", HCF_ALG_TYPE, HCF_ALG_HKDF_DEFAULT}, {"SCRYPT", HCF_ALG_TYPE, HCF_ALG_SCRYPT_DEFAULT}, + {"X963KDF", HCF_ALG_TYPE, HCF_ALG_X963KDF_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}, diff --git a/frameworks/crypto_operation/kdf.c b/frameworks/crypto_operation/kdf.c index 1d8cc95a74ce6d19dcf17a688fe50cd6b417ec46..969a745cfa2159332e22711d1022621ccc47b730 100644 --- a/frameworks/crypto_operation/kdf.c +++ b/frameworks/crypto_operation/kdf.c @@ -25,6 +25,7 @@ #include "pbkdf2_openssl.h" #include "hkdf_openssl.h" #include "scrypt_openssl.h" +#include "x963kdf_openssl.h" #include "utils.h" typedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **); @@ -52,6 +53,9 @@ static void SetKdfType(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) case HCF_ALG_SCRYPT_DEFAULT: kdf->algo = HCF_ALG_SCRYPT; break; + case HCF_ALG_X963KDF_DEFAULT: + kdf->algo = HCF_ALG_X963KDF; + break; default: LOGE("Invalid algo %{public}u.", value); break; @@ -98,6 +102,7 @@ static const HcfKdfGenAbility KDF_ABILITY_SET[] = { { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate }, { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate}, { HCF_ALG_SCRYPT, HcfKdfScryptSpiCreate }, + { HCF_ALG_X963KDF, HcfKdfX963SpiCreate }, }; static HcfKdfSpiCreateFunc FindAbility(HcfKdfDeriveParams* params) 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 76f8605985e7cf24d0ae417bf5a034682d82afab..8592c818fa11e89aae236126ea53d66b59a036a3 100644 --- a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h +++ b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h @@ -101,8 +101,9 @@ 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"; +const std::string KDF_PARAMS_KEY = "key"; +const std::string KDF_PARAMS_INFO = "info"; +const std::string X963KDF_ALG_NAME = "X963KDF"; const std::string MD_NAME = "mdName"; const std::string CIPHER_NAME = "cipherName"; diff --git a/frameworks/js/napi/crypto/src/napi_kdf.cpp b/frameworks/js/napi/crypto/src/napi_kdf.cpp index 19e50c7ed66076195aa9ef24b1522409d1ebb525..c7de3c5abb616c0a2f9917c172683ecef0af74de 100644 --- a/frameworks/js/napi/crypto/src/napi_kdf.cpp +++ b/frameworks/js/napi/crypto/src/napi_kdf.cpp @@ -23,6 +23,7 @@ #include "detailed_pbkdf2_params.h" #include "detailed_hkdf_params.h" #include "detailed_scrypt_params.h" +#include "detailed_x963kdf_params.h" #define PBKDF2_ALG_SIZE 6 @@ -154,8 +155,10 @@ static void KdfGenSecretComplete(napi_env env, napi_status status, void *data) } else if (SCRYPT_ALG_NAME.compare(context->paramsSpec->algName) == 0) { HcfScryptParamsSpec *params = reinterpret_cast(context->paramsSpec); returnBlob = ConvertBlobToNapiValue(env, &(params->output)); + } else if (X963KDF_ALG_NAME.compare(context->paramsSpec->algName) == 0) { + HcfX963KDFParamsSpec *params = reinterpret_cast(context->paramsSpec); + returnBlob = ConvertBlobToNapiValue(env, &(params->output)); } - if (returnBlob == nullptr) { LOGE("returnOutBlob is nullptr!"); returnBlob = NapiGetNull(env); @@ -333,6 +336,15 @@ static void SetScryptParamsSpecAttribute(const HcfBlob &out, const HcfBlob *salt tmpParams->base.algName = SCRYPT_ALG_NAME.c_str(); } +static void SetX963ParamsSpecAttribute(const HcfBlob &out, const HcfBlob &key, const HcfBlob *info, + HcfX963KDFParamsSpec *tmpParams) +{ + tmpParams->output = out; + tmpParams->key = key; + tmpParams->info = *info; + tmpParams->base.algName = X963KDF_ALG_NAME.c_str(); +} + static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { // get attribute from params @@ -413,13 +425,13 @@ static bool GetHkdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **p HcfHkdfParamsSpec *tmpParams = nullptr; do { // get key - if (!GetKeyOrPwdFromKdfParams(env, arg, HKDF_PARAMS_KEY, &key)) { + if (!GetKeyOrPwdFromKdfParams(env, arg, KDF_PARAMS_KEY, &key)) { LOGE("failed to get key"); break; } // get info态salt - info = GetBlobFromKdfParamsSpec(env, arg, HKDF_PARAMS_INFO); + info = GetBlobFromKdfParamsSpec(env, arg, KDF_PARAMS_INFO); salt = GetBlobFromKdfParamsSpec(env, arg, KDF_PARAMS_SALT); if (info == nullptr || salt == nullptr) { LOGE("fail to get info or salt"); @@ -526,6 +538,53 @@ static bool GetScryptParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec * return true; } +static bool GetX963ParamsSpec(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 key = { .data = nullptr, .len = 0 }; + HcfBlob *info = nullptr; + HcfX963KDFParamsSpec *tmpParams = nullptr; + do { + if (!GetKeyOrPwdFromKdfParams(env, arg, KDF_PARAMS_KEY, &key)) { + LOGE("failed to get key"); + break; + } + info = GetBlobFromKdfParamsSpec(env, arg, KDF_PARAMS_INFO); + if (info == nullptr) { + LOGE("fail to get info"); + break; + } + tmpParams = static_cast(HcfMalloc(sizeof(HcfX963KDFParamsSpec), 0)); + if (tmpParams == nullptr) { + LOGE("x963kdf spec malloc failed!"); + break; + } + SetX963ParamsSpecAttribute(out, key, info, tmpParams); + HCF_FREE_PTR(info); + *params = reinterpret_cast(tmpParams); + return true; + } while (0); + HcfBlobDataClearAndFree(info); + HCF_FREE_PTR(info); + HCF_FREE_PTR(out.data); + return false; +} + static bool GetKdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { napi_value data = nullptr; @@ -552,6 +611,8 @@ static bool GetKdfParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **pa return GetHkdfParamsSpec(env, arg, params); } else if (algoName.compare(SCRYPT_ALG_NAME) == 0) { return GetScryptParamsSpec(env, arg, params); + } else if (algoName.compare(X963KDF_ALG_NAME) == 0) { + return GetX963ParamsSpec(env, arg, params); } else { LOGE("Not support that alg"); return false; @@ -668,6 +729,9 @@ static napi_value NewKdfJsGenSecretSyncWork(napi_env env, HcfKdfParamsSpec *para } else if (SCRYPT_ALG_NAME.compare(paramsSpec->algName) == 0) { HcfScryptParamsSpec *params = reinterpret_cast(paramsSpec); returnBlob = ConvertBlobToNapiValue(env, &(params->output)); + } else if (X963KDF_ALG_NAME.compare(paramsSpec->algName) == 0) { + HcfX963KDFParamsSpec *params = reinterpret_cast(paramsSpec); + returnBlob = ConvertBlobToNapiValue(env, &(params->output)); } if (returnBlob == nullptr) { LOGE("returnBlob is nullptr!"); diff --git a/interfaces/inner_api/algorithm_parameter/detailed_x963kdf_params.h b/interfaces/inner_api/algorithm_parameter/detailed_x963kdf_params.h new file mode 100644 index 0000000000000000000000000000000000000000..913a1733bf949148bd9c77fbb78bc5437eb6716a --- /dev/null +++ b/interfaces/inner_api/algorithm_parameter/detailed_x963kdf_params.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2025 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_X963KDF_PARAMS_H +#define HCF_DETAILED_X963KDF_PARAMS_H + +#include "blob.h" +#include "kdf_params.h" + +typedef struct HcfX963KDFParamsSpec HcfX963KDFParamsSpec; + +struct HcfX963KDFParamsSpec { + HcfKdfParamsSpec base; + HcfBlob key; + HcfBlob info; + HcfBlob output; +}; + +#endif // HCF_DETAILED_X963KDF_PARAMS_H + \ No newline at end of file diff --git a/plugin/openssl_plugin.map b/plugin/openssl_plugin.map index 6a189088690a5257e7320a2f93d604a4c6454c13..d5a63250cca8fd0d5171ec0b0ecfd2d26f0c7683 100644 --- a/plugin/openssl_plugin.map +++ b/plugin/openssl_plugin.map @@ -37,6 +37,7 @@ HcfKdfPBKDF2SpiCreate; HcfKdfHkdfSpiCreate; HcfKdfScryptSpiCreate; + HcfKdfX963SpiCreate; HcfAsn1ToSm2Spec; HcfSm2SpecToAsn1; HcfDerDataToSm2Spec; diff --git a/plugin/openssl_plugin/crypto_operation/kdf/inc/x963kdf_openssl.h b/plugin/openssl_plugin/crypto_operation/kdf/inc/x963kdf_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..020a9286a7736783780c52c24b9740c7cbc44812 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/inc/x963kdf_openssl.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2025 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_X963KDF_OPENSSL_H +#define HCF_X963KDF_OPENSSL_H + +#include "kdf_spi.h" +#include "params_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif +HcfResult HcfKdfX963SpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/kdf/src/x963kdf_openssl.c b/plugin/openssl_plugin/crypto_operation/kdf/src/x963kdf_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..13c79a4f84ca64a4fb471a2b1f647ada1ee6db8e --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/src/x963kdf_openssl.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2025 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 "x963kdf_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_x963kdf_params.h" + +#define X963KDF_ALG_NAME "X963KDF" + +typedef struct { + unsigned char *key; + int keyLen; + unsigned char *info; + int infoLen; + unsigned char *out; + int outLen; +} HcfX963KDFData; + +typedef struct { + HcfKdfSpi base; + int digestAlg; + HcfX963KDFData *kdfData; +} OpensslX963KDFSpiImpl; + +static const char *EngineGetKdfClass(void) +{ + return "OpensslX963KDF"; +} + +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 FreeX963KDFData(HcfX963KDFData **data) +{ + if (data == NULL || *data == NULL) { + return; + } + HcfClearAndFree((*data)->out, (*data)->outLen); + (*data)->out = NULL; + (*data)->outLen = 0; + HcfClearAndFree((*data)->info, (*data)->infoLen); + (*data)->info = NULL; + (*data)->infoLen = 0; + HcfClearAndFree((*data)->key, (*data)->keyLen); + (*data)->key = NULL; + (*data)->keyLen = 0; + (void)memset_s(*data, sizeof(HcfX963KDFData), 0, sizeof(HcfX963KDFData)); + HcfFree(*data); + *data = NULL; +} + +static void EngineDestroyKdf(HcfObjectBase *self) +{ + if (self == NULL) { + LOGE("Self ptr is NULL!"); + return; + } + if (!HcfIsClassMatch(self, EngineGetKdfClass())) { + LOGE("Class is not match."); + return; + } + OpensslX963KDFSpiImpl *impl = (OpensslX963KDFSpiImpl *)self; + FreeX963KDFData(&(impl->kdfData)); + HcfFree(self); +} + +static bool CheckX963KDFParams(HcfX963KDFParamsSpec *params) +{ + // openssl only support INT and blob attribute is size_t, it should samller than INT_MAX. + if (params->output.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->info.data == NULL && params->info.len == 0) { + LOGD("empty info"); + } + return true; +} + +static bool GetX963KDFKeyFromSpec(HcfX963KDFData *data, HcfX963KDFParamsSpec *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 bool GetX963KDFInfoFromSpec(OpensslX963KDFSpiImpl *self, HcfX963KDFData *data, HcfX963KDFParamsSpec *params) +{ + 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 HcfResult InitX963KDFData(OpensslX963KDFSpiImpl *self, HcfX963KDFParamsSpec *params) +{ + HcfX963KDFData *data = (HcfX963KDFData *)HcfMalloc(sizeof(HcfX963KDFData), 0); + do { + if (data == NULL) { + LOGE("malloc data failed"); + break; + } + if (!GetX963KDFKeyFromSpec(data, params)) { + LOGE("malloc key failed!"); + break; + } + if (!GetX963KDFInfoFromSpec(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); + FreeX963KDFData(&data); + return HCF_ERR_MALLOC; +} + +static HcfResult CheckX963KDFDigest(OpensslX963KDFSpiImpl *self) +{ + if (self->digestAlg == HCF_OPENSSL_DIGEST_MD5 || self->digestAlg == HCF_OPENSSL_DIGEST_SM3) { + LOGE("MD5 and SM3 are not supported"); + return HCF_NOT_SUPPORT; + } + return HCF_SUCCESS; +} + +static char *SwitchMd(OpensslX963KDFSpiImpl *self) +{ + switch (self->digestAlg) { + case HCF_OPENSSL_DIGEST_NONE: + return ""; + 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 OpensslX963KDF(OpensslX963KDFSpiImpl *self, HcfBlob *output) +{ + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *kctx = NULL; + // need set 6 params + OSSL_PARAM params[5] = {}; + OSSL_PARAM *p = params; + HcfResult res = CheckX963KDFDigest(self); + if (res != HCF_SUCCESS) { + LOGE("CheckX963KDFDigest failed"); + return res; + } + + kdf = OpensslEvpKdfFetch(NULL, "X963KDF", NULL); + if (kdf == NULL) { + LOGE("kdf fetch failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + kctx = OpensslEvpKdfCtxNew(kdf); + OpensslEvpKdfFree(kdf); + if (kctx == NULL) { + LOGE("kdf ctx new failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + char *digest = SwitchMd(self); + *p++ = OpensslOsslParamConstructUtf8String("digest", digest, 0); + *p++ = OpensslOsslParamConstructOctetString("key", self->kdfData->key, self->kdfData->keyLen); + *p++ = OpensslOsslParamConstructOctetString("info", self->kdfData->info, self->kdfData->infoLen); + *p = OpensslOsslParamConstructEnd(); + if (OpensslEvpKdfDerive(kctx, output->data, output->len, params) <= 0) { + HcfPrintOpensslError(); + LOGE("EVP_KDF_derive failed"); + OpensslEvpKdfCtxFree(kctx); + return HCF_ERR_CRYPTO_OPERATION; + } + OpensslEvpKdfCtxFree(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 (!HcfIsClassMatch((HcfObjectBase *)self, EngineGetKdfClass())) { + return HCF_INVALID_PARAMS; + } + OpensslX963KDFSpiImpl *x963kdfImpl = (OpensslX963KDFSpiImpl *)self; + if (paramsSpec->algName == NULL || strcmp(paramsSpec->algName, X963KDF_ALG_NAME) != 0) { + LOGE("Not x963kdf paramsSpec"); + return HCF_INVALID_PARAMS; + } + HcfX963KDFParamsSpec *params = (HcfX963KDFParamsSpec *)paramsSpec; + if (!CheckX963KDFParams(params)) { + LOGE("params error"); + return HCF_INVALID_PARAMS; + } + HcfResult res = InitX963KDFData(x963kdfImpl, params); + if (res != HCF_SUCCESS) { + LOGE("InitCipherData failed!"); + return res; + } + res = OpensslX963KDF(x963kdfImpl, ¶ms->output); + FreeX963KDFData(&(x963kdfImpl->kdfData)); + return res; +} + +HcfResult HcfKdfX963SpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj) +{ + if (params == NULL || spiObj == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + OpensslX963KDFSpiImpl *returnSpiImpl = (OpensslX963KDFSpiImpl *)HcfMalloc(sizeof(OpensslX963KDFSpiImpl), 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; + *spiObj = (HcfKdfSpi *)returnSpiImpl; + return HCF_SUCCESS; +} diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 87194ef19aaf3f9a3da646b99ee171708693bbda..14de019387660cd58b86c2bb423caf675d64dcb4 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -94,6 +94,7 @@ 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_path}/openssl_plugin/crypto_operation/kdf/src/scrypt_openssl.c", + "${plugin_path}/openssl_plugin/crypto_operation/kdf/src/x963kdf_openssl.c" ] plugin_files = plugin_asy_key_generator_files + plugin_key_agreement_files + diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index eeafe0ba60d704d9524c40bbd61d83a8bf60fc3d..b1c3f2d7c714a951f6acbe52795c21026e0bbe8d 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -106,6 +106,7 @@ ohos_unittest("crypto_framework_test") { "src/crypto_x25519_asy_key_generator_by_spec_test.cpp", "src/crypto_x25519_asy_key_generator_test.cpp", "src/crypto_x25519_key_agreement_test.cpp", + "src/crypto_x963kdf_test.cpp", "src/ecc/crypto_ecc_asy_key_generator_by_spec_sub_four_test.cpp", "src/ecc/crypto_ecc_asy_key_generator_by_spec_sub_one_test.cpp", "src/ecc/crypto_ecc_asy_key_generator_by_spec_sub_three_test.cpp", diff --git a/test/unittest/src/crypto_x963kdf_test.cpp b/test/unittest/src/crypto_x963kdf_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03c48ffd61eb963801e366a2119ab77e5c73283b --- /dev/null +++ b/test/unittest/src/crypto_x963kdf_test.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2025 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 "x963kdf_openssl.h" + +#include +#include "securec.h" + +#include "detailed_x963kdf_params.h" +#include "kdf.h" +#include "log.h" +#include "memory.h" + +using namespace std; +using namespace testing::ext; + +namespace { +class CryptoX963KdfTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void CryptoX963KdfTest::SetUpTestCase() {} +void CryptoX963KdfTest::TearDownTestCase() {} + +void CryptoX963KdfTest::SetUp() // add init here, this will be called before test. +{ +} + +void CryptoX963KdfTest::TearDown() // add destroy here, this will be called when test case done. +{ +} + +static const char *g_keyData = "012345678901234567890123456789"; +static const char *g_infoData = "infostring"; + + +constexpr uint32_t OUT_PUT_MAX_LENGTH = 128; +constexpr uint32_t OUT_PUT_NORMAL_LENGTH = 32; + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTest1, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = reinterpret_cast(const_cast(g_keyData)), + .len = strlen(g_keyData)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(g_infoData)), + .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfErrTest1, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = reinterpret_cast(const_cast(g_keyData)), + .len = strlen(g_keyData)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(g_infoData)), + .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + generator->base.destroy(nullptr); + ret = generator->generateSecret(nullptr, &(params.base)); + EXPECT_EQ(ret, HCF_INVALID_PARAMS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTest2, TestSize.Level0) +{ + // mode is default, info data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = reinterpret_cast(const_cast(g_keyData)), + .len = strlen(g_keyData)}; + HcfBlob info = {.data = nullptr, .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTest4, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = reinterpret_cast(const_cast(g_keyData)), + .len = strlen(g_keyData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTest5, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|MD5", &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(g_keyData)), + .len = strlen(g_keyData)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(g_infoData)), + .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_NOT_SUPPORT); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTest6, TestSize.Level0) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = reinterpret_cast(const_cast(g_keyData)), + .len = strlen(g_keyData)}; + HcfBlob info = {.data = reinterpret_cast(const_cast(g_infoData)), + .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError1, TestSize.Level1) +{ + // mode is default, data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = nullptr, .len = 0}; + HcfBlob info = {.data = nullptr, .len = 0}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError2, TestSize.Level1) +{ + // mode is default, key data is nullptr + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|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 key = {.data = nullptr, .len = 0}; + HcfBlob info = {.data = reinterpret_cast(const_cast(g_infoData)), + .len = strlen(g_infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, &(params.base)); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError5, TestSize.Level1) +{ + // use basic params + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + HcfBlob key = {.data = nullptr, .len = 0}; + HcfBlob info = {.data = nullptr, .len = 0}; + HcfBlob output = {.data = nullptr, .len = 0}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .info = info, + .output = output, + }; + ret = generator->generateSecret(generator, (HcfKdfParamsSpec *)¶ms); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError6, TestSize.Level1) +{ + // use nullptr params + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|SHA256", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + ret = generator->generateSecret(generator, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError7, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|abcd", &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError8, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("ABCD|SM3", &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError9, TestSize.Level1) +{ + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate(nullptr, &generator); + EXPECT_NE(ret, HCF_SUCCESS); + HcfObjDestroy(generator); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestError10, TestSize.Level1) +{ + HcfResult ret = HcfKdfCreate(nullptr, nullptr); + EXPECT_NE(ret, HCF_SUCCESS); +} + +HWTEST_F(CryptoX963KdfTest, CryptoX963KdfTestVectors1, TestSize.Level1) +{ + uint8_t keyData[] = { 0x5e, 0xd0, 0x96, 0x51, 0x0e, 0x3f, 0xcf, 0x78, 0x2c, 0xee, 0xa9, 0x8e, 0x97, 0x37, 0x99, 0x3e, 0x2b, 0x21, 0x37, 0x0f, 0x6c, 0xda, 0x2a, 0xb1 }; + uint8_t infoData[] = {}; + uint8_t expectSecret[] = { 0xec, 0x3e, 0x22, 0x44, 0x46, 0xbf, 0xd7, 0xb3, 0xbe, 0x1d, 0xf4, 0x04, 0x10, 0x4a, 0xf9, 0x53 }; + + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|SHA1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[16] = {0}; + HcfBlob output = {.data = out, .len = 16}; + HcfBlob key = {.data = keyData, .len = sizeof(keyData)}; + HcfBlob info = {.data = infoData, .len = sizeof(infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .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(CryptoX963KdfTest, CryptoX963KdfTestVectors2, TestSize.Level1) +{ + uint8_t keyData[] = { 0xfd, 0x17, 0x19, 0x8b, 0x89, 0xab, 0x39, 0xc4, 0xab, 0x5d, 0x7c, 0xca, 0x36, 0x3b, 0x82, 0xf9, 0xfd, 0x7e, 0x23, 0xc3, 0x98, 0x4d, 0xc8, 0xa2 }; + uint8_t infoData[] = { 0x85, 0x6a, 0x53, 0xf3, 0xe3, 0x6a, 0x26, 0xbb, 0xc5, 0x79, 0x28, 0x79, 0xf3, 0x07, 0xcc, 0xe2 }; + uint8_t expectSecret[] = { 0x6e, 0x5f, 0xad, 0x86, 0x5c, 0xb4, 0xa5, 0x1c, 0x95, 0x20, 0x9b, 0x16, 0xdf, 0x0c, 0xc4, 0x90, 0xbc, 0x2c, 0x90, 0x64, 0x40, 0x5c, 0x5b, 0xcc, 0xd4, 0xee, 0x48, 0x32, 0xa5, 0x31, 0xfb, 0xe7, 0xf1, 0x0c, 0xb7, 0x9e, 0x2e, 0xab, 0x6a, 0xb1, 0x14, 0x9f, 0xbd, 0x5a, 0x23, 0xcf, 0xda, 0xbc, 0x41, 0x24, 0x22, 0x69, 0xc9, 0xdf, 0x22, 0xf6, 0x28, 0xc4, 0x42, 0x43, 0x33, 0x85, 0x5b, 0x64, 0xe9, 0x5e, 0x2d, 0x4f, 0xb8, 0x46, 0x9c, 0x66, 0x9f, 0x17, 0x17, 0x6c, 0x07, 0xd1, 0x03, 0x37, 0x6b, 0x10, 0xb3, 0x84, 0xec, 0x57, 0x63, 0xd8, 0xb8, 0xc6, 0x10, 0x40, 0x9f, 0x19, 0xac, 0xa8, 0xeb, 0x31, 0xf9, 0xd8, 0x5c, 0xc6, 0x1a, 0x8d, 0x6d, 0x4a, 0x03, 0xd0, 0x3e, 0x5a, 0x50, 0x6b, 0x78, 0xd6, 0x84, 0x7e, 0x93, 0xd2, 0x95, 0xee, 0x54, 0x8c, 0x65, 0xaf, 0xed, 0xd2, 0xef, 0xec }; + + HcfKdf *generator = nullptr; + HcfResult ret = HcfKdfCreate("X963KDF|SHA1", &generator); + EXPECT_EQ(ret, HCF_SUCCESS); + uint8_t out[128] = {0}; + HcfBlob output = {.data = out, .len = 128}; + HcfBlob key = {.data = keyData, .len = sizeof(keyData)}; + HcfBlob info = {.data = infoData, .len = sizeof(infoData)}; + HcfX963KDFParamsSpec params = { + .base = { .algName = "X963KDF", }, + .key = key, + .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); +} +}