• 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_MD)
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "securec.h"
22 #include "bsl_err_internal.h"
23 #include "bsl_sal.h"
24 #include "crypt_local_types.h"
25 #include "crypt_eal_md.h"
26 #include "crypt_algid.h"
27 #include "crypt_errno.h"
28 #include "eal_md_local.h"
29 #include "eal_common.h"
30 #include "crypt_ealinit.h"
31 #ifdef HITLS_CRYPTO_PROVIDER
32 #include "crypt_eal_implprovider.h"
33 #include "crypt_provider.h"
34 #endif
35 
MdAllocCtx(CRYPT_MD_AlgId id,const EAL_MdUnitaryMethod * method)36 static CRYPT_EAL_MdCTX *MdAllocCtx(CRYPT_MD_AlgId id, const EAL_MdUnitaryMethod *method)
37 {
38     CRYPT_EAL_MdCTX *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX));
39     if (ctx == NULL) {
40         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL);
41         return NULL;
42     }
43     void *data = NULL;
44     if (method->newCtx != NULL) {
45         data = method->newCtx();
46     } else {
47         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_NULL_INPUT);
48         BSL_SAL_FREE(ctx);
49         return NULL;
50     }
51     if (data == NULL) {
52         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_MEM_ALLOC_FAIL);
53         BSL_SAL_FREE(ctx);
54         return NULL;
55     }
56     ctx->data = data;
57     return ctx;
58 }
59 
EalMdCopyMethod(const EAL_MdMethod * method,EAL_MdUnitaryMethod * dest)60 static void EalMdCopyMethod(const EAL_MdMethod *method, EAL_MdUnitaryMethod *dest)
61 {
62     dest->blockSize = method->blockSize;
63     dest->mdSize = method->mdSize;
64     dest->newCtx = method->newCtx;
65     dest->init = method->init;
66     dest->update = method->update;
67     dest->final = method->final;
68     dest->deinit = method->deinit;
69     dest->dupCtx = method->dupCtx;
70     dest->freeCtx = method->freeCtx;
71     dest->ctrl = method->ctrl;
72     dest->squeeze = method->squeeze;
73 }
74 
MdNewDefaultCtx(CRYPT_MD_AlgId id)75 static CRYPT_EAL_MdCTX *MdNewDefaultCtx(CRYPT_MD_AlgId id)
76 {
77     const EAL_MdMethod *method = EAL_MdFindMethod(id);
78     if (method == NULL) {
79         BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_ALGID);
80         return NULL;
81     }
82 
83     EAL_MdUnitaryMethod *temp = BSL_SAL_Calloc(1, sizeof(EAL_MdUnitaryMethod));
84     if (temp == NULL) {
85         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
86         return NULL;
87     }
88     EalMdCopyMethod(method, temp);
89     CRYPT_EAL_MdCTX *ctx = MdAllocCtx(id, temp);
90     if (ctx == NULL) {
91         BSL_SAL_FREE(temp);
92         return NULL;
93     }
94 
95     ctx->id = id;
96     ctx->state = CRYPT_MD_STATE_NEW;
97     ctx->method = temp;
98     return ctx;
99 }
100 
101 #ifdef HITLS_CRYPTO_PROVIDER
CRYPT_EAL_SetMdMethod(CRYPT_EAL_MdCTX * ctx,const CRYPT_EAL_Func * funcs)102 static int32_t CRYPT_EAL_SetMdMethod(CRYPT_EAL_MdCTX *ctx, const CRYPT_EAL_Func *funcs)
103 {
104     int32_t index = 0;
105     EAL_MdUnitaryMethod *method = BSL_SAL_Calloc(1, sizeof(EAL_MdUnitaryMethod));
106     if (method == NULL) {
107         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
108         return BSL_MALLOC_FAIL;
109     }
110 
111     while (funcs[index].id != 0) {
112         switch (funcs[index].id) {
113             case CRYPT_EAL_IMPLMD_NEWCTX:
114                 method->provNewCtx = funcs[index].func;
115                 break;
116             case CRYPT_EAL_IMPLMD_INITCTX:
117                 method->init = funcs[index].func;
118                 break;
119             case CRYPT_EAL_IMPLMD_UPDATE:
120                 method->update = funcs[index].func;
121                 break;
122             case CRYPT_EAL_IMPLMD_FINAL:
123                 method->final = funcs[index].func;
124                 break;
125             case CRYPT_EAL_IMPLMD_DEINITCTX:
126                 method->deinit = funcs[index].func;
127                 break;
128             case CRYPT_EAL_IMPLMD_DUPCTX:
129                 method->dupCtx = funcs[index].func;
130                 break;
131             case CRYPT_EAL_IMPLMD_CTRL:
132                 method->ctrl = funcs[index].func;
133                 break;
134             case CRYPT_EAL_IMPLMD_FREECTX:
135                 method->freeCtx = funcs[index].func;
136                 break;
137             case CRYPT_EAL_IMPLMD_SQUEEZE:
138                 method->squeeze = funcs[index].func;
139                 break;
140             default:
141                 BSL_SAL_FREE(method);
142                 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL);
143                 return CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL;
144         }
145         index++;
146     }
147     ctx->method = method;
148     return CRYPT_SUCCESS;
149 }
150 
CRYPT_EAL_ProviderMdNewCtxInner(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)151 CRYPT_EAL_MdCTX *CRYPT_EAL_ProviderMdNewCtxInner(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
152 {
153     const CRYPT_EAL_Func *funcs = NULL;
154     void *provCtx = NULL;
155     int32_t ret = CRYPT_EAL_ProviderGetFuncs(libCtx, CRYPT_EAL_OPERAID_HASH, algId, attrName,
156         &funcs, &provCtx);
157     if (ret != CRYPT_SUCCESS) {
158         BSL_ERR_PUSH_ERROR(ret);
159         return NULL;
160     }
161     CRYPT_EAL_MdCTX *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX));
162     if (ctx == NULL) {
163         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, algId, CRYPT_MEM_ALLOC_FAIL);
164         return NULL;
165     }
166 
167     ret = CRYPT_EAL_SetMdMethod(ctx, funcs);
168     if (ret != BSL_SUCCESS) {
169         BSL_SAL_FREE(ctx);
170         return NULL;
171     }
172     if (ctx->method->provNewCtx == NULL) {
173         BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_IMPL_NULL);
174         BSL_SAL_FREE(ctx->method);
175         BSL_SAL_FREE(ctx);
176         return NULL;
177     }
178     ctx->data = ctx->method->provNewCtx(provCtx, algId);
179     if (ctx->data == NULL) {
180         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
181         BSL_SAL_FREE(ctx->method);
182         BSL_SAL_FREE(ctx);
183         return NULL;
184     }
185     ctx->id = algId;
186     ctx->state = CRYPT_MD_STATE_NEW;
187     ctx->isProvider = true;
188     return ctx;
189 }
190 #endif // HITLS_CRYPTO_PROVIDER
191 
CRYPT_EAL_ProviderMdNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)192 CRYPT_EAL_MdCTX *CRYPT_EAL_ProviderMdNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
193 {
194 #ifdef HITLS_CRYPTO_PROVIDER
195     return CRYPT_EAL_ProviderMdNewCtxInner(libCtx, algId, attrName);
196 #else
197     (void)libCtx;
198     (void)attrName;
199     return CRYPT_EAL_MdNewCtx(algId);
200 #endif
201 }
202 
CRYPT_EAL_MdNewCtx(CRYPT_MD_AlgId id)203 CRYPT_EAL_MdCTX *CRYPT_EAL_MdNewCtx(CRYPT_MD_AlgId id)
204 {
205 #ifdef HITLS_CRYPTO_ASM_CHECK
206     if (CRYPT_ASMCAP_Md(id) != CRYPT_SUCCESS) {
207         BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT);
208         return NULL;
209     }
210 #endif
211     return MdNewDefaultCtx(id);
212 }
213 
CRYPT_EAL_MdIsValidAlgId(CRYPT_MD_AlgId id)214 bool CRYPT_EAL_MdIsValidAlgId(CRYPT_MD_AlgId id)
215 {
216     return EAL_MdFindMethod(id) != NULL;
217 }
218 
CRYPT_EAL_MdGetId(CRYPT_EAL_MdCTX * ctx)219 int32_t CRYPT_EAL_MdGetId(CRYPT_EAL_MdCTX *ctx)
220 {
221     if (ctx == NULL) {
222         return CRYPT_MD_MAX;
223     }
224     return ctx->id;
225 }
226 
CRYPT_EAL_MdCopyCtx(CRYPT_EAL_MdCTX * to,const CRYPT_EAL_MdCTX * from)227 int32_t CRYPT_EAL_MdCopyCtx(CRYPT_EAL_MdCTX *to, const CRYPT_EAL_MdCTX *from)
228 {
229     if (to == NULL || to->method == NULL) {
230         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
231         return CRYPT_NULL_INPUT;
232     }
233     if (from == NULL || from->method == NULL || from->method->dupCtx == NULL) {
234         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
235         return CRYPT_NULL_INPUT;
236     }
237     if (to->isProvider != from->isProvider) {
238         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_INCONSISTENT_OPERATION);
239         return CRYPT_INCONSISTENT_OPERATION;
240     }
241 
242     if (to->data != NULL) {
243         if (to->method->freeCtx == NULL) {
244             EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_INVALID_ARG);
245             return CRYPT_INVALID_ARG;
246         }
247         to->method->freeCtx(to->data);
248         to->data = NULL;
249     }
250     void *data = from->method->dupCtx(from->data);
251     if (data == NULL) {
252         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, from->id, CRYPT_MEM_ALLOC_FAIL);
253         return CRYPT_MEM_ALLOC_FAIL;
254     }
255     *(EAL_MdUnitaryMethod *)to->method = *from->method;
256     to->data = data;
257     to->state = from->state;
258     to->id = from->id;
259     return CRYPT_SUCCESS;
260 }
261 
CRYPT_EAL_MdDupCtx(const CRYPT_EAL_MdCTX * ctx)262 CRYPT_EAL_MdCTX *CRYPT_EAL_MdDupCtx(const CRYPT_EAL_MdCTX *ctx)
263 {
264     if (ctx == NULL) {
265         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
266         return NULL;
267     }
268     if (ctx->method == NULL || ctx->method->dupCtx == NULL) {
269         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_NULL_INPUT);
270         return NULL;
271     }
272 
273     CRYPT_EAL_MdCTX *newCtx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_MdCTX));
274     if (newCtx == NULL) {
275         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
276         return NULL;
277     }
278     EAL_MdUnitaryMethod *method = BSL_SAL_Calloc(1u, sizeof(EAL_MdUnitaryMethod));
279     if (method == NULL) {
280         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
281         BSL_SAL_FREE(newCtx);
282         return NULL;
283     }
284     *method = *ctx->method;
285     newCtx->data = ctx->method->dupCtx(ctx->data);
286     if (newCtx->data == NULL) {
287         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
288         BSL_SAL_FREE(method);
289         BSL_SAL_FREE(newCtx);
290         return NULL;
291     }
292     newCtx->method = method;
293     newCtx->state = ctx->state;
294     newCtx->id = ctx->id;
295     return newCtx;
296 }
297 
CRYPT_EAL_MdFreeCtx(CRYPT_EAL_MdCTX * ctx)298 void CRYPT_EAL_MdFreeCtx(CRYPT_EAL_MdCTX *ctx)
299 {
300     if (ctx == NULL) {
301         return;
302     }
303     if (ctx->method == NULL || ctx->method->freeCtx == NULL) {
304         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
305         BSL_SAL_FREE(ctx->method);
306         BSL_SAL_FREE(ctx);
307         return;
308     }
309     EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_MD, ctx->id, CRYPT_SUCCESS);
310     ctx->method->freeCtx(ctx->data);
311     BSL_SAL_FREE(ctx->method);
312     BSL_SAL_FREE(ctx);
313     return;
314 }
315 
CRYPT_EAL_MdInit(CRYPT_EAL_MdCTX * ctx)316 int32_t CRYPT_EAL_MdInit(CRYPT_EAL_MdCTX *ctx)
317 {
318     if (ctx == NULL) {
319         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
320         return CRYPT_NULL_INPUT;
321     }
322     if (ctx->method == NULL || ctx->method->init == NULL) {
323         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
324         return CRYPT_EAL_ALG_NOT_SUPPORT;
325     }
326 
327     int32_t ret = ctx->method->init(ctx->data, NULL);
328     if (ret != CRYPT_SUCCESS) {
329         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret);
330         return ret;
331     }
332     ctx->state = CRYPT_MD_STATE_INIT;
333     return CRYPT_SUCCESS;
334 }
335 
CRYPT_EAL_MdUpdate(CRYPT_EAL_MdCTX * ctx,const uint8_t * data,uint32_t len)336 int32_t CRYPT_EAL_MdUpdate(CRYPT_EAL_MdCTX *ctx, const uint8_t *data, uint32_t len)
337 {
338     if (ctx == NULL) {
339         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
340         return CRYPT_NULL_INPUT;
341     }
342     if (ctx->method == NULL || ctx->method->update == NULL) {
343         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
344         return CRYPT_EAL_ALG_NOT_SUPPORT;
345     }
346 
347     if ((ctx->state == CRYPT_MD_STATE_FINAL) || (ctx->state == CRYPT_MD_STATE_NEW)
348         || (ctx->state == CRYPT_MD_STATE_SQUEEZE)) {
349         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ERR_STATE);
350         return CRYPT_EAL_ERR_STATE;
351     }
352 
353     int32_t ret = ctx->method->update(ctx->data, data, len);
354     if (ret != CRYPT_SUCCESS) {
355         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret);
356         return ret;
357     }
358     ctx->state = CRYPT_MD_STATE_UPDATE;
359     return CRYPT_SUCCESS;
360 }
361 
CRYPT_EAL_MdFinal(CRYPT_EAL_MdCTX * ctx,uint8_t * out,uint32_t * len)362 int32_t CRYPT_EAL_MdFinal(CRYPT_EAL_MdCTX *ctx, uint8_t *out, uint32_t *len)
363 {
364     if (ctx == NULL) {
365         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
366         return CRYPT_NULL_INPUT;
367     }
368     if (ctx->method == NULL || ctx->method->final == NULL) {
369         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
370         return CRYPT_EAL_ALG_NOT_SUPPORT;
371     }
372 
373     if ((ctx->state == CRYPT_MD_STATE_NEW) || (ctx->state == CRYPT_MD_STATE_FINAL) ||
374         (ctx->state == CRYPT_MD_STATE_SQUEEZE)) {
375         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ERR_STATE);
376         return CRYPT_EAL_ERR_STATE;
377     }
378 
379     // The validity of the buffer length that carries the output result (len > ctx->method->mdSize)
380     // is determined by the algorithm bottom layer and is not verified here.
381     int32_t ret = ctx->method->final(ctx->data, out, len);
382     if (ret != CRYPT_SUCCESS) {
383         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret);
384         return ret;
385     }
386     ctx->state = CRYPT_MD_STATE_FINAL;
387     EAL_EventReport(CRYPT_EVENT_MD, CRYPT_ALGO_MD, ctx->id, CRYPT_SUCCESS);
388     return CRYPT_SUCCESS;
389 }
390 
CRYPT_EAL_MdSqueeze(CRYPT_EAL_MdCTX * ctx,uint8_t * out,uint32_t len)391 int32_t CRYPT_EAL_MdSqueeze(CRYPT_EAL_MdCTX *ctx, uint8_t *out, uint32_t len)
392 {
393     if (ctx == NULL) {
394         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
395         return CRYPT_NULL_INPUT;
396     }
397     if (ctx->method == NULL || ctx->method->squeeze == NULL) {
398         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
399         return CRYPT_EAL_ALG_NOT_SUPPORT;
400     }
401     if ((ctx->state == CRYPT_MD_STATE_NEW) || (ctx->state == CRYPT_MD_STATE_FINAL)) {
402         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, CRYPT_EAL_ERR_STATE);
403         return CRYPT_EAL_ERR_STATE;
404     }
405 
406     int32_t ret = ctx->method->squeeze(ctx->data, out, len);
407     if (ret != CRYPT_SUCCESS) {
408         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, ctx->id, ret);
409         return ret;
410     }
411     ctx->state = CRYPT_MD_STATE_SQUEEZE;
412     EAL_EventReport(CRYPT_EVENT_MD, CRYPT_ALGO_MD, ctx->id, CRYPT_SUCCESS);
413     return CRYPT_SUCCESS;
414 }
415 
CRYPT_EAL_MdDeinit(CRYPT_EAL_MdCTX * ctx)416 int32_t CRYPT_EAL_MdDeinit(CRYPT_EAL_MdCTX *ctx)
417 {
418     if (ctx == NULL || ctx->method == NULL || ctx->method->deinit == NULL) {
419         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, CRYPT_MD_MAX, CRYPT_NULL_INPUT);
420         return CRYPT_NULL_INPUT;
421     }
422 
423     ctx->method->deinit(ctx->data);
424     ctx->state = CRYPT_MD_STATE_NEW;
425     return CRYPT_SUCCESS;
426 }
427 
CRYPT_EAL_MdGetDigestSize(CRYPT_MD_AlgId id)428 uint32_t CRYPT_EAL_MdGetDigestSize(CRYPT_MD_AlgId id)
429 {
430     const EAL_MdMethod *method = EAL_MdFindMethod(id);
431     if (method == NULL) {
432         EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_MD, id, CRYPT_EAL_ERR_ALGID);
433         return 0;
434     }
435 
436     return method->mdSize;
437 }
438 
CRYPT_EAL_Md(CRYPT_MD_AlgId id,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)439 int32_t CRYPT_EAL_Md(CRYPT_MD_AlgId id, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
440 {
441     return EAL_Md(id, in, inLen, out, outLen);
442 }
443 #endif
444