From 329c271124943b7306d233b15a0afb62b8bfc0a4 Mon Sep 17 00:00:00 2001 From: lcc Date: Thu, 1 Feb 2024 20:24:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E3=80=90=E7=AE=97=E6=B3=95=E5=BA=93?= =?UTF-8?q?=E9=80=82=E9=85=8D=E5=B1=82=E3=80=91=E7=AE=97=E6=B3=95=E5=BA=93?= =?UTF-8?q?=E9=80=82=E9=85=8D=E5=B1=82=E6=8F=90=E4=BE=9BJS=E5=AF=B9?= =?UTF-8?q?=E7=A7=B0=E5=AF=86=E9=92=A5=E7=94=9F=E6=88=90=E8=83=BD=E5=8A=9B?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E6=AD=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lcc --- .../napi/crypto/inc/napi_sym_key_generator.h | 2 + .../crypto/src/napi_sym_key_generator.cpp | 120 ++++++++++++++++++ 2 files changed, 122 insertions(+) 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 92f6591..e1cda31 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/src/napi_sym_key_generator.cpp b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp index 918ac65..9903c79 100644 --- a/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp +++ b/frameworks/js/napi/crypto/src/napi_sym_key_generator.cpp @@ -335,6 +335,61 @@ 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; + 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 && argc != expectedArgc - 1) { + LOGE("wrong argument num. require 0 or 1 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; + } + + HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator(); + if (generator == nullptr) { + LOGE("failed to get generator obj!"); + return nullptr; + } + + HcfSymKey *key = nullptr; + HcfResult ret = generator->generateSymKey(generator, &key); + if (ret != HCF_SUCCESS) { + LOGE("generate sym key failed."); + return nullptr; + } + + napi_value instance = NapiSymKey::CreateSymKey(env); + 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."); + return nullptr; + } + + 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 nullptr; + } + + return instance; +} + napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info) { SymKeyGeneratorFwkCtx context = static_cast(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0)); @@ -360,6 +415,69 @@ 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_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); + if (argc != expectedArgc && argc != expectedArgc - 1) { + 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) { + LOGE("get keyMaterial failed!"); + return nullptr; + } + + HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator(); + if (generator == nullptr) { + 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) { + LOGE("convertSymKey key failed!"); + return nullptr; + } + + napi_value instance = NapiSymKey::CreateSymKey(env); + 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."); + return nullptr; + } + + 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 nullptr; + } + return instance; +} + napi_value NapiSymKeyGenerator::SymKeyGeneratorConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -451,7 +569,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; -- Gitee From 1708f4cdc171809e9fa7238ad599ac1a462cf1ea Mon Sep 17 00:00:00 2001 From: lcc Date: Thu, 22 Feb 2024 10:42:37 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=B0=81=E8=A3=85Openssl=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=90=91=E4=B8=8A=E6=8F=90=E4=BE=9BHKDF=E5=AF=86?= =?UTF-8?q?=E9=92=A5=E6=B4=BE=E7=94=9F=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lcc --- common/inc/params_parser.h | 10 + common/src/params_parser.c | 4 + frameworks/crypto_operation/kdf.c | 29 ++ .../inc/napi_crypto_framework_defines.h | 6 + frameworks/js/napi/crypto/src/napi_kdf.cpp | 86 ++++ .../detailed_hkdf_params.h | 32 ++ .../common/inc/openssl_adapter.h | 6 + .../common/src/openssl_adapter.c | 25 ++ .../crypto_operation/kdf/inc/hkdf_openssl.h | 31 ++ .../crypto_operation/kdf/src/hkdf_openssl.c | 402 ++++++++++++++++++ plugin/plugin.gni | 1 + 11 files changed, 632 insertions(+) create mode 100644 interfaces/innerkits/algorithm_parameter/detailed_hkdf_params.h create mode 100644 plugin/openssl_plugin/crypto_operation/kdf/inc/hkdf_openssl.h create mode 100644 plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index 8fd6422..2fdc7fb 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -44,6 +44,7 @@ typedef enum { HCF_ALG_ED25519, HCF_ALG_X25519, HCF_ALG_DH, + HCF_ALG_HKDF, } HcfAlgValue; typedef enum { @@ -165,6 +166,14 @@ typedef enum { HCF_OPENSSL_DH_FFDHE_4096, HCF_OPENSSL_DH_FFDHE_6144, HCF_OPENSSL_DH_FFDHE_8192, + + // key derivation function, HKDF + HCF_ALG_HKDF_DEFAULT, + + // hkdf mode + HCF_ALG_MODE_EXTRACT_AND_EXPAND = 0, + HCF_ALG_MODE_EXTRACT_ONLY, + HCF_ALG_MODE_EXPAND_ONLY, } HcfAlgParaValue; typedef struct { @@ -212,6 +221,7 @@ typedef struct { typedef struct { HcfAlgValue algo; // algType HcfAlgParaValue md; + HcfAlgParaValue mode; } HcfKdfDeriveParams; typedef HcfResult (*SetParameterFunc) (const HcfParaConfig* config, void *params); diff --git a/common/src/params_parser.c b/common/src/params_parser.c index ab7f8fe..ed652e5 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -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}, diff --git a/frameworks/crypto_operation/kdf.c b/frameworks/crypto_operation/kdf.c index fe95cf5..a6c4183 100644 --- a/frameworks/crypto_operation/kdf.c +++ b/frameworks/crypto_operation/kdf.c @@ -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,27 @@ static void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) kdf->md = value; } +// static HcfResult GetPaddingMode(HcfCipherSm4GeneratorSpiOpensslImpl* cipherImpl) +// { +// switch (cipherImpl->attr.paddingMode) { +// case HCF_ALG_MODE_EXTRACT_AND_EXPAND: +// break; +// case HCF_ALG_PADDING_PKCS5: +// return EVP_PADDING_PKCS7; +// case HCF_ALG_PADDING_PKCS7: +// return EVP_PADDING_PKCS7; +// default: +// LOGE("No Params!"); +// break; +// } +// return HCF_SUCCESS; +// } + +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 +96,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 +108,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/js/napi/crypto/inc/napi_crypto_framework_defines.h b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h index bf20906..7a6ff74 100644 --- a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h +++ b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h @@ -86,6 +86,12 @@ 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 HKDF_ALG_NAME = "HKDF"; +const std::string HKDF_PARAMS_SALT = "salt"; +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/src/napi_kdf.cpp b/frameworks/js/napi/crypto/src/napi_kdf.cpp index 2d1626c..2f6422b 100644 --- a/frameworks/js/napi/crypto/src/napi_kdf.cpp +++ b/frameworks/js/napi/crypto/src/napi_kdf.cpp @@ -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 @@ -125,7 +126,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); @@ -270,6 +275,18 @@ 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 *tmp) +{ + tmp->output = out; + tmp->salt.data = salt->data; + tmp->salt.len = salt->len; + tmp->key.data = key.data; + tmp->key.len = key.len; + tmp->info.data = info->data; + tmp->info.len = info->len; + tmp->base.algName = HKDF_ALG_NAME.c_str(); +} + static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { // get attribute from params @@ -324,6 +341,71 @@ static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec * return false; } +static bool GetHKDFParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) +{ + // get attribute from params + // int attribute + int keySize = -1; + if (!GetInt32FromPBKDF2Params(env, arg, PBKDF2_PARAMS_KEY_SIZE, keySize)) { + LOGE("failed to get valid num"); + return false; + } + if (keySize <= 0) { + LOGE("iter and 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 *tmp = nullptr; + do { + // get key + if (!GetPasswordFromPBKDF2Params(env, arg, HKDF_PARAMS_KEY, &key)) { + LOGE("failed to get key"); + break; + } + + // get info + info = GetBlobFromPBKDF2ParamsSpec(env, arg, HKDF_PARAMS_INFO); + if (info == nullptr) { + LOGE("fail to get info"); + break; + } + + // get salt attribute + salt = GetBlobFromPBKDF2ParamsSpec(env, arg, HKDF_PARAMS_SALT); + if (salt == nullptr) { + LOGE("fail to get salt"); + break; + } + // malloc params + tmp = static_cast(HcfMalloc(sizeof(HcfHKDFParamsSpec), 0)); + if (tmp == nullptr) { + LOGE("hkdf spec malloc failed!"); + break; + } + SetHKDFParamsSpecAttribute(out, salt, key, info, tmp); + // only need the data and data length of the salt, so free the blob pointer. + HcfFree(salt); + HcfFree(info); + *params = reinterpret_cast(tmp); + 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 +428,9 @@ 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; @@ -494,6 +579,7 @@ napi_value NapiKdf::CreateJsKdf(napi_env env, napi_callback_info info) return nullptr; } HcfKdf *kdf = nullptr; + LOGE("----------------create %s kdf obj .", algoName.c_str()); HcfResult res = HcfKdfCreate(algoName.c_str(), &kdf); if (res != HCF_SUCCESS) { napi_throw(env, GenerateBusinessError(env, res, "create C obj failed.")); 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 0000000..e464a45 --- /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/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index feeeb58..c2e9fb6 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -313,6 +314,11 @@ int Openssl_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) 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); +int Openssl_EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); +int Openssl_EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen); +int Openssl_EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const unsigned char *key, int keylen); +int Openssl_EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const unsigned char *info, int infolen); #ifdef __cplusplus } diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index b48c03e..36f89be 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -1292,4 +1292,29 @@ 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); +} + +int Openssl_EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) +{ + return EVP_PKEY_CTX_set_hkdf_mode(ctx, mode); +} + +int Openssl_EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_set_hkdf_md(ctx, md); +} + +int Openssl_EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen) +{ + return EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, saltlen); +} + +int Openssl_EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const unsigned char *key, int keylen) +{ + return EVP_PKEY_CTX_set1_hkdf_key(ctx, key, keylen); +} + +int Openssl_EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const unsigned char *info, int infolen) +{ + return EVP_PKEY_CTX_add1_hkdf_info(ctx, info, infolen); } \ No newline at end of file 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 0000000..b1094ae --- /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 0000000..7e4e42e --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c @@ -0,0 +1,402 @@ +/* + * 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 "detailed_hkdf_params.h" +#include "openssl/kdf.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; + const EVP_MD *digestAlg; + int mode; + HcfHkdfData *kdfData; +} OpensslHkdfSpiImpl; + +static const char *EngineGetKdfClass(void) +{ + return "OpensslHkdf"; +} + +static void HcfClearAndFreeUnsignedChar(unsigned char *blob, int len) +{ + // when blob == null, len must be 0; in check func, len >= 0 + if (blob == NULL) { + LOGD("The input blob is null, no need to free."); + return; + } + (void)memset_s(blob, len, 0, len); + HcfFree(blob); +} + +static void FreeKdfData(HcfHkdfData **data) +{ + if (data == NULL || *data == NULL) { + return; + } + if ((*data)->out != NULL) { + HcfClearAndFreeUnsignedChar((*data)->out, (*data)->outLen); + (*data)->out = NULL; + (*data)->outLen = 0; + } + if ((*data)->salt != NULL) { + HcfClearAndFreeUnsignedChar((*data)->salt, (*data)->saltLen); + (*data)->salt = NULL; + (*data)->saltLen = 0; + } + if ((*data)->info != NULL) { + HcfClearAndFreeUnsignedChar((*data)->info, (*data)->infoLen); + (*data)->info = NULL; + (*data)->infoLen = 0; + } + if ((*data)->key != NULL) { + HcfClearAndFreeUnsignedChar((*data)->key, (*data)->keyLen); + (*data)->key = NULL; + (*data)->keyLen = 0; + } + 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; + FreeKdfData(&(impl->kdfData)); + impl->digestAlg = NULL; + 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; + } + // when params password == nullptr, the size will be set 0 by openssl; + if (params->output.data == NULL || params->output.len == 0) { + LOGE("invalid output"); + return false; + } + if (params->salt.data == NULL && params->salt.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->key.data == NULL && params->key.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->info.data == NULL && params->info.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->salt.data != NULL && params->salt.len != 0) { + return true; + } + return false; +} + +static bool GetHKDFSaltFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->salt.data != NULL) { + 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; + } else { + data->salt = NULL; + data->saltLen = 0; + } + return true; +} + +static bool GetHKDFKeyFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->key.data != NULL) { + 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; + } else { + data->key = NULL; + data->keyLen = 0; + } + return true; +} + +static bool GetHKDFInfoFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->info.data != NULL) { + 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; + } else { + data->info = NULL; + data->infoLen = 0; + } + return true; +} + + +static HcfResult InitHKDFData(OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + HcfHkdfData *data = (HcfHkdfData *)HcfMalloc(sizeof(HcfHkdfData), 0); + do { + if (data == NULL) { + LOGE("malloc data failed"); + break; + } + if (!GetHKDFKeyFromSpec(data, params)) { + LOGE("key malloc failed!"); + break; + } + if (!GetHKDFSaltFromSpec(data, params)) { + LOGE("salt malloc failed!"); + break; + } + if (!GetHKDFInfoFromSpec(data, params)) { + LOGE("info malloc failed!"); + break; + } + data->out = (unsigned char *)HcfMalloc(params->output.len, 0); + if (data->out == NULL) { + LOGE("out malloc failed!"); + break; + } + data->outLen = params->output.len; + self->kdfData = data; + return HCF_SUCCESS; + } while (0); + FreeKdfData(&data); + return HCF_ERR_MALLOC; +} + +static int HKDF(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + LOGD("mode is EXTRACT_AND_EXPAND"); + HcfHkdfData *data = self->kdfData; + if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { + LOGE("PKEY_derive_init filed"); + return HCF_INVALID_PARAMS; + } + LOGE("mode is %d", self->mode); + if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, self->mode) <= 0) { + LOGE("PKEY_CTX_set_hkdf_mode filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { + LOGE("PKEY_CTX_set_hkdf_md filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_salt(pctx, data->salt, data->saltLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_salt filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_key filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_add1_hkdf_info(pctx, data->info, data->infoLen) <= 0) { + LOGE("PKEY_CTX_add1_hkdf_info filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive start"); + if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ + LOGE("EVP_PKEY_derive filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive end"); + + (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); + return HCF_SUCCESS; +} + +static int HKDF_Extract(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + LOGD("mode is EXTRACT"); + HcfHkdfData *data = self->kdfData; + if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { + LOGE("PKEY_derive_init filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, self->mode) <= 0) { + LOGE("PKEY_CTX_set_hkdf_mode filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { + LOGE("PKEY_CTX_set_hkdf_md filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_salt(pctx, data->salt, data->saltLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_salt filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_key filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive start"); + if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ + LOGE("EVP_PKEY_derive filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive end"); + (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); + return HCF_SUCCESS; + +} + +static int HKDF_Expand(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + LOGD("mode is EXPAND"); + HcfHkdfData *data = self->kdfData; + if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { + LOGE("PKEY_derive_init filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, self->mode) <= 0) { + LOGE("PKEY_CTX_set_hkdf_mode filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { + LOGE("PKEY_CTX_set_hkdf_md filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_key filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_add1_hkdf_info(pctx, data->info, data->infoLen) <= 0) { + LOGE("PKEY_CTX_add1_hkdf_info filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive start"); + if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ + LOGE("EVP_PKEY_derive filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive end"); + (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); + return HCF_SUCCESS; +} + +static HcfResult OpensslHKDF(OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + EVP_PKEY_CTX *pctx = Openssl_EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + switch (self->mode) + { + case HCF_ALG_MODE_EXTRACT_AND_EXPAND: + default: + return HKDF(pctx, self, params); + + case HCF_ALG_MODE_EXTRACT_ONLY: + return HKDF_Extract(pctx, self, params); + + case HCF_ALG_MODE_EXPAND_ONLY: + return HKDF_Expand(pctx, self, params); + } + EVP_PKEY_CTX_free(pctx); +} + +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 HCF_INVALID_PARAMS; + } + res = OpensslHKDF(hkdfImpl, params); + FreeKdfData(&(hkdfImpl->kdfData)); + return res; +} + +HcfResult HcfKdfHKDFSpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj) +{ + if (params == NULL || spiObj == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + EVP_MD *md = NULL; + HcfResult res = GetOpensslDigestAlg(params->md, &md); + if (res != HCF_SUCCESS || md == NULL) { + LOGE("get md failed"); + 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 = md; + returnSpiImpl->mode = params->mode; + *spiObj = (HcfKdfSpi *)returnSpiImpl; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 4ed4b8d..35b6ecf 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -88,6 +88,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 + -- Gitee From 1d3779aefd828db2ab50098b7e9d59a1e6448cef Mon Sep 17 00:00:00 2001 From: lcc Date: Thu, 22 Feb 2024 10:42:37 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=B0=81=E8=A3=85Openssl=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=90=91=E4=B8=8A=E6=8F=90=E4=BE=9BHKDF=E5=AF=86?= =?UTF-8?q?=E9=92=A5=E6=B4=BE=E7=94=9F=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lcc --- common/inc/params_parser.h | 10 + common/src/params_parser.c | 4 + frameworks/crypto_operation/kdf.c | 13 + .../inc/napi_crypto_framework_defines.h | 6 + frameworks/js/napi/crypto/src/napi_kdf.cpp | 86 ++++ .../detailed_hkdf_params.h | 32 ++ .../common/inc/openssl_adapter.h | 6 + .../common/src/openssl_adapter.c | 25 ++ .../crypto_operation/kdf/inc/hkdf_openssl.h | 31 ++ .../crypto_operation/kdf/src/hkdf_openssl.c | 417 ++++++++++++++++++ plugin/plugin.gni | 1 + 11 files changed, 631 insertions(+) create mode 100644 interfaces/innerkits/algorithm_parameter/detailed_hkdf_params.h create mode 100644 plugin/openssl_plugin/crypto_operation/kdf/inc/hkdf_openssl.h create mode 100644 plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c diff --git a/common/inc/params_parser.h b/common/inc/params_parser.h index 8fd6422..760ea2d 100644 --- a/common/inc/params_parser.h +++ b/common/inc/params_parser.h @@ -44,6 +44,7 @@ typedef enum { HCF_ALG_ED25519, HCF_ALG_X25519, HCF_ALG_DH, + HCF_ALG_HKDF, } HcfAlgValue; typedef enum { @@ -165,6 +166,14 @@ typedef enum { HCF_OPENSSL_DH_FFDHE_4096, HCF_OPENSSL_DH_FFDHE_6144, HCF_OPENSSL_DH_FFDHE_8192, + + // 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 struct { @@ -212,6 +221,7 @@ typedef struct { typedef struct { HcfAlgValue algo; // algType HcfAlgParaValue md; + HcfAlgParaValue mode; } HcfKdfDeriveParams; typedef HcfResult (*SetParameterFunc) (const HcfParaConfig* config, void *params); diff --git a/common/src/params_parser.c b/common/src/params_parser.c index ab7f8fe..ed652e5 100644 --- a/common/src/params_parser.c +++ b/common/src/params_parser.c @@ -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}, diff --git a/frameworks/crypto_operation/kdf.c b/frameworks/crypto_operation/kdf.c index fe95cf5..aa8a1b4 100644 --- a/frameworks/crypto_operation/kdf.c +++ b/frameworks/crypto_operation/kdf.c @@ -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/js/napi/crypto/inc/napi_crypto_framework_defines.h b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h index bf20906..7a6ff74 100644 --- a/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h +++ b/frameworks/js/napi/crypto/inc/napi_crypto_framework_defines.h @@ -86,6 +86,12 @@ 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 HKDF_ALG_NAME = "HKDF"; +const std::string HKDF_PARAMS_SALT = "salt"; +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/src/napi_kdf.cpp b/frameworks/js/napi/crypto/src/napi_kdf.cpp index 2d1626c..2f6422b 100644 --- a/frameworks/js/napi/crypto/src/napi_kdf.cpp +++ b/frameworks/js/napi/crypto/src/napi_kdf.cpp @@ -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 @@ -125,7 +126,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); @@ -270,6 +275,18 @@ 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 *tmp) +{ + tmp->output = out; + tmp->salt.data = salt->data; + tmp->salt.len = salt->len; + tmp->key.data = key.data; + tmp->key.len = key.len; + tmp->info.data = info->data; + tmp->info.len = info->len; + tmp->base.algName = HKDF_ALG_NAME.c_str(); +} + static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) { // get attribute from params @@ -324,6 +341,71 @@ static bool GetPBKDF2ParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec * return false; } +static bool GetHKDFParamsSpec(napi_env env, napi_value arg, HcfKdfParamsSpec **params) +{ + // get attribute from params + // int attribute + int keySize = -1; + if (!GetInt32FromPBKDF2Params(env, arg, PBKDF2_PARAMS_KEY_SIZE, keySize)) { + LOGE("failed to get valid num"); + return false; + } + if (keySize <= 0) { + LOGE("iter and 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 *tmp = nullptr; + do { + // get key + if (!GetPasswordFromPBKDF2Params(env, arg, HKDF_PARAMS_KEY, &key)) { + LOGE("failed to get key"); + break; + } + + // get info + info = GetBlobFromPBKDF2ParamsSpec(env, arg, HKDF_PARAMS_INFO); + if (info == nullptr) { + LOGE("fail to get info"); + break; + } + + // get salt attribute + salt = GetBlobFromPBKDF2ParamsSpec(env, arg, HKDF_PARAMS_SALT); + if (salt == nullptr) { + LOGE("fail to get salt"); + break; + } + // malloc params + tmp = static_cast(HcfMalloc(sizeof(HcfHKDFParamsSpec), 0)); + if (tmp == nullptr) { + LOGE("hkdf spec malloc failed!"); + break; + } + SetHKDFParamsSpecAttribute(out, salt, key, info, tmp); + // only need the data and data length of the salt, so free the blob pointer. + HcfFree(salt); + HcfFree(info); + *params = reinterpret_cast(tmp); + 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 +428,9 @@ 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; @@ -494,6 +579,7 @@ napi_value NapiKdf::CreateJsKdf(napi_env env, napi_callback_info info) return nullptr; } HcfKdf *kdf = nullptr; + LOGE("----------------create %s kdf obj .", algoName.c_str()); HcfResult res = HcfKdfCreate(algoName.c_str(), &kdf); if (res != HCF_SUCCESS) { napi_throw(env, GenerateBusinessError(env, res, "create C obj failed.")); 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 0000000..e464a45 --- /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/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index feeeb58..c2e9fb6 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -313,6 +314,11 @@ int Openssl_EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) 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); +int Openssl_EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); +int Openssl_EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen); +int Openssl_EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const unsigned char *key, int keylen); +int Openssl_EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const unsigned char *info, int infolen); #ifdef __cplusplus } diff --git a/plugin/openssl_plugin/common/src/openssl_adapter.c b/plugin/openssl_plugin/common/src/openssl_adapter.c index b48c03e..36f89be 100644 --- a/plugin/openssl_plugin/common/src/openssl_adapter.c +++ b/plugin/openssl_plugin/common/src/openssl_adapter.c @@ -1292,4 +1292,29 @@ 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); +} + +int Openssl_EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) +{ + return EVP_PKEY_CTX_set_hkdf_mode(ctx, mode); +} + +int Openssl_EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return EVP_PKEY_CTX_set_hkdf_md(ctx, md); +} + +int Openssl_EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen) +{ + return EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt, saltlen); +} + +int Openssl_EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, const unsigned char *key, int keylen) +{ + return EVP_PKEY_CTX_set1_hkdf_key(ctx, key, keylen); +} + +int Openssl_EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, const unsigned char *info, int infolen) +{ + return EVP_PKEY_CTX_add1_hkdf_info(ctx, info, infolen); } \ No newline at end of file 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 0000000..b1094ae --- /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 0000000..b6cd582 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/kdf/src/hkdf_openssl.c @@ -0,0 +1,417 @@ +/* + * 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 "detailed_hkdf_params.h" +#include "openssl/kdf.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; + const EVP_MD *digestAlg; + int mode; + HcfHkdfData *kdfData; +} OpensslHkdfSpiImpl; + +static const char *EngineGetKdfClass(void) +{ + return "OpensslHkdf"; +} + +static void HcfClearAndFreeUnsignedChar(unsigned char *blob, int len) +{ + // when blob == null, len must be 0; in check func, len >= 0 + if (blob == NULL) { + LOGD("The input blob is null, no need to free."); + return; + } + (void)memset_s(blob, len, 0, len); + HcfFree(blob); +} + +static void FreeKdfData(HcfHkdfData **data) +{ + if (data == NULL || *data == NULL) { + return; + } + if ((*data)->out != NULL) { + HcfClearAndFreeUnsignedChar((*data)->out, (*data)->outLen); + (*data)->out = NULL; + (*data)->outLen = 0; + } + if ((*data)->salt != NULL) { + HcfClearAndFreeUnsignedChar((*data)->salt, (*data)->saltLen); + (*data)->salt = NULL; + (*data)->saltLen = 0; + } + if ((*data)->info != NULL) { + HcfClearAndFreeUnsignedChar((*data)->info, (*data)->infoLen); + (*data)->info = NULL; + (*data)->infoLen = 0; + } + if ((*data)->key != NULL) { + HcfClearAndFreeUnsignedChar((*data)->key, (*data)->keyLen); + (*data)->key = NULL; + (*data)->keyLen = 0; + } + 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; + FreeKdfData(&(impl->kdfData)); + impl->digestAlg = NULL; + 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; + } + // when params password == nullptr, the size will be set 0 by openssl; + if (params->output.data == NULL || params->output.len == 0) { + LOGE("invalid output"); + return false; + } + if (params->salt.data == NULL && params->salt.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->key.data == NULL && params->key.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->info.data == NULL && params->info.len == 0) { + LOGD("empty salt"); + return true; + } + if (params->salt.data != NULL && params->salt.len != 0) { + return true; + } + return false; +} + +static bool GetHKDFSaltFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->salt.data != NULL) { + 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; + } else { + data->salt = NULL; + data->saltLen = 0; + } + return true; +} + +static bool GetHKDFKeyFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->key.data != NULL) { + 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; + } else { + data->key = NULL; + data->keyLen = 0; + } + return true; +} + +static bool GetHKDFInfoFromSpec(HcfHkdfData *data, HcfHKDFParamsSpec *params) +{ + if (params->info.data != NULL) { + 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; + } else { + data->info = NULL; + data->infoLen = 0; + } + return true; +} + +static HcfResult 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; + } + return HCF_SUCCESS; +} + +static HcfResult InitHKDFData(OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + HcfHkdfData *data = (HcfHkdfData *)HcfMalloc(sizeof(HcfHkdfData), 0); + do { + if (data == NULL) { + LOGE("malloc data failed"); + break; + } + if (!GetHKDFKeyFromSpec(data, params)) { + LOGE("key malloc failed!"); + break; + } + if (!GetHKDFSaltFromSpec(data, params)) { + LOGE("salt malloc failed!"); + break; + } + if (!GetHKDFInfoFromSpec(data, params)) { + LOGE("info malloc failed!"); + break; + } + data->out = (unsigned char *)HcfMalloc(params->output.len, 0); + if (data->out == NULL) { + LOGE("out malloc failed!"); + break; + } + data->outLen = params->output.len; + self->kdfData = data; + return HCF_SUCCESS; + } while (0); + FreeKdfData(&data); + return HCF_ERR_MALLOC; +} + +static int HKDF(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + LOGD("mode is EXTRACT_AND_EXPAND"); + HcfHkdfData *data = self->kdfData; + if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { + LOGE("PKEY_derive_init filed"); + return HCF_INVALID_PARAMS; + } + LOGE("mode is %d", self->mode); + if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, GetHkdfMode(self)) <= 0) { + LOGE("PKEY_CTX_set_hkdf_mode filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { + LOGE("PKEY_CTX_set_hkdf_md filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_salt(pctx, data->salt, data->saltLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_salt filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { + LOGE("PKEY_CTX_set1_hkdf_key filed"); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_PKEY_CTX_add1_hkdf_info(pctx, data->info, data->infoLen) <= 0) { + LOGE("PKEY_CTX_add1_hkdf_info filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive start"); + if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ + LOGE("EVP_PKEY_derive filed"); + return HCF_INVALID_PARAMS; + } + LOGD("EVP_PKEY_derive end"); + + (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); + return HCF_SUCCESS; +} + +// static int HKDF_Extract(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +// { +// LOGD("mode is EXTRACT"); +// HcfHkdfData *data = self->kdfData; +// if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { +// LOGE("PKEY_derive_init filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, self->mode) <= 0) { +// LOGE("PKEY_CTX_set_hkdf_mode filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { +// LOGE("PKEY_CTX_set_hkdf_md filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set1_hkdf_salt(pctx, data->salt, data->saltLen) <= 0) { +// LOGE("PKEY_CTX_set1_hkdf_salt filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { +// LOGE("PKEY_CTX_set1_hkdf_key filed"); +// return HCF_INVALID_PARAMS; +// } +// LOGD("EVP_PKEY_derive start"); +// if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ +// LOGE("EVP_PKEY_derive filed"); +// return HCF_INVALID_PARAMS; +// } +// LOGD("EVP_PKEY_derive end"); +// (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); +// return HCF_SUCCESS; + +// } + +// static int HKDF_Expand(EVP_PKEY_CTX *pctx, OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +// { +// LOGD("mode is EXPAND"); +// HcfHkdfData *data = self->kdfData; +// if (Openssl_EVP_PKEY_derive_init(pctx) <= 0) { +// LOGE("PKEY_derive_init filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set_hkdf_mode(pctx, self->mode) <= 0) { +// LOGE("PKEY_CTX_set_hkdf_mode filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set_hkdf_md(pctx, self->digestAlg) <= 0) { +// LOGE("PKEY_CTX_set_hkdf_md filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_set1_hkdf_key(pctx, data->key, data->keyLen) <= 0) { +// LOGE("PKEY_CTX_set1_hkdf_key filed"); +// return HCF_INVALID_PARAMS; +// } +// if (Openssl_EVP_PKEY_CTX_add1_hkdf_info(pctx, data->info, data->infoLen) <= 0) { +// LOGE("PKEY_CTX_add1_hkdf_info filed"); +// return HCF_INVALID_PARAMS; +// } +// LOGD("EVP_PKEY_derive start"); +// if (Openssl_EVP_PKEY_derive(pctx, data->out, (size_t *)(&(data->outLen))) <=0){ +// LOGE("EVP_PKEY_derive filed"); +// return HCF_INVALID_PARAMS; +// } +// LOGD("EVP_PKEY_derive end"); +// (void)memcpy_s(params->output.data, data->outLen, data->out, data->outLen); +// return HCF_SUCCESS; +// } + +static HcfResult OpensslHKDF(OpensslHkdfSpiImpl *self, HcfHKDFParamsSpec *params) +{ + EVP_PKEY_CTX *pctx = Openssl_EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); + return HKDF(pctx, self, params); + EVP_PKEY_CTX_free(pctx); + // switch (self->mode) + // { + // case HCF_ALG_MODE_EXTRACT_AND_EXPAND: + // default: + // return HKDF(pctx, self, params); + + // case HCF_ALG_MODE_EXTRACT_ONLY: + // return HKDF_Extract(pctx, self, params); + + // case HCF_ALG_MODE_EXPAND_ONLY: + // return HKDF_Expand(pctx, self, params); + // } +} + +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 HCF_INVALID_PARAMS; + } + res = OpensslHKDF(hkdfImpl, params); + FreeKdfData(&(hkdfImpl->kdfData)); + return res; +} + +HcfResult HcfKdfHKDFSpiCreate(HcfKdfDeriveParams *params, HcfKdfSpi **spiObj) +{ + if (params == NULL || spiObj == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + EVP_MD *md = NULL; + HcfResult res = GetOpensslDigestAlg(params->md, &md); + if (res != HCF_SUCCESS || md == NULL) { + LOGE("get md failed"); + 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 = md; + returnSpiImpl->mode = params->mode; + *spiObj = (HcfKdfSpi *)returnSpiImpl; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/plugin.gni b/plugin/plugin.gni index 4ed4b8d..35b6ecf 100644 --- a/plugin/plugin.gni +++ b/plugin/plugin.gni @@ -88,6 +88,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 + -- Gitee