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