• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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