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]: %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 HcfFree(impl);
158 }
159
SetMacAlgoName(HcfMacImpl * macImpl,const char * algoName)160 static HcfResult SetMacAlgoName(HcfMacImpl *macImpl, const char *algoName)
161 {
162 if (strcpy_s(macImpl->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
163 LOGE("Failed to copy algoName!");
164 return HCF_INVALID_PARAMS;
165 }
166 return HCF_SUCCESS;
167 }
168
HandleCmacAlgo(HcfMacImpl * macImpl,const HcfMacParamsSpec * paramsSpec,HcfMacSpiCreateFunc * createSpiFunc)169 static HcfResult HandleCmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec,
170 HcfMacSpiCreateFunc *createSpiFunc)
171 {
172 const char *cipherName = ((HcfCmacParamsSpec *)paramsSpec)->cipherName;
173 if (cipherName == NULL) {
174 LOGE("Invalid cipher name: null pointer.");
175 return HCF_INVALID_PARAMS;
176 }
177
178 if ((strcmp(cipherName, "AES128") != 0) && (strcmp(cipherName, "AES256") != 0)) {
179 LOGE("Unsupported cipher name: %s, only support AES128 and AES256.", cipherName);
180 return HCF_INVALID_PARAMS;
181 }
182 *createSpiFunc = OpensslCmacSpiCreate;
183 return SetMacAlgoName(macImpl, cipherName);
184 }
185
HandleHmacAlgo(HcfMacImpl * macImpl,const HcfMacParamsSpec * paramsSpec,HcfMacSpiCreateFunc * createSpiFunc)186 static HcfResult HandleHmacAlgo(HcfMacImpl *macImpl, const HcfMacParamsSpec *paramsSpec,
187 HcfMacSpiCreateFunc *createSpiFunc)
188 {
189 const char *mdName = ((HcfHmacParamsSpec *)paramsSpec)->mdName;
190 *createSpiFunc = FindAbility(mdName);
191 if (*createSpiFunc == NULL) {
192 LOGE("Unsupported HMAC algorithm: %s", mdName);
193 return HCF_INVALID_PARAMS;
194 }
195 return SetMacAlgoName(macImpl, mdName);
196 }
197
HcfMacCreate(HcfMacParamsSpec * paramsSpec,HcfMac ** mac)198 HcfResult HcfMacCreate(HcfMacParamsSpec *paramsSpec, HcfMac **mac)
199 {
200 if (paramsSpec == NULL || !HcfIsStrValid(paramsSpec->algName, HCF_MAX_ALGO_NAME_LEN) || (mac == NULL)) {
201 LOGE("Invalid input params while creating mac!");
202 return HCF_INVALID_PARAMS;
203 }
204 HcfMacSpiCreateFunc createSpiFunc = NULL;
205 HcfMacImpl *returnMacApi = (HcfMacImpl *)HcfMalloc(sizeof(HcfMacImpl), 0);
206 if (returnMacApi == NULL) {
207 LOGE("Failed to allocate Mac Obj memory!");
208 return HCF_ERR_MALLOC;
209 }
210
211 HcfResult res = HCF_INVALID_PARAMS;
212 if (strcmp(paramsSpec->algName, "CMAC") == 0) {
213 res = HandleCmacAlgo(returnMacApi, paramsSpec, &createSpiFunc);
214 } else if (strcmp(paramsSpec->algName, "HMAC") == 0) {
215 res = HandleHmacAlgo(returnMacApi, paramsSpec, &createSpiFunc);
216 } else {
217 LOGE("Unsupported algorithm: %s", paramsSpec->algName);
218 HcfFree(returnMacApi);
219 return HCF_INVALID_PARAMS;
220 }
221
222 if (res != HCF_SUCCESS) {
223 HcfFree(returnMacApi);
224 return res;
225 }
226 if (createSpiFunc == NULL) {
227 LOGE("Algo name is error!");
228 return HCF_INVALID_PARAMS;
229 }
230 HcfMacSpi *spiObj = NULL;
231 res = createSpiFunc(paramsSpec, &spiObj);
232 if (res != HCF_SUCCESS) {
233 LOGE("Failed to create spi object!");
234 HcfFree(returnMacApi);
235 return res;
236 }
237 returnMacApi->base.base.getClass = GetMacClass;
238 returnMacApi->base.base.destroy = MacDestroy;
239 returnMacApi->base.init = Init;
240 returnMacApi->base.update = Update;
241 returnMacApi->base.doFinal = DoFinal;
242 returnMacApi->base.getMacLength = GetMacLength;
243 returnMacApi->base.getAlgoName = GetAlgoName;
244 returnMacApi->spiObj = spiObj;
245 *mac = (HcfMac *)returnMacApi;
246 return HCF_SUCCESS;
247 }