Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : /** @file
8 : * SHA3-256/384/512 and Shake-256 digest Wrapper Implementation
9 : **/
10 :
11 : #include "internal_crypt_lib.h"
12 : #include <mbedtls/sha3.h>
13 :
14 : /**
15 : * Allocates and initializes one HASH_CTX context for subsequent SHA3-256 use.
16 : *
17 : * @return Pointer to the HASH_CTX context that has been initialized.
18 : * If the allocations fails, libspdm_sha3_256_new() returns NULL.
19 : *
20 : **/
21 0 : void *libspdm_sha3_256_new(void)
22 : {
23 : void *hmac_md_ctx;
24 :
25 0 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha3_context));
26 0 : if (hmac_md_ctx == NULL) {
27 0 : return NULL;
28 : }
29 :
30 0 : return hmac_md_ctx;
31 : }
32 :
33 : /**
34 : * Release the specified HASH_CTX context.
35 : *
36 : * @param[in] sha3_256_ctx Pointer to the HASH_CTX context to be released.
37 : *
38 : **/
39 0 : void libspdm_sha3_256_free(void *sha3_256_ctx)
40 : {
41 0 : mbedtls_sha3_free(sha3_256_ctx);
42 0 : free_pool (sha3_256_ctx);
43 0 : }
44 :
45 : /**
46 : * Initializes user-supplied memory pointed by sha3_256_context as SHA3-256 hash context for
47 : * subsequent use.
48 : *
49 : * If sha3_256_context is NULL, then return false.
50 : *
51 : * @param[out] sha3_256_context Pointer to SHA3-256 context being initialized.
52 : *
53 : * @retval true SHA3-256 context initialization succeeded.
54 : * @retval false SHA3-256 context initialization failed.
55 : *
56 : **/
57 0 : bool libspdm_sha3_256_init(void *sha3_256_context)
58 : {
59 : int ret;
60 :
61 0 : if (sha3_256_context == NULL) {
62 0 : return false;
63 : }
64 :
65 0 : mbedtls_sha3_init(sha3_256_context);
66 :
67 0 : ret = mbedtls_sha3_starts(sha3_256_context, MBEDTLS_SHA3_256);
68 0 : if (ret != 0) {
69 0 : return false;
70 : }
71 0 : return true;
72 : }
73 :
74 : /**
75 : * Makes a copy of an existing SHA3-256 context.
76 : *
77 : * If sha3_256_context is NULL, then return false.
78 : * If new_sha3_256_context is NULL, then return false.
79 : * If this interface is not supported, then return false.
80 : *
81 : * @param[in] sha3_256_context Pointer to SHA3-256 context being copied.
82 : * @param[out] new_sha3_256_context Pointer to new SHA3-256 context.
83 : *
84 : * @retval true SHA3-256 context copy succeeded.
85 : * @retval false SHA3-256 context copy failed.
86 : * @retval false This interface is not supported.
87 : *
88 : **/
89 0 : bool libspdm_sha3_256_duplicate(const void *sha3_256_context,
90 : void *new_sha3_256_context)
91 : {
92 0 : if (sha3_256_context == NULL || new_sha3_256_context == NULL) {
93 0 : return false;
94 : }
95 :
96 0 : mbedtls_sha3_clone(new_sha3_256_context, sha3_256_context);
97 :
98 0 : return true;
99 : }
100 :
101 : /**
102 : * Digests the input data and updates SHA3-256 context.
103 : *
104 : * This function performs SHA3-256 digest on a data buffer of the specified size.
105 : * It can be called multiple times to compute the digest of long or discontinuous data streams.
106 : * SHA3-256 context should be already correctly initialized by libspdm_sha3_256_init(), and should not be finalized
107 : * by libspdm_sha3_256_final(). Behavior with invalid context is undefined.
108 : *
109 : * If sha3_256_context is NULL, then return false.
110 : *
111 : * @param[in, out] sha3_256_context Pointer to the SHA3-256 context.
112 : * @param[in] data Pointer to the buffer containing the data to be hashed.
113 : * @param[in] data_size size of data buffer in bytes.
114 : *
115 : * @retval true SHA3-256 data digest succeeded.
116 : * @retval false SHA3-256 data digest failed.
117 : *
118 : **/
119 0 : bool libspdm_sha3_256_update(void *sha3_256_context, const void *data,
120 : size_t data_size)
121 : {
122 : int ret;
123 :
124 0 : if (sha3_256_context == NULL) {
125 0 : return false;
126 : }
127 :
128 0 : if (data == NULL && data_size != 0) {
129 0 : return false;
130 : }
131 0 : if (data_size > INT_MAX) {
132 0 : return false;
133 : }
134 :
135 0 : ret = mbedtls_sha3_update(sha3_256_context, data, data_size);
136 0 : if (ret != 0) {
137 0 : return false;
138 : }
139 0 : return true;
140 : }
141 :
142 : /**
143 : * Completes computation of the SHA3-256 digest value.
144 : *
145 : * This function completes SHA3-256 hash computation and retrieves the digest value into
146 : * the specified memory. After this function has been called, the SHA3-256 context cannot
147 : * be used again.
148 : * SHA3-256 context should be already correctly initialized by libspdm_sha3_256_init(), and should not be
149 : * finalized by libspdm_sha3_256_final(). Behavior with invalid SHA3-256 context is undefined.
150 : *
151 : * If sha3_256_context is NULL, then return false.
152 : * If hash_value is NULL, then return false.
153 : *
154 : * @param[in, out] sha3_256_context Pointer to the SHA3-256 context.
155 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-256 digest
156 : * value (256 / 8 bytes).
157 : *
158 : * @retval true SHA3-256 digest computation succeeded.
159 : * @retval false SHA3-256 digest computation failed.
160 : *
161 : **/
162 0 : bool libspdm_sha3_256_final(void *sha3_256_context, uint8_t *hash_value)
163 : {
164 : int ret;
165 :
166 0 : if (sha3_256_context == NULL || hash_value == NULL) {
167 0 : return false;
168 : }
169 :
170 0 : ret = mbedtls_sha3_finish(sha3_256_context, hash_value, LIBSPDM_SHA3_256_DIGEST_SIZE);
171 0 : mbedtls_sha3_free(sha3_256_context);
172 0 : if (ret != 0) {
173 0 : return false;
174 : }
175 0 : return true;
176 : }
177 :
178 : /**
179 : * Computes the SHA3-256 message digest of a input data buffer.
180 : *
181 : * This function performs the SHA3-256 message digest of a given data buffer, and places
182 : * the digest value into the specified memory.
183 : *
184 : * If this interface is not supported, then return false.
185 : *
186 : * @param[in] data Pointer to the buffer containing the data to be hashed.
187 : * @param[in] data_size size of data buffer in bytes.
188 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-256 digest
189 : * value (256 / 8 bytes).
190 : *
191 : * @retval true SHA3-256 digest computation succeeded.
192 : * @retval false SHA3-256 digest computation failed.
193 : * @retval false This interface is not supported.
194 : *
195 : **/
196 1 : bool libspdm_sha3_256_hash_all(const void *data, size_t data_size,
197 : uint8_t *hash_value)
198 : {
199 : int ret;
200 :
201 1 : if (hash_value == NULL) {
202 0 : return false;
203 : }
204 1 : if (data == NULL && data_size != 0) {
205 0 : return false;
206 : }
207 1 : if (data_size > INT_MAX) {
208 0 : return false;
209 : }
210 :
211 1 : ret = mbedtls_sha3(MBEDTLS_SHA3_256, data, data_size, hash_value, LIBSPDM_SHA3_256_DIGEST_SIZE);
212 1 : if (ret != 0) {
213 0 : return false;
214 : }
215 1 : return true;
216 : }
217 :
218 : /**
219 : * Allocates and initializes one HASH_CTX context for subsequent SHA3-384 use.
220 : *
221 : * @return Pointer to the HASH_CTX context that has been initialized.
222 : * If the allocations fails, libspdm_sha3_384_new() returns NULL.
223 : *
224 : **/
225 0 : void *libspdm_sha3_384_new(void)
226 : {
227 : void *hmac_md_ctx;
228 :
229 0 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha3_context));
230 0 : if (hmac_md_ctx == NULL) {
231 0 : return NULL;
232 : }
233 :
234 0 : return hmac_md_ctx;
235 : }
236 :
237 : /**
238 : * Release the specified HASH_CTX context.
239 : *
240 : * @param[in] sha3_384_ctx Pointer to the HASH_CTX context to be released.
241 : *
242 : **/
243 0 : void libspdm_sha3_384_free(void *sha3_384_ctx)
244 : {
245 0 : mbedtls_sha3_free(sha3_384_ctx);
246 0 : free_pool (sha3_384_ctx);
247 0 : }
248 :
249 : /**
250 : * Initializes user-supplied memory pointed by sha3_384_context as SHA3-384 hash context for
251 : * subsequent use.
252 : *
253 : * If sha3_384_context is NULL, then return false.
254 : *
255 : * @param[out] sha3_384_context Pointer to SHA3-384 context being initialized.
256 : *
257 : * @retval true SHA3-384 context initialization succeeded.
258 : * @retval false SHA3-384 context initialization failed.
259 : *
260 : **/
261 0 : bool libspdm_sha3_384_init(void *sha3_384_context)
262 : {
263 : int ret;
264 :
265 0 : if (sha3_384_context == NULL) {
266 0 : return false;
267 : }
268 :
269 0 : mbedtls_sha3_init(sha3_384_context);
270 :
271 0 : ret = mbedtls_sha3_starts(sha3_384_context, MBEDTLS_SHA3_384);
272 0 : if (ret != 0) {
273 0 : return false;
274 : }
275 0 : return true;
276 : }
277 :
278 : /**
279 : * Makes a copy of an existing SHA3-384 context.
280 : *
281 : * If sha3_384_context is NULL, then return false.
282 : * If new_sha3_384_context is NULL, then return false.
283 : * If this interface is not supported, then return false.
284 : *
285 : * @param[in] sha3_384_context Pointer to SHA3-384 context being copied.
286 : * @param[out] new_sha3_384_context Pointer to new SHA3-384 context.
287 : *
288 : * @retval true SHA3-384 context copy succeeded.
289 : * @retval false SHA3-384 context copy failed.
290 : * @retval false This interface is not supported.
291 : *
292 : **/
293 0 : bool libspdm_sha3_384_duplicate(const void *sha3_384_context,
294 : void *new_sha3_384_context)
295 : {
296 0 : if (sha3_384_context == NULL || new_sha3_384_context == NULL) {
297 0 : return false;
298 : }
299 :
300 0 : mbedtls_sha3_clone(new_sha3_384_context, sha3_384_context);
301 :
302 0 : return true;
303 : }
304 :
305 : /**
306 : * Digests the input data and updates SHA3-384 context.
307 : *
308 : * This function performs SHA3-384 digest on a data buffer of the specified size.
309 : * It can be called multiple times to compute the digest of long or discontinuous data streams.
310 : * SHA3-384 context should be already correctly initialized by libspdm_sha3_384_init(), and should not be finalized
311 : * by libspdm_sha3_384_final(). Behavior with invalid context is undefined.
312 : *
313 : * If sha3_384_context is NULL, then return false.
314 : *
315 : * @param[in, out] sha3_384_context Pointer to the SHA3-384 context.
316 : * @param[in] data Pointer to the buffer containing the data to be hashed.
317 : * @param[in] data_size size of data buffer in bytes.
318 : *
319 : * @retval true SHA3-384 data digest succeeded.
320 : * @retval false SHA3-384 data digest failed.
321 : *
322 : **/
323 0 : bool libspdm_sha3_384_update(void *sha3_384_context, const void *data,
324 : size_t data_size)
325 : {
326 : int ret;
327 :
328 0 : if (sha3_384_context == NULL) {
329 0 : return false;
330 : }
331 :
332 0 : if (data == NULL && data_size != 0) {
333 0 : return false;
334 : }
335 0 : if (data_size > INT_MAX) {
336 0 : return false;
337 : }
338 :
339 0 : ret = mbedtls_sha3_update(sha3_384_context, data, data_size);
340 0 : if (ret != 0) {
341 0 : return false;
342 : }
343 0 : return true;
344 : }
345 :
346 : /**
347 : * Completes computation of the SHA3-384 digest value.
348 : *
349 : * This function completes SHA3-384 hash computation and retrieves the digest value into
350 : * the specified memory. After this function has been called, the SHA3-384 context cannot
351 : * be used again.
352 : * SHA3-384 context should be already correctly initialized by libspdm_sha3_384_init(), and should not be
353 : * finalized by libspdm_sha3_384_final(). Behavior with invalid SHA3-384 context is undefined.
354 : *
355 : * If sha3_384_context is NULL, then return false.
356 : * If hash_value is NULL, then return false.
357 : *
358 : * @param[in, out] sha3_384_context Pointer to the SHA3-384 context.
359 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-384 digest
360 : * value (384 / 8 bytes).
361 : *
362 : * @retval true SHA3-384 digest computation succeeded.
363 : * @retval false SHA3-384 digest computation failed.
364 : *
365 : **/
366 0 : bool libspdm_sha3_384_final(void *sha3_384_context, uint8_t *hash_value)
367 : {
368 : int ret;
369 :
370 0 : if (sha3_384_context == NULL || hash_value == NULL) {
371 0 : return false;
372 : }
373 :
374 0 : ret = mbedtls_sha3_finish(sha3_384_context, hash_value, LIBSPDM_SHA3_384_DIGEST_SIZE);
375 0 : mbedtls_sha3_free(sha3_384_context);
376 0 : if (ret != 0) {
377 0 : return false;
378 : }
379 0 : return true;
380 : }
381 :
382 : /**
383 : * Computes the SHA3-384 message digest of a input data buffer.
384 : *
385 : * This function performs the SHA3-384 message digest of a given data buffer, and places
386 : * the digest value into the specified memory.
387 : *
388 : * If this interface is not supported, then return false.
389 : *
390 : * @param[in] data Pointer to the buffer containing the data to be hashed.
391 : * @param[in] data_size size of data buffer in bytes.
392 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-384 digest
393 : * value (384 / 8 bytes).
394 : *
395 : * @retval true SHA3-384 digest computation succeeded.
396 : * @retval false SHA3-384 digest computation failed.
397 : * @retval false This interface is not supported.
398 : *
399 : **/
400 1 : bool libspdm_sha3_384_hash_all(const void *data, size_t data_size,
401 : uint8_t *hash_value)
402 : {
403 : int ret;
404 :
405 1 : if (hash_value == NULL) {
406 0 : return false;
407 : }
408 1 : if (data == NULL && data_size != 0) {
409 0 : return false;
410 : }
411 1 : if (data_size > INT_MAX) {
412 0 : return false;
413 : }
414 :
415 1 : ret = mbedtls_sha3(MBEDTLS_SHA3_384, data, data_size, hash_value, LIBSPDM_SHA3_384_DIGEST_SIZE);
416 1 : if (ret != 0) {
417 0 : return false;
418 : }
419 1 : return true;
420 : }
421 :
422 : /**
423 : * Allocates and initializes one HASH_CTX context for subsequent SHA3-512 use.
424 : *
425 : * @return Pointer to the HASH_CTX context that has been initialized.
426 : * If the allocations fails, libspdm_sha3_512_new() returns NULL.
427 : *
428 : **/
429 0 : void *libspdm_sha3_512_new(void)
430 : {
431 : void *hmac_md_ctx;
432 :
433 0 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha3_context));
434 0 : if (hmac_md_ctx == NULL) {
435 0 : return NULL;
436 : }
437 :
438 0 : return hmac_md_ctx;
439 : }
440 :
441 : /**
442 : * Release the specified HASH_CTX context.
443 : *
444 : * @param[in] sha3_512_ctx Pointer to the HASH_CTX context to be released.
445 : *
446 : **/
447 0 : void libspdm_sha3_512_free(void *sha3_512_ctx)
448 : {
449 0 : mbedtls_sha3_free(sha3_512_ctx);
450 0 : free_pool (sha3_512_ctx);
451 0 : }
452 :
453 : /**
454 : * Initializes user-supplied memory pointed by sha3_512_context as SHA3-512 hash context for
455 : * subsequent use.
456 : *
457 : * If sha3_512_context is NULL, then return false.
458 : *
459 : * @param[out] sha3_512_context Pointer to SHA3-512 context being initialized.
460 : *
461 : * @retval true SHA3-512 context initialization succeeded.
462 : * @retval false SHA3-512 context initialization failed.
463 : *
464 : **/
465 0 : bool libspdm_sha3_512_init(void *sha3_512_context)
466 : {
467 : int ret;
468 :
469 0 : if (sha3_512_context == NULL) {
470 0 : return false;
471 : }
472 :
473 0 : mbedtls_sha3_init(sha3_512_context);
474 :
475 0 : ret = mbedtls_sha3_starts(sha3_512_context, MBEDTLS_SHA3_512);
476 0 : if (ret != 0) {
477 0 : return false;
478 : }
479 0 : return true;
480 : }
481 :
482 : /**
483 : * Makes a copy of an existing SHA3-512 context.
484 : *
485 : * If sha3_512_context is NULL, then return false.
486 : * If new_sha3_512_context is NULL, then return false.
487 : * If this interface is not supported, then return false.
488 : *
489 : * @param[in] sha3_512_context Pointer to SHA3-512 context being copied.
490 : * @param[out] new_sha3_512_context Pointer to new SHA3-512 context.
491 : *
492 : * @retval true SHA3-512 context copy succeeded.
493 : * @retval false SHA3-512 context copy failed.
494 : * @retval false This interface is not supported.
495 : *
496 : **/
497 0 : bool libspdm_sha3_512_duplicate(const void *sha3_512_context,
498 : void *new_sha3_512_context)
499 : {
500 0 : if (sha3_512_context == NULL || new_sha3_512_context == NULL) {
501 0 : return false;
502 : }
503 :
504 0 : mbedtls_sha3_clone(new_sha3_512_context, sha3_512_context);
505 :
506 0 : return true;
507 : }
508 :
509 : /**
510 : * Digests the input data and updates SHA3-512 context.
511 : *
512 : * This function performs SHA3-512 digest on a data buffer of the specified size.
513 : * It can be called multiple times to compute the digest of long or discontinuous data streams.
514 : * SHA3-512 context should be already correctly initialized by libspdm_sha3_512_init(), and should not be finalized
515 : * by libspdm_sha3_512_final(). Behavior with invalid context is undefined.
516 : *
517 : * If sha3_512_context is NULL, then return false.
518 : *
519 : * @param[in, out] sha3_512_context Pointer to the SHA3-512 context.
520 : * @param[in] data Pointer to the buffer containing the data to be hashed.
521 : * @param[in] data_size size of data buffer in bytes.
522 : *
523 : * @retval true SHA3-512 data digest succeeded.
524 : * @retval false SHA3-512 data digest failed.
525 : *
526 : **/
527 0 : bool libspdm_sha3_512_update(void *sha3_512_context, const void *data,
528 : size_t data_size)
529 : {
530 : int ret;
531 :
532 0 : if (sha3_512_context == NULL) {
533 0 : return false;
534 : }
535 :
536 0 : if (data == NULL && data_size != 0) {
537 0 : return false;
538 : }
539 0 : if (data_size > INT_MAX) {
540 0 : return false;
541 : }
542 :
543 0 : ret = mbedtls_sha3_update(sha3_512_context, data, data_size);
544 0 : if (ret != 0) {
545 0 : return false;
546 : }
547 0 : return true;
548 : }
549 :
550 : /**
551 : * Completes computation of the SHA3-512 digest value.
552 : *
553 : * This function completes SHA3-512 hash computation and retrieves the digest value into
554 : * the specified memory. After this function has been called, the SHA3-512 context cannot
555 : * be used again.
556 : * SHA3-512 context should be already correctly initialized by libspdm_sha3_512_init(), and should not be
557 : * finalized by libspdm_sha3_512_final(). Behavior with invalid SHA3-512 context is undefined.
558 : *
559 : * If sha3_512_context is NULL, then return false.
560 : * If hash_value is NULL, then return false.
561 : *
562 : * @param[in, out] sha3_512_context Pointer to the SHA3-512 context.
563 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-512 digest
564 : * value (512 / 8 bytes).
565 : *
566 : * @retval true SHA3-512 digest computation succeeded.
567 : * @retval false SHA3-512 digest computation failed.
568 : *
569 : **/
570 0 : bool libspdm_sha3_512_final(void *sha3_512_context, uint8_t *hash_value)
571 : {
572 : int ret;
573 :
574 0 : if (sha3_512_context == NULL || hash_value == NULL) {
575 0 : return false;
576 : }
577 :
578 0 : ret = mbedtls_sha3_finish(sha3_512_context, hash_value, LIBSPDM_SHA3_512_DIGEST_SIZE);
579 0 : mbedtls_sha3_free(sha3_512_context);
580 0 : if (ret != 0) {
581 0 : return false;
582 : }
583 0 : return true;
584 : }
585 :
586 : /**
587 : * Computes the SHA3-512 message digest of a input data buffer.
588 : *
589 : * This function performs the SHA3-512 message digest of a given data buffer, and places
590 : * the digest value into the specified memory.
591 : *
592 : * If this interface is not supported, then return false.
593 : *
594 : * @param[in] data Pointer to the buffer containing the data to be hashed.
595 : * @param[in] data_size size of data buffer in bytes.
596 : * @param[out] hash_value Pointer to a buffer that receives the SHA3-512 digest
597 : * value (512 / 8 bytes).
598 : *
599 : * @retval true SHA3-512 digest computation succeeded.
600 : * @retval false SHA3-512 digest computation failed.
601 : * @retval false This interface is not supported.
602 : *
603 : **/
604 1 : bool libspdm_sha3_512_hash_all(const void *data, size_t data_size,
605 : uint8_t *hash_value)
606 : {
607 : int ret;
608 :
609 1 : if (hash_value == NULL) {
610 0 : return false;
611 : }
612 1 : if (data == NULL && data_size != 0) {
613 0 : return false;
614 : }
615 1 : if (data_size > INT_MAX) {
616 0 : return false;
617 : }
618 :
619 1 : ret = mbedtls_sha3(MBEDTLS_SHA3_512, data, data_size, hash_value, LIBSPDM_SHA3_512_DIGEST_SIZE);
620 1 : if (ret != 0) {
621 0 : return false;
622 : }
623 1 : return true;
624 : }
|