11b8d9b87Sopenharmony_ci/*
21b8d9b87Sopenharmony_ci * Copyright (C) 2022-2023 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 "md.h"
171b8d9b87Sopenharmony_ci
181b8d9b87Sopenharmony_ci#include <securec.h>
191b8d9b87Sopenharmony_ci
201b8d9b87Sopenharmony_ci#include "sym_key.h"
211b8d9b87Sopenharmony_ci#include "md_spi.h"
221b8d9b87Sopenharmony_ci#ifdef CRYPTO_MBEDTLS
231b8d9b87Sopenharmony_ci#include "mbedtls_md.h"
241b8d9b87Sopenharmony_ci#else
251b8d9b87Sopenharmony_ci#include "md_openssl.h"
261b8d9b87Sopenharmony_ci#endif
271b8d9b87Sopenharmony_ci
281b8d9b87Sopenharmony_ci#include "log.h"
291b8d9b87Sopenharmony_ci#include "config.h"
301b8d9b87Sopenharmony_ci#include "memory.h"
311b8d9b87Sopenharmony_ci#include "utils.h"
321b8d9b87Sopenharmony_ci
331b8d9b87Sopenharmony_citypedef HcfResult (*HcfMdSpiCreateFunc)(const char *, HcfMdSpi **);
341b8d9b87Sopenharmony_ci
351b8d9b87Sopenharmony_citypedef struct {
361b8d9b87Sopenharmony_ci    HcfMd base;
371b8d9b87Sopenharmony_ci
381b8d9b87Sopenharmony_ci    HcfMdSpi *spiObj;
391b8d9b87Sopenharmony_ci
401b8d9b87Sopenharmony_ci    char algoName[HCF_MAX_ALGO_NAME_LEN];
411b8d9b87Sopenharmony_ci} HcfMdImpl;
421b8d9b87Sopenharmony_ci
431b8d9b87Sopenharmony_citypedef struct {
441b8d9b87Sopenharmony_ci    char *algoName;
451b8d9b87Sopenharmony_ci
461b8d9b87Sopenharmony_ci    HcfMdSpiCreateFunc createSpiFunc;
471b8d9b87Sopenharmony_ci} HcfMdAbility;
481b8d9b87Sopenharmony_ci
491b8d9b87Sopenharmony_cistatic const HcfMdAbility MD_ABILITY_SET[] = {
501b8d9b87Sopenharmony_ci#ifdef CRYPTO_MBEDTLS
511b8d9b87Sopenharmony_ci    { "SHA1", MbedtlsMdSpiCreate },
521b8d9b87Sopenharmony_ci    { "SHA256", MbedtlsMdSpiCreate },
531b8d9b87Sopenharmony_ci    { "SHA512", MbedtlsMdSpiCreate },
541b8d9b87Sopenharmony_ci    { "MD5", MbedtlsMdSpiCreate },
551b8d9b87Sopenharmony_ci#else
561b8d9b87Sopenharmony_ci    { "SHA1", OpensslMdSpiCreate },
571b8d9b87Sopenharmony_ci    { "SHA224", OpensslMdSpiCreate },
581b8d9b87Sopenharmony_ci    { "SHA256", OpensslMdSpiCreate },
591b8d9b87Sopenharmony_ci    { "SHA384", OpensslMdSpiCreate },
601b8d9b87Sopenharmony_ci    { "SHA512", OpensslMdSpiCreate },
611b8d9b87Sopenharmony_ci    { "MD5", OpensslMdSpiCreate },
621b8d9b87Sopenharmony_ci    { "SM3", OpensslMdSpiCreate },
631b8d9b87Sopenharmony_ci#endif
641b8d9b87Sopenharmony_ci};
651b8d9b87Sopenharmony_ci
661b8d9b87Sopenharmony_cistatic const char *GetMdClass(void)
671b8d9b87Sopenharmony_ci{
681b8d9b87Sopenharmony_ci    return "Md";
691b8d9b87Sopenharmony_ci}
701b8d9b87Sopenharmony_ci
711b8d9b87Sopenharmony_cistatic HcfMdSpiCreateFunc FindAbility(const char *algoName)
721b8d9b87Sopenharmony_ci{
731b8d9b87Sopenharmony_ci    for (uint32_t i = 0; i < (sizeof(MD_ABILITY_SET) / sizeof(MD_ABILITY_SET[0])); i++) {
741b8d9b87Sopenharmony_ci        if (strcmp(MD_ABILITY_SET[i].algoName, algoName) == 0) {
751b8d9b87Sopenharmony_ci            return MD_ABILITY_SET[i].createSpiFunc;
761b8d9b87Sopenharmony_ci        }
771b8d9b87Sopenharmony_ci    }
781b8d9b87Sopenharmony_ci    LOGE("Algo not support! [Algo]: %s", algoName);
791b8d9b87Sopenharmony_ci    return NULL;
801b8d9b87Sopenharmony_ci}
811b8d9b87Sopenharmony_ci
821b8d9b87Sopenharmony_cistatic HcfResult Update(HcfMd *self, HcfBlob *input)
831b8d9b87Sopenharmony_ci{
841b8d9b87Sopenharmony_ci    if ((self == NULL) || (!HcfIsBlobValid(input))) {
851b8d9b87Sopenharmony_ci        LOGE("The input self ptr or dataBlob is NULL!");
861b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
871b8d9b87Sopenharmony_ci    }
881b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetMdClass())) {
891b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
901b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
911b8d9b87Sopenharmony_ci    }
921b8d9b87Sopenharmony_ci    return ((HcfMdImpl *)self)->spiObj->engineUpdateMd(
931b8d9b87Sopenharmony_ci        ((HcfMdImpl *)self)->spiObj, input);
941b8d9b87Sopenharmony_ci}
951b8d9b87Sopenharmony_ci
961b8d9b87Sopenharmony_cistatic HcfResult DoFinal(HcfMd *self, HcfBlob *output)
971b8d9b87Sopenharmony_ci{
981b8d9b87Sopenharmony_ci    if ((self == NULL) || (output == NULL)) {
991b8d9b87Sopenharmony_ci        LOGE("The input self ptr or dataBlob is NULL!");
1001b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1011b8d9b87Sopenharmony_ci    }
1021b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetMdClass())) {
1031b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
1041b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1051b8d9b87Sopenharmony_ci    }
1061b8d9b87Sopenharmony_ci    return ((HcfMdImpl *)self)->spiObj->engineDoFinalMd(
1071b8d9b87Sopenharmony_ci        ((HcfMdImpl *)self)->spiObj, output);
1081b8d9b87Sopenharmony_ci}
1091b8d9b87Sopenharmony_ci
1101b8d9b87Sopenharmony_cistatic uint32_t GetMdLength(HcfMd *self)
1111b8d9b87Sopenharmony_ci{
1121b8d9b87Sopenharmony_ci    if (self == NULL) {
1131b8d9b87Sopenharmony_ci        LOGE("The input self ptr is NULL!");
1141b8d9b87Sopenharmony_ci        return 0;
1151b8d9b87Sopenharmony_ci    }
1161b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetMdClass())) {
1171b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
1181b8d9b87Sopenharmony_ci        return 0;
1191b8d9b87Sopenharmony_ci    }
1201b8d9b87Sopenharmony_ci    return ((HcfMdImpl *)self)->spiObj->engineGetMdLength(
1211b8d9b87Sopenharmony_ci        ((HcfMdImpl *)self)->spiObj);
1221b8d9b87Sopenharmony_ci}
1231b8d9b87Sopenharmony_ci
1241b8d9b87Sopenharmony_cistatic const char *GetAlgoName(HcfMd *self)
1251b8d9b87Sopenharmony_ci{
1261b8d9b87Sopenharmony_ci    if (self == NULL) {
1271b8d9b87Sopenharmony_ci        LOGE("The input self ptr is NULL!");
1281b8d9b87Sopenharmony_ci        return NULL;
1291b8d9b87Sopenharmony_ci    }
1301b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetMdClass())) {
1311b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
1321b8d9b87Sopenharmony_ci        return NULL;
1331b8d9b87Sopenharmony_ci    }
1341b8d9b87Sopenharmony_ci    return ((HcfMdImpl *)self)->algoName;
1351b8d9b87Sopenharmony_ci}
1361b8d9b87Sopenharmony_ci
1371b8d9b87Sopenharmony_cistatic void MdDestroy(HcfObjectBase *self)
1381b8d9b87Sopenharmony_ci{
1391b8d9b87Sopenharmony_ci    if (self == NULL) {
1401b8d9b87Sopenharmony_ci        LOGE("The input self ptr is NULL!");
1411b8d9b87Sopenharmony_ci        return;
1421b8d9b87Sopenharmony_ci    }
1431b8d9b87Sopenharmony_ci    if (!HcfIsClassMatch((HcfObjectBase *)self, GetMdClass())) {
1441b8d9b87Sopenharmony_ci        LOGE("Class is not match.");
1451b8d9b87Sopenharmony_ci        return;
1461b8d9b87Sopenharmony_ci    }
1471b8d9b87Sopenharmony_ci    HcfMdImpl *impl = (HcfMdImpl *)self;
1481b8d9b87Sopenharmony_ci    HcfObjDestroy(impl->spiObj);
1491b8d9b87Sopenharmony_ci    HcfFree(impl);
1501b8d9b87Sopenharmony_ci}
1511b8d9b87Sopenharmony_ci
1521b8d9b87Sopenharmony_ciHcfResult HcfMdCreate(const char *algoName, HcfMd **md)
1531b8d9b87Sopenharmony_ci{
1541b8d9b87Sopenharmony_ci    if (!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN) || (md == NULL)) {
1551b8d9b87Sopenharmony_ci        LOGE("Invalid input params while creating md!");
1561b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1571b8d9b87Sopenharmony_ci    }
1581b8d9b87Sopenharmony_ci    HcfMdSpiCreateFunc createSpiFunc = FindAbility(algoName);
1591b8d9b87Sopenharmony_ci    if (createSpiFunc == NULL) {
1601b8d9b87Sopenharmony_ci        LOGE("Algo name is error!");
1611b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1621b8d9b87Sopenharmony_ci    }
1631b8d9b87Sopenharmony_ci    HcfMdImpl *returnMdApi = (HcfMdImpl *)HcfMalloc(sizeof(HcfMdImpl), 0);
1641b8d9b87Sopenharmony_ci    if (returnMdApi == NULL) {
1651b8d9b87Sopenharmony_ci        LOGE("Failed to allocate Md Obj memory!");
1661b8d9b87Sopenharmony_ci        return HCF_ERR_MALLOC;
1671b8d9b87Sopenharmony_ci    }
1681b8d9b87Sopenharmony_ci    if (strcpy_s(returnMdApi->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
1691b8d9b87Sopenharmony_ci        LOGE("Failed to copy algoName!");
1701b8d9b87Sopenharmony_ci        HcfFree(returnMdApi);
1711b8d9b87Sopenharmony_ci        return HCF_INVALID_PARAMS;
1721b8d9b87Sopenharmony_ci    }
1731b8d9b87Sopenharmony_ci    HcfMdSpi *spiObj = NULL;
1741b8d9b87Sopenharmony_ci    HcfResult res = createSpiFunc(algoName, &spiObj);
1751b8d9b87Sopenharmony_ci    if (res != HCF_SUCCESS) {
1761b8d9b87Sopenharmony_ci        LOGE("Failed to create spi object!");
1771b8d9b87Sopenharmony_ci        HcfFree(returnMdApi);
1781b8d9b87Sopenharmony_ci        return res;
1791b8d9b87Sopenharmony_ci    }
1801b8d9b87Sopenharmony_ci    returnMdApi->base.base.getClass = GetMdClass;
1811b8d9b87Sopenharmony_ci    returnMdApi->base.base.destroy = MdDestroy;
1821b8d9b87Sopenharmony_ci    returnMdApi->base.update = Update;
1831b8d9b87Sopenharmony_ci    returnMdApi->base.doFinal = DoFinal;
1841b8d9b87Sopenharmony_ci    returnMdApi->base.getMdLength = GetMdLength;
1851b8d9b87Sopenharmony_ci    returnMdApi->base.getAlgoName = GetAlgoName;
1861b8d9b87Sopenharmony_ci    returnMdApi->spiObj = spiObj;
1871b8d9b87Sopenharmony_ci    *md = (HcfMd *)returnMdApi;
1881b8d9b87Sopenharmony_ci    return HCF_SUCCESS;
1891b8d9b87Sopenharmony_ci}