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 }