11b8d9b87Sopenharmony_ci/* 21b8d9b87Sopenharmony_ci * Copyright (C) 2023-2024 Huawei Device Co., Ltd. 31b8d9b87Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 41b8d9b87Sopenharmony_ci * you may not use this file except in compliance with the License. 51b8d9b87Sopenharmony_ci * You may obtain a copy of the License at 61b8d9b87Sopenharmony_ci * 71b8d9b87Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 81b8d9b87Sopenharmony_ci * 91b8d9b87Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 101b8d9b87Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 111b8d9b87Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121b8d9b87Sopenharmony_ci * See the License for the specific language governing permissions and 131b8d9b87Sopenharmony_ci * limitations under the License. 141b8d9b87Sopenharmony_ci */ 151b8d9b87Sopenharmony_ci 161b8d9b87Sopenharmony_ci#include "kdf.h" 171b8d9b87Sopenharmony_ci 181b8d9b87Sopenharmony_ci#include <securec.h> 191b8d9b87Sopenharmony_ci#include "memory.h" 201b8d9b87Sopenharmony_ci 211b8d9b87Sopenharmony_ci#include "config.h" 221b8d9b87Sopenharmony_ci#include "kdf_spi.h" 231b8d9b87Sopenharmony_ci#include "log.h" 241b8d9b87Sopenharmony_ci#include "params_parser.h" 251b8d9b87Sopenharmony_ci#include "pbkdf2_openssl.h" 261b8d9b87Sopenharmony_ci#include "hkdf_openssl.h" 271b8d9b87Sopenharmony_ci#include "utils.h" 281b8d9b87Sopenharmony_ci 291b8d9b87Sopenharmony_citypedef HcfResult (*HcfKdfSpiCreateFunc)(HcfKdfDeriveParams *, HcfKdfSpi **); 301b8d9b87Sopenharmony_ci 311b8d9b87Sopenharmony_citypedef struct { 321b8d9b87Sopenharmony_ci HcfKdf base; 331b8d9b87Sopenharmony_ci HcfKdfSpi *spiObj; 341b8d9b87Sopenharmony_ci char algoName[HCF_MAX_ALGO_NAME_LEN]; 351b8d9b87Sopenharmony_ci} HcfKdfImpl; 361b8d9b87Sopenharmony_ci 371b8d9b87Sopenharmony_citypedef struct { 381b8d9b87Sopenharmony_ci HcfAlgValue algo; 391b8d9b87Sopenharmony_ci HcfKdfSpiCreateFunc createSpiFunc; 401b8d9b87Sopenharmony_ci} HcfKdfGenAbility; 411b8d9b87Sopenharmony_ci 421b8d9b87Sopenharmony_cistatic void SetKdfType(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 431b8d9b87Sopenharmony_ci{ 441b8d9b87Sopenharmony_ci switch (value) { 451b8d9b87Sopenharmony_ci case HCF_ALG_PBKDF2_DEFAULT: 461b8d9b87Sopenharmony_ci kdf->algo = HCF_ALG_PKBDF2; 471b8d9b87Sopenharmony_ci break; 481b8d9b87Sopenharmony_ci case HCF_ALG_HKDF_DEFAULT: 491b8d9b87Sopenharmony_ci kdf->algo = HCF_ALG_HKDF; 501b8d9b87Sopenharmony_ci break; 511b8d9b87Sopenharmony_ci default: 521b8d9b87Sopenharmony_ci LOGE("Invalid algo %u.", value); 531b8d9b87Sopenharmony_ci break; 541b8d9b87Sopenharmony_ci } 551b8d9b87Sopenharmony_ci} 561b8d9b87Sopenharmony_ci 571b8d9b87Sopenharmony_cistatic void SetDigest(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 581b8d9b87Sopenharmony_ci{ 591b8d9b87Sopenharmony_ci kdf->md = value; 601b8d9b87Sopenharmony_ci} 611b8d9b87Sopenharmony_ci 621b8d9b87Sopenharmony_cistatic void SetMode(HcfAlgParaValue value, HcfKdfDeriveParams *kdf) 631b8d9b87Sopenharmony_ci{ 641b8d9b87Sopenharmony_ci kdf->mode = value; 651b8d9b87Sopenharmony_ci} 661b8d9b87Sopenharmony_ci 671b8d9b87Sopenharmony_cistatic HcfResult ParseKdfParams(const HcfParaConfig *config, void *params) 681b8d9b87Sopenharmony_ci{ 691b8d9b87Sopenharmony_ci if (config == NULL || params == NULL) { 701b8d9b87Sopenharmony_ci LOGE("Invalid Kdf params"); 711b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 721b8d9b87Sopenharmony_ci } 731b8d9b87Sopenharmony_ci HcfResult ret = HCF_SUCCESS; 741b8d9b87Sopenharmony_ci HcfKdfDeriveParams *paramsObj = (HcfKdfDeriveParams *)params; 751b8d9b87Sopenharmony_ci LOGD("Set Parameter: %s", config->tag); 761b8d9b87Sopenharmony_ci switch (config->paraType) { 771b8d9b87Sopenharmony_ci case HCF_ALG_TYPE: 781b8d9b87Sopenharmony_ci SetKdfType(config->paraValue, paramsObj); 791b8d9b87Sopenharmony_ci break; 801b8d9b87Sopenharmony_ci case HCF_ALG_DIGEST: 811b8d9b87Sopenharmony_ci SetDigest(config->paraValue, paramsObj); 821b8d9b87Sopenharmony_ci break; 831b8d9b87Sopenharmony_ci case HCF_ALG_MODE: 841b8d9b87Sopenharmony_ci SetMode(config->paraValue, paramsObj); 851b8d9b87Sopenharmony_ci break; 861b8d9b87Sopenharmony_ci default: 871b8d9b87Sopenharmony_ci ret = HCF_INVALID_PARAMS; 881b8d9b87Sopenharmony_ci break; 891b8d9b87Sopenharmony_ci } 901b8d9b87Sopenharmony_ci return ret; 911b8d9b87Sopenharmony_ci} 921b8d9b87Sopenharmony_ci 931b8d9b87Sopenharmony_cistatic const HcfKdfGenAbility KDF_ABILITY_SET[] = { 941b8d9b87Sopenharmony_ci { HCF_ALG_PKBDF2, HcfKdfPBKDF2SpiCreate }, 951b8d9b87Sopenharmony_ci { HCF_ALG_HKDF, HcfKdfHkdfSpiCreate}, 961b8d9b87Sopenharmony_ci}; 971b8d9b87Sopenharmony_ci 981b8d9b87Sopenharmony_cistatic HcfKdfSpiCreateFunc FindAbility(HcfKdfDeriveParams* params) 991b8d9b87Sopenharmony_ci{ 1001b8d9b87Sopenharmony_ci for (uint32_t i = 0; i < (sizeof(KDF_ABILITY_SET) / sizeof(KDF_ABILITY_SET[0])); i++) { 1011b8d9b87Sopenharmony_ci if (KDF_ABILITY_SET[i].algo == params->algo) { 1021b8d9b87Sopenharmony_ci return KDF_ABILITY_SET[i].createSpiFunc; 1031b8d9b87Sopenharmony_ci } 1041b8d9b87Sopenharmony_ci } 1051b8d9b87Sopenharmony_ci LOGE("Algo not support! [Algo]: %d", params->algo); 1061b8d9b87Sopenharmony_ci return NULL; 1071b8d9b87Sopenharmony_ci} 1081b8d9b87Sopenharmony_ci 1091b8d9b87Sopenharmony_ci// export interfaces 1101b8d9b87Sopenharmony_cistatic const char *GetKdfGeneratorClass(void) 1111b8d9b87Sopenharmony_ci{ 1121b8d9b87Sopenharmony_ci return "HcfKdfGenerator"; 1131b8d9b87Sopenharmony_ci} 1141b8d9b87Sopenharmony_ci 1151b8d9b87Sopenharmony_cistatic const char *GetAlgoName(HcfKdf *self) 1161b8d9b87Sopenharmony_ci{ 1171b8d9b87Sopenharmony_ci if (self == NULL) { 1181b8d9b87Sopenharmony_ci LOGE("The input self ptr is NULL!"); 1191b8d9b87Sopenharmony_ci return NULL; 1201b8d9b87Sopenharmony_ci } 1211b8d9b87Sopenharmony_ci if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 1221b8d9b87Sopenharmony_ci return NULL; 1231b8d9b87Sopenharmony_ci } 1241b8d9b87Sopenharmony_ci return ((HcfKdfImpl *)self)->algoName; 1251b8d9b87Sopenharmony_ci} 1261b8d9b87Sopenharmony_ci 1271b8d9b87Sopenharmony_cistatic HcfResult GenerateSecret(HcfKdf *self, HcfKdfParamsSpec *paramsSpec) 1281b8d9b87Sopenharmony_ci{ 1291b8d9b87Sopenharmony_ci if (self == NULL || paramsSpec == NULL) { 1301b8d9b87Sopenharmony_ci LOGE("Invalid input parameter."); 1311b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 1321b8d9b87Sopenharmony_ci } 1331b8d9b87Sopenharmony_ci if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 1341b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 1351b8d9b87Sopenharmony_ci } 1361b8d9b87Sopenharmony_ci 1371b8d9b87Sopenharmony_ci HcfKdfImpl *tmp = (HcfKdfImpl *)self; 1381b8d9b87Sopenharmony_ci return tmp->spiObj->generateSecret(tmp->spiObj, paramsSpec); 1391b8d9b87Sopenharmony_ci} 1401b8d9b87Sopenharmony_ci 1411b8d9b87Sopenharmony_cistatic void DestroyKdf(HcfObjectBase *self) 1421b8d9b87Sopenharmony_ci{ 1431b8d9b87Sopenharmony_ci if (self == NULL) { 1441b8d9b87Sopenharmony_ci return; 1451b8d9b87Sopenharmony_ci } 1461b8d9b87Sopenharmony_ci if (!HcfIsClassMatch((HcfObjectBase *)self, GetKdfGeneratorClass())) { 1471b8d9b87Sopenharmony_ci return; 1481b8d9b87Sopenharmony_ci } 1491b8d9b87Sopenharmony_ci HcfKdfImpl *impl = (HcfKdfImpl *)self; 1501b8d9b87Sopenharmony_ci HcfObjDestroy(impl->spiObj); 1511b8d9b87Sopenharmony_ci impl->spiObj = NULL; 1521b8d9b87Sopenharmony_ci HcfFree(impl); 1531b8d9b87Sopenharmony_ci} 1541b8d9b87Sopenharmony_ci 1551b8d9b87Sopenharmony_ciHcfResult HcfKdfCreate(const char *transformation, HcfKdf **returnObj) 1561b8d9b87Sopenharmony_ci{ 1571b8d9b87Sopenharmony_ci if ((!HcfIsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { 1581b8d9b87Sopenharmony_ci LOGE("Invalid input params while creating kdf!"); 1591b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 1601b8d9b87Sopenharmony_ci } 1611b8d9b87Sopenharmony_ci 1621b8d9b87Sopenharmony_ci HcfKdfDeriveParams params = { 0 }; 1631b8d9b87Sopenharmony_ci if (ParseAndSetParameter(transformation, ¶ms, ParseKdfParams) != HCF_SUCCESS) { 1641b8d9b87Sopenharmony_ci LOGE("Failed to parse params!"); 1651b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 1661b8d9b87Sopenharmony_ci } 1671b8d9b87Sopenharmony_ci HcfKdfSpiCreateFunc createSpiFunc = FindAbility(¶ms); 1681b8d9b87Sopenharmony_ci if (createSpiFunc == NULL) { 1691b8d9b87Sopenharmony_ci LOGE("Not support this KDF func"); 1701b8d9b87Sopenharmony_ci return HCF_NOT_SUPPORT; 1711b8d9b87Sopenharmony_ci } 1721b8d9b87Sopenharmony_ci 1731b8d9b87Sopenharmony_ci HcfKdfImpl *returnGenerator = (HcfKdfImpl *)HcfMalloc(sizeof(HcfKdfImpl), 0); 1741b8d9b87Sopenharmony_ci if (returnGenerator == NULL) { 1751b8d9b87Sopenharmony_ci LOGE("Failed to allocate returnGenerator memory!"); 1761b8d9b87Sopenharmony_ci return HCF_ERR_MALLOC; 1771b8d9b87Sopenharmony_ci } 1781b8d9b87Sopenharmony_ci if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) { 1791b8d9b87Sopenharmony_ci LOGE("Failed to copy algoName!"); 1801b8d9b87Sopenharmony_ci HcfFree(returnGenerator); 1811b8d9b87Sopenharmony_ci return HCF_INVALID_PARAMS; 1821b8d9b87Sopenharmony_ci } 1831b8d9b87Sopenharmony_ci HcfKdfSpi *spiObj = NULL; 1841b8d9b87Sopenharmony_ci HcfResult res = createSpiFunc(¶ms, &spiObj); 1851b8d9b87Sopenharmony_ci if (res != HCF_SUCCESS) { 1861b8d9b87Sopenharmony_ci LOGE("Failed to create spi object!"); 1871b8d9b87Sopenharmony_ci HcfFree(returnGenerator); 1881b8d9b87Sopenharmony_ci return res; 1891b8d9b87Sopenharmony_ci } 1901b8d9b87Sopenharmony_ci returnGenerator->base.base.destroy = DestroyKdf; 1911b8d9b87Sopenharmony_ci returnGenerator->base.base.getClass = GetKdfGeneratorClass; 1921b8d9b87Sopenharmony_ci returnGenerator->base.generateSecret = GenerateSecret; 1931b8d9b87Sopenharmony_ci returnGenerator->base.getAlgorithm = GetAlgoName; 1941b8d9b87Sopenharmony_ci returnGenerator->spiObj = spiObj; 1951b8d9b87Sopenharmony_ci 1961b8d9b87Sopenharmony_ci *returnObj = (HcfKdf *)returnGenerator; 1971b8d9b87Sopenharmony_ci return HCF_SUCCESS; 1981b8d9b87Sopenharmony_ci} 199