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