• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mac.h"
17 
18 #include <securec.h>
19 
20 #include "mac_spi.h"
21 #include "mac_openssl.h"
22 #include "detailed_hmac_params.h"
23 #include "detailed_cmac_params.h"
24 
25 #include "log.h"
26 #include "config.h"
27 #include "memory.h"
28 #include "utils.h"
29 
30 typedef HcfResult (*HcfMacSpiCreateFunc)(HcfMacParamsSpec *, HcfMacSpi **);
31 
32 typedef struct {
33     HcfMac base;
34 
35     HcfMacSpi *spiObj;
36 
37     char algoName[HCF_MAX_ALGO_NAME_LEN];
38 } HcfMacImpl;
39 
40 typedef struct {
41     char *mdName;
42 
43     HcfMacSpiCreateFunc createSpiFunc;
44 } HcfHmacAbility;
45 
46 static const HcfHmacAbility HMAC_ABILITY_SET[] = {
47     { "SHA1", OpensslHmacSpiCreate },
48     { "SHA224", OpensslHmacSpiCreate },
49     { "SHA256", OpensslHmacSpiCreate },
50     { "SHA384", OpensslHmacSpiCreate },
51     { "SHA512", OpensslHmacSpiCreate },
52     { "SM3", OpensslHmacSpiCreate },
53     { "MD5", OpensslHmacSpiCreate },
54 };
55 
GetMacClass(void)56 static const char *GetMacClass(void)
57 {
58     return "HMAC";
59 }
60 
FindAbility(const char * mdName)61 static HcfMacSpiCreateFunc FindAbility(const char *mdName)
62 {
63     if (mdName == NULL) {
64         LOGE("Invalid mdName: null pointer.");
65         return NULL;
66     }
67     for (uint32_t i = 0; i < (sizeof(HMAC_ABILITY_SET) / sizeof(HMAC_ABILITY_SET[0])); i++) {
68         if (strcmp(HMAC_ABILITY_SET[i].mdName, mdName) == 0) {
69             return HMAC_ABILITY_SET[i].createSpiFunc;
70         }
71     }
72     LOGE("Algo not support! [Algo]: %{public}s", mdName);
73     return NULL;
74 }
75 
Init(HcfMac * self,const HcfSymKey * key)76 static HcfResult Init(HcfMac *self, const HcfSymKey *key)
77 {
78     if ((self == NULL) || (key == NULL)) {
79         LOGE("The input self ptr or key is NULL!");
80         return HCF_INVALID_PARAMS;
81     }
82     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
83         LOGE("Class is not match.");
84         return HCF_INVALID_PARAMS;
85     }
86     return ((HcfMacImpl *)self)->spiObj->engineInitMac(
87         ((HcfMacImpl *)self)->spiObj, key);
88 }
89 
Update(HcfMac * self,HcfBlob * input)90 static HcfResult Update(HcfMac *self, HcfBlob *input)
91 {
92     if ((self == NULL) || (!HcfIsBlobValid(input))) {
93         LOGE("The input self ptr or dataBlob is NULL!");
94         return HCF_INVALID_PARAMS;
95     }
96     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
97         LOGE("Class is not match.");
98         return HCF_INVALID_PARAMS;
99     }
100     return ((HcfMacImpl *)self)->spiObj->engineUpdateMac(
101         ((HcfMacImpl *)self)->spiObj, input);
102 }
103 
DoFinal(HcfMac * self,HcfBlob * output)104 static HcfResult DoFinal(HcfMac *self, HcfBlob *output)
105 {
106     if ((self == NULL) || (output == NULL)) {
107         LOGE("The input self ptr or dataBlob is NULL!");
108         return HCF_INVALID_PARAMS;
109     }
110     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
111         LOGE("Class is not match.");
112         return HCF_INVALID_PARAMS;
113     }
114     return ((HcfMacImpl *)self)->spiObj->engineDoFinalMac(
115         ((HcfMacImpl *)self)->spiObj, output);
116 }
117 
GetMacLength(HcfMac * self)118 static uint32_t GetMacLength(HcfMac *self)
119 {
120     if (self == NULL) {
121         LOGE("The input self ptr is NULL!");
122         return 0;
123     }
124     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
125         LOGE("Class is not match.");
126         return 0;
127     }
128     return ((HcfMacImpl *)self)->spiObj->engineGetMacLength(
129         ((HcfMacImpl *)self)->spiObj);
130 }
131 
GetAlgoName(HcfMac * self)132 static const char *GetAlgoName(HcfMac *self)
133 {
134     if (self == NULL) {
135         LOGE("The input self ptr is NULL!");
136         return NULL;
137     }
138     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
139         LOGE("Class is not match.");
140         return NULL;
141     }
142     return ((HcfMacImpl *)self)->algoName;
143 }
144 
MacDestroy(HcfObjectBase * self)145 static void MacDestroy(HcfObjectBase *self)
146 {
147     if (self == NULL) {
148         LOGE("The input self ptr is NULL!");
149         return;
150     }
151     if (!HcfIsClassMatch((HcfObjectBase *)self, GetMacClass())) {
152         LOGE("Class is not match.");
153         return;
154     }
155     HcfMacImpl *impl = (HcfMacImpl *)self;
156     HcfObjDestroy(impl->spiObj);
157     impl->spiObj = NULL;
158     HcfFree(impl);
159 }
160 
SetMacAlgoName(HcfMacImpl * macImpl,const char * algoName)161 static HcfResult SetMacAlgoName(HcfMacImpl *macImpl, const char *algoName)
162 {
163     if (strcpy_s(macImpl->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
164         LOGE("Failed to copy algoName!");
165         return HCF_INVALID_PARAMS;
166     }
167     return HCF_SUCCESS;
168 }
169 
HandleCmacAlgo(HcfMacImpl * macImpl,const HcfMacParamsSpec * paramsSpec,HcfMacSpiCreateFunc * createSpiFunc)170 static HcfResult HandleCmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec,
171     HcfMacSpiCreateFunc *createSpiFunc)
172 {
173     const char *cipherName = ((HcfCmacParamsSpec *)paramsSpec)->cipherName;
174     if (cipherName == NULL) {
175         LOGE("Invalid cipher name: null pointer.");
176         return HCF_INVALID_PARAMS;
177     }
178 
179     if ((strcmp(cipherName, "AES128") != 0) && (strcmp(cipherName, "AES256") != 0)) {
180         LOGE("Unsupported cipher name: %{public}s, only support AES128 and AES256.", cipherName);
181         return HCF_INVALID_PARAMS;
182     }
183     *createSpiFunc = OpensslCmacSpiCreate;
184     return SetMacAlgoName(macImpl, paramsSpec->algName);
185 }
186 
HandleHmacAlgo(HcfMacImpl * macImpl,const HcfMacParamsSpec * paramsSpec,HcfMacSpiCreateFunc * createSpiFunc)187 static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec,
188     HcfMacSpiCreateFunc *createSpiFunc)
189 {
190     const char *mdName = ((HcfHmacParamsSpec *)paramsSpec)->mdName;
191     *createSpiFunc = FindAbility(mdName);
192     if (*createSpiFunc == NULL) {
193         LOGE("Unsupported HMAC algorithm: %{public}s", mdName);
194         return HCF_INVALID_PARAMS;
195     }
196     return SetMacAlgoName(macImpl, paramsSpec->algName);
197 }
198 
HcfMacCreate(HcfMacParamsSpec * paramsSpec,HcfMac ** mac)199 HcfResult HcfMacCreate(HcfMacParamsSpec *paramsSpec, HcfMac **mac)
200 {
201     if (paramsSpec == NULL || !HcfIsStrValid(paramsSpec->algName, HCF_MAX_ALGO_NAME_LEN) || (mac == NULL)) {
202         LOGE("Invalid input params while creating mac!");
203         return HCF_INVALID_PARAMS;
204     }
205     HcfMacSpiCreateFunc createSpiFunc = NULL;
206     HcfMacImpl *returnMacApi = (HcfMacImpl *)HcfMalloc(sizeof(HcfMacImpl), 0);
207     if (returnMacApi == NULL) {
208         LOGE("Failed to allocate Mac Obj memory!");
209         return HCF_ERR_MALLOC;
210     }
211 
212     HcfResult res = HCF_INVALID_PARAMS;
213     if (strcmp(paramsSpec->algName, "CMAC") == 0) {
214         res = HandleCmacAlgo(returnMacApi, paramsSpec, &createSpiFunc);
215     } else if (strcmp(paramsSpec->algName, "HMAC") == 0) {
216         res = HandleHmacAlgo(returnMacApi, paramsSpec, &createSpiFunc);
217     } else {
218         LOGE("Unsupported algorithm: %{public}s", paramsSpec->algName);
219         HcfFree(returnMacApi);
220         returnMacApi = NULL;
221         return HCF_INVALID_PARAMS;
222     }
223 
224     if (res != HCF_SUCCESS) {
225         HcfFree(returnMacApi);
226         returnMacApi = NULL;
227         return res;
228     }
229     if (createSpiFunc == NULL) {
230         LOGE("Algo name is error!");
231         return HCF_INVALID_PARAMS;
232     }
233     HcfMacSpi *spiObj = NULL;
234     res = createSpiFunc(paramsSpec, &spiObj);
235     if (res != HCF_SUCCESS) {
236         LOGE("Failed to create spi object!");
237         HcfFree(returnMacApi);
238         returnMacApi = NULL;
239         return res;
240     }
241     returnMacApi->base.base.getClass = GetMacClass;
242     returnMacApi->base.base.destroy = MacDestroy;
243     returnMacApi->base.init = Init;
244     returnMacApi->base.update = Update;
245     returnMacApi->base.doFinal = DoFinal;
246     returnMacApi->base.getMacLength = GetMacLength;
247     returnMacApi->base.getAlgoName = GetAlgoName;
248     returnMacApi->spiObj = spiObj;
249     *mac = (HcfMac *)returnMacApi;
250     return HCF_SUCCESS;
251 }