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, &params, ParseKdfParams) != HCF_SUCCESS) {
1641b8d9b87Sopenharmony_ci        LOGE("Failed to parse params!");
1651b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1661b8d9b87Sopenharmony_ci    }
1671b8d9b87Sopenharmony_ci    HcfKdfSpiCreateFunc createSpiFunc = FindAbility(&params);
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(&params, &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