1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_MAC)
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "crypt_eal_mac.h"
22 #include "securec.h"
23 #include "bsl_err_internal.h"
24 #include "bsl_sal.h"
25 #include "crypt_local_types.h"
26 #include "crypt_eal_mac.h"
27 #include "crypt_algid.h"
28 #include "crypt_errno.h"
29 #include "crypt_ealinit.h"
30 #include "eal_mac_local.h"
31 #include "eal_common.h"
32 #ifdef HITLS_CRYPTO_PROVIDER
33 #include "crypt_eal_implprovider.h"
34 #include "crypt_provider.h"
35 #endif
36
37 #define MAC_TYPE_INVALID 0
38
EalMacCopyMethod(const EAL_MacMethod * src,EAL_MacUnitaryMethod * dst)39 static void EalMacCopyMethod(const EAL_MacMethod *src, EAL_MacUnitaryMethod *dst)
40 {
41 dst->init = src->init;
42 dst->update = src->update;
43 dst->final = src->final;
44 dst->deinit = src->deinit;
45 dst->reinit = src->reinit;
46 dst->newCtx = src->newCtx;
47 dst->ctrl = src->ctrl;
48 dst->freeCtx = src->freeCtx;
49 }
50
51 #ifdef HITLS_CRYPTO_PROVIDER
CRYPT_EAL_SetMacMethod(CRYPT_EAL_MacCtx * ctx,const CRYPT_EAL_Func * funcs)52 static int32_t CRYPT_EAL_SetMacMethod(CRYPT_EAL_MacCtx *ctx, const CRYPT_EAL_Func *funcs)
53 {
54 int32_t index = 0;
55 EAL_MacUnitaryMethod *method = BSL_SAL_Calloc(1, sizeof(EAL_MacUnitaryMethod));
56 if (method == NULL) {
57 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
58 return BSL_MALLOC_FAIL;
59 }
60 while (funcs[index].id != 0) {
61 switch (funcs[index].id) {
62 case CRYPT_EAL_IMPLMAC_NEWCTX:
63 method->provNewCtx = funcs[index].func;
64 break;
65 case CRYPT_EAL_IMPLMAC_INIT:
66 method->init = funcs[index].func;
67 break;
68 case CRYPT_EAL_IMPLMAC_UPDATE:
69 method->update = funcs[index].func;
70 break;
71 case CRYPT_EAL_IMPLMAC_FINAL:
72 method->final = funcs[index].func;
73 break;
74 case CRYPT_EAL_IMPLMAC_REINITCTX:
75 method->reinit = funcs[index].func;
76 break;
77 case CRYPT_EAL_IMPLMAC_DEINITCTX:
78 method->deinit = funcs[index].func;
79 break;
80 case CRYPT_EAL_IMPLMAC_CTRL:
81 method->ctrl = funcs[index].func;
82 break;
83 case CRYPT_EAL_IMPLMAC_FREECTX:
84 method->freeCtx = funcs[index].func;
85 break;
86 default:
87 BSL_SAL_Free(method);
88 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL);
89 return CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL;
90 }
91 index++;
92 }
93 ctx->macMeth = method;
94 return CRYPT_SUCCESS;
95 }
96
CRYPT_EAL_ProviderMacNewCtxInner(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)97 CRYPT_EAL_MacCtx *CRYPT_EAL_ProviderMacNewCtxInner(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
98 {
99 const CRYPT_EAL_Func *funcs = NULL;
100 void *provCtx = NULL;
101 int32_t ret = CRYPT_EAL_ProviderGetFuncs(libCtx, CRYPT_EAL_OPERAID_MAC, algId, attrName,
102 &funcs, &provCtx);
103 if (ret != CRYPT_SUCCESS) {
104 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, algId, ret);
105 return NULL;
106 }
107 CRYPT_EAL_MacCtx *macCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MacCtx));
108 if (macCtx == NULL) {
109 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, algId, CRYPT_MEM_ALLOC_FAIL);
110 return NULL;
111 }
112
113 ret = CRYPT_EAL_SetMacMethod(macCtx, funcs);
114 if (ret != BSL_SUCCESS) {
115 BSL_SAL_FREE(macCtx);
116 return NULL;
117 }
118 if (macCtx->macMeth->provNewCtx == NULL) {
119 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, algId, CRYPT_PROVIDER_ERR_IMPL_NULL);
120 BSL_SAL_FREE(macCtx->macMeth);
121 BSL_SAL_FREE(macCtx);
122 return NULL;
123 }
124 macCtx->ctx = macCtx->macMeth->provNewCtx(provCtx, algId);
125 if (macCtx->ctx == NULL) {
126 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, algId, CRYPT_MEM_ALLOC_FAIL);
127 BSL_SAL_FREE(macCtx->macMeth);
128 BSL_SAL_FREE(macCtx);
129 return NULL;
130 }
131
132 macCtx->id = algId;
133 macCtx->state = CRYPT_MAC_STATE_NEW;
134 macCtx->isProvider = true;
135
136 return macCtx;
137 }
138 #endif
139
CRYPT_EAL_ProviderMacNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)140 CRYPT_EAL_MacCtx *CRYPT_EAL_ProviderMacNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
141 {
142 #ifdef HITLS_CRYPTO_PROVIDER
143 return CRYPT_EAL_ProviderMacNewCtxInner(libCtx, algId, attrName);
144 #else
145 (void)libCtx;
146 (void)attrName;
147 return CRYPT_EAL_MacNewCtx(algId);
148 #endif
149 }
150
MacNewDefaultCtx(CRYPT_MAC_AlgId id)151 CRYPT_EAL_MacCtx *MacNewDefaultCtx(CRYPT_MAC_AlgId id)
152 {
153 EAL_MacMethLookup method;
154 int32_t ret = EAL_MacFindMethod(id, &method);
155 if (ret != CRYPT_SUCCESS) {
156 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, ret);
157 return NULL;
158 }
159
160 CRYPT_EAL_MacCtx *macCtx = NULL;
161
162 macCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MacCtx));
163 if (macCtx == NULL) {
164 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_MEM_ALLOC_FAIL);
165 return NULL;
166 }
167 macCtx->id = id;
168 macCtx->state = CRYPT_MAC_STATE_NEW;
169
170 EAL_MacUnitaryMethod *temp = BSL_SAL_Calloc(1, sizeof(EAL_MacUnitaryMethod));
171 if (temp == NULL) {
172 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_MEM_ALLOC_FAIL);
173 BSL_SAL_FREE(macCtx);
174 return NULL;
175 }
176 EalMacCopyMethod(method.macMethod, temp);
177 macCtx->macMeth = temp;
178
179 if (method.macMethod->newCtx == NULL) {
180 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_PROVIDER_ERR_IMPL_NULL);
181 BSL_SAL_FREE(macCtx->macMeth);
182 BSL_SAL_FREE(macCtx);
183 return NULL;
184 }
185 macCtx->ctx = method.macMethod->newCtx(id);
186 if (macCtx->ctx == NULL) {
187 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_MEM_ALLOC_FAIL);
188 BSL_SAL_FREE(macCtx->macMeth);
189 BSL_SAL_FREE(macCtx);
190 return NULL;
191 }
192
193 return macCtx;
194 }
195
CRYPT_EAL_MacNewCtx(CRYPT_MAC_AlgId id)196 CRYPT_EAL_MacCtx *CRYPT_EAL_MacNewCtx(CRYPT_MAC_AlgId id)
197 {
198 #if defined(HITLS_CRYPTO_ASM_CHECK)
199 if (CRYPT_ASMCAP_Mac(id) != CRYPT_SUCCESS) {
200 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, id, CRYPT_EAL_ALG_ASM_NOT_SUPPORT);
201 return NULL;
202 }
203 #endif
204 return MacNewDefaultCtx(id);
205 }
206
CRYPT_EAL_MacFreeCtx(CRYPT_EAL_MacCtx * ctx)207 void CRYPT_EAL_MacFreeCtx(CRYPT_EAL_MacCtx *ctx)
208 {
209 if (ctx == NULL) {
210 return;
211 }
212 if (ctx->macMeth == NULL || ctx->macMeth->freeCtx == NULL) {
213 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
214 BSL_SAL_FREE(ctx->macMeth);
215 BSL_SAL_FREE(ctx);
216 return;
217 }
218 EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_MAC, ctx->id, CRYPT_SUCCESS);
219 ctx->macMeth->freeCtx(ctx->ctx);
220 BSL_SAL_FREE(ctx->macMeth);
221 BSL_SAL_FREE(ctx);
222 return;
223 }
224
CRYPT_EAL_MacInit(CRYPT_EAL_MacCtx * ctx,const uint8_t * key,uint32_t len)225 int32_t CRYPT_EAL_MacInit(CRYPT_EAL_MacCtx *ctx, const uint8_t *key, uint32_t len)
226 {
227 if (ctx == NULL) {
228 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
229 return CRYPT_NULL_INPUT;
230 }
231 if (ctx->macMeth == NULL) {
232 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT);
233 return CRYPT_NULL_INPUT;
234 }
235
236 if (ctx->macMeth == NULL || ctx->macMeth->init == NULL) {
237 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
238 return CRYPT_EAL_ALG_NOT_SUPPORT;
239 }
240
241 int32_t ret = ctx->macMeth->init(ctx->ctx, key, len, NULL);
242 if (ret != CRYPT_SUCCESS) {
243 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret);
244 return ret;
245 }
246 EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_MAC, ctx->id, ret);
247 ctx->state = CRYPT_MAC_STATE_INIT;
248 return CRYPT_SUCCESS;
249 }
250
CRYPT_EAL_MacUpdate(CRYPT_EAL_MacCtx * ctx,const uint8_t * in,uint32_t len)251 int32_t CRYPT_EAL_MacUpdate(CRYPT_EAL_MacCtx *ctx, const uint8_t *in, uint32_t len)
252 {
253 if (ctx == NULL) {
254 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
255 return CRYPT_NULL_INPUT;
256 }
257 if (ctx->macMeth == NULL) {
258 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT);
259 return CRYPT_NULL_INPUT;
260 }
261
262 if ((ctx->state == CRYPT_MAC_STATE_FINAL) || (ctx->state == CRYPT_MAC_STATE_NEW)) {
263 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE);
264 return CRYPT_EAL_ERR_STATE;
265 }
266
267 if (ctx->macMeth == NULL || ctx->macMeth->update == NULL) {
268 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
269 return CRYPT_EAL_ALG_NOT_SUPPORT;
270 }
271
272 int32_t ret = ctx->macMeth->update(ctx->ctx, in, len);
273 if (ret != CRYPT_SUCCESS) {
274 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret);
275 return ret;
276 }
277 ctx->state = CRYPT_MAC_STATE_UPDATE;
278 return CRYPT_SUCCESS;
279 }
280
CRYPT_EAL_MacFinal(CRYPT_EAL_MacCtx * ctx,uint8_t * out,uint32_t * len)281 int32_t CRYPT_EAL_MacFinal(CRYPT_EAL_MacCtx *ctx, uint8_t *out, uint32_t *len)
282 {
283 if (ctx == NULL) {
284 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
285 return CRYPT_NULL_INPUT;
286 }
287 if (ctx->macMeth == NULL) {
288 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_NULL_INPUT);
289 return CRYPT_NULL_INPUT;
290 }
291
292 if ((ctx->state == CRYPT_MAC_STATE_NEW) || (ctx->state == CRYPT_MAC_STATE_FINAL)) {
293 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE);
294 return CRYPT_EAL_ERR_STATE;
295 }
296
297 if (ctx->macMeth == NULL || ctx->macMeth->final == NULL) {
298 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
299 return CRYPT_EAL_ALG_NOT_SUPPORT;
300 }
301
302 int32_t ret = ctx->macMeth->final(ctx->ctx, out, len);
303 if (ret != CRYPT_SUCCESS) {
304 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, ret);
305 return ret;
306 }
307 ctx->state = CRYPT_MAC_STATE_FINAL;
308 EAL_EventReport(CRYPT_EVENT_MAC, CRYPT_ALGO_MAC, ctx->id, CRYPT_SUCCESS);
309 return CRYPT_SUCCESS;
310 }
311
CRYPT_EAL_MacDeinit(CRYPT_EAL_MacCtx * ctx)312 void CRYPT_EAL_MacDeinit(CRYPT_EAL_MacCtx *ctx)
313 {
314 if (ctx == NULL) {
315 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
316 return;
317 }
318 if (ctx->macMeth == NULL || ctx->macMeth->deinit == NULL) {
319 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
320 return;
321 }
322 ctx->macMeth->deinit(ctx->ctx);
323
324 ctx->state = CRYPT_MAC_STATE_NEW;
325 return;
326 }
327
CRYPT_EAL_MacReinit(CRYPT_EAL_MacCtx * ctx)328 int32_t CRYPT_EAL_MacReinit(CRYPT_EAL_MacCtx *ctx)
329 {
330 if (ctx == NULL) {
331 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
332 return CRYPT_NULL_INPUT;
333 }
334
335 if (ctx->state == CRYPT_MAC_STATE_NEW) {
336 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE);
337 return CRYPT_EAL_ERR_STATE;
338 }
339
340 if (ctx->macMeth == NULL || ctx->macMeth->reinit == NULL) {
341 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
342 return CRYPT_EAL_ALG_NOT_SUPPORT;
343 }
344 ctx->macMeth->reinit(ctx->ctx);
345 ctx->state = CRYPT_MAC_STATE_INIT;
346 return CRYPT_SUCCESS;
347 }
348
CRYPT_EAL_MacCtrl(CRYPT_EAL_MacCtx * ctx,int32_t cmd,void * val,uint32_t valLen)349 int32_t CRYPT_EAL_MacCtrl(CRYPT_EAL_MacCtx *ctx, int32_t cmd, void *val, uint32_t valLen)
350 {
351 if (ctx == NULL || ctx->macMeth == NULL || ctx->macMeth->ctrl== NULL) {
352 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, CRYPT_MAC_MAX, CRYPT_NULL_INPUT);
353 return CRYPT_NULL_INPUT;
354 }
355
356 if (cmd == CRYPT_CTRL_GET_MACLEN) {
357 return ctx->macMeth->ctrl(ctx->ctx, cmd, val, valLen);
358 }
359
360 if (ctx->state != CRYPT_MAC_STATE_INIT) {
361 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MAC, ctx->id, CRYPT_EAL_ERR_STATE);
362 return CRYPT_EAL_ERR_STATE;
363 }
364
365 return ctx->macMeth->ctrl(ctx->ctx, cmd, val, valLen);
366 }
367
CRYPT_EAL_GetMacLen(const CRYPT_EAL_MacCtx * ctx)368 uint32_t CRYPT_EAL_GetMacLen(const CRYPT_EAL_MacCtx *ctx)
369 {
370 uint32_t result = 0;
371 int32_t ret = CRYPT_EAL_MacCtrl((CRYPT_EAL_MacCtx *)(uintptr_t)ctx,
372 CRYPT_CTRL_GET_MACLEN, &result, sizeof(uint32_t));
373 return (ret == CRYPT_SUCCESS) ? result : 0;
374 }
375
CRYPT_EAL_MacIsValidAlgId(CRYPT_MAC_AlgId id)376 bool CRYPT_EAL_MacIsValidAlgId(CRYPT_MAC_AlgId id)
377 {
378 EAL_MacMethLookup method;
379 return EAL_MacFindMethod(id, &method) == CRYPT_SUCCESS;
380 }
381
382 #endif
383