Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2024 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 : * SHA-256/384/512 digest Wrapper Implementation.
9 : **/
10 :
11 : #include "internal_crypt_lib.h"
12 : #include <mbedtls/sha256.h>
13 : #include <mbedtls/sha512.h>
14 :
15 : /**
16 : * Allocates and initializes one HASH_CTX context for subsequent SHA256 use.
17 : *
18 : * @return Pointer to the HASH_CTX context that has been initialized.
19 : * If the allocations fails, libspdm_sha256_new() returns NULL.
20 : *
21 : **/
22 848 : void *libspdm_sha256_new(void)
23 : {
24 : void *hmac_md_ctx;
25 :
26 848 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha256_context));
27 848 : if (hmac_md_ctx == NULL) {
28 0 : return NULL;
29 : }
30 :
31 848 : return hmac_md_ctx;
32 : }
33 :
34 : /**
35 : * Release the specified HASH_CTX context.
36 : *
37 : * @param[in] sha256_ctx Pointer to the HASH_CTX context to be released.
38 : *
39 : **/
40 804 : void libspdm_sha256_free(void *sha256_ctx)
41 : {
42 804 : mbedtls_sha256_free(sha256_ctx);
43 804 : free_pool (sha256_ctx);
44 804 : }
45 :
46 : /**
47 : * Initializes user-supplied memory pointed by sha256_context as SHA-256 hash context for
48 : * subsequent use.
49 : *
50 : * If sha256_context is NULL, then return false.
51 : *
52 : * @param[out] sha256_context Pointer to SHA-256 context being initialized.
53 : *
54 : * @retval true SHA-256 context initialization succeeded.
55 : * @retval false SHA-256 context initialization failed.
56 : *
57 : **/
58 455 : bool libspdm_sha256_init(void *sha256_context)
59 : {
60 : int ret;
61 :
62 455 : if (sha256_context == NULL) {
63 0 : return false;
64 : }
65 :
66 455 : mbedtls_sha256_init(sha256_context);
67 :
68 455 : ret = mbedtls_sha256_starts(sha256_context, false);
69 455 : if (ret != 0) {
70 0 : return false;
71 : }
72 455 : return true;
73 : }
74 :
75 : /**
76 : * Makes a copy of an existing SHA-256 context.
77 : *
78 : * If sha256_context is NULL, then return false.
79 : * If new_sha256_context is NULL, then return false.
80 : *
81 : * @param[in] sha256_context Pointer to SHA-256 context being copied.
82 : * @param[out] new_sha256_context Pointer to new SHA-256 context.
83 : *
84 : * @retval true SHA-256 context copy succeeded.
85 : * @retval false SHA-256 context copy failed.
86 : *
87 : **/
88 393 : bool libspdm_sha256_duplicate(const void *sha256_context,
89 : void *new_sha256_context)
90 : {
91 393 : if (sha256_context == NULL || new_sha256_context == NULL) {
92 0 : return false;
93 : }
94 :
95 393 : mbedtls_sha256_clone(new_sha256_context, sha256_context);
96 :
97 393 : return true;
98 : }
99 :
100 : /**
101 : * Digests the input data and updates SHA-256 context.
102 : *
103 : * This function performs SHA-256 digest on a data buffer of the specified size.
104 : * It can be called multiple times to compute the digest of long or discontinuous data streams.
105 : * SHA-256 context should be already correctly initialized by libspdm_sha256_init(), and should not be finalized
106 : * by libspdm_sha256_final(). Behavior with invalid context is undefined.
107 : *
108 : * If sha256_context is NULL, then return false.
109 : *
110 : * @param[in, out] sha256_context Pointer to the SHA-256 context.
111 : * @param[in] data Pointer to the buffer containing the data to be hashed.
112 : * @param[in] data_size size of data buffer in bytes.
113 : *
114 : * @retval true SHA-256 data digest succeeded.
115 : * @retval false SHA-256 data digest failed.
116 : *
117 : **/
118 10628 : bool libspdm_sha256_update(void *sha256_context, const void *data,
119 : size_t data_size)
120 : {
121 : int ret;
122 :
123 10628 : if (sha256_context == NULL) {
124 0 : return false;
125 : }
126 :
127 10628 : if (data == NULL && data_size != 0) {
128 0 : return false;
129 : }
130 10628 : if (data_size > INT_MAX) {
131 0 : return false;
132 : }
133 :
134 10628 : ret = mbedtls_sha256_update(sha256_context, data, data_size);
135 10628 : if (ret != 0) {
136 0 : return false;
137 : }
138 10628 : return true;
139 : }
140 :
141 : /**
142 : * Completes computation of the SHA-256 digest value.
143 : *
144 : * This function completes SHA-256 hash computation and retrieves the digest value into
145 : * the specified memory. After this function has been called, the SHA-256 context cannot
146 : * be used again.
147 : * SHA-256 context should be already correctly initialized by libspdm_sha256_init(), and should not be
148 : * finalized by libspdm_sha256_final(). Behavior with invalid SHA-256 context is undefined.
149 : *
150 : * If sha256_context is NULL, then return false.
151 : * If hash_value is NULL, then return false.
152 : *
153 : * @param[in, out] sha256_context Pointer to the SHA-256 context.
154 : * @param[out] hash_value Pointer to a buffer that receives the SHA-256 digest
155 : * value (32 bytes).
156 : *
157 : * @retval true SHA-256 digest computation succeeded.
158 : * @retval false SHA-256 digest computation failed.
159 : *
160 : **/
161 402 : bool libspdm_sha256_final(void *sha256_context, uint8_t *hash_value)
162 : {
163 : int ret;
164 :
165 402 : if (sha256_context == NULL || hash_value == NULL) {
166 0 : return false;
167 : }
168 :
169 402 : ret = mbedtls_sha256_finish(sha256_context, hash_value);
170 402 : mbedtls_sha256_free(sha256_context);
171 402 : if (ret != 0) {
172 0 : return false;
173 : }
174 402 : return true;
175 : }
176 :
177 : /**
178 : * Computes the SHA-256 message digest of a input data buffer.
179 : *
180 : * This function performs the SHA-256 message digest of a given data buffer, and places
181 : * the digest value into the specified memory.
182 : *
183 : * If this interface is not supported, then return false.
184 : *
185 : * @param[in] data Pointer to the buffer containing the data to be hashed.
186 : * @param[in] data_size size of data buffer in bytes.
187 : * @param[out] hash_value Pointer to a buffer that receives the SHA-256 digest
188 : * value (32 bytes).
189 : *
190 : * @retval true SHA-256 digest computation succeeded.
191 : * @retval false SHA-256 digest computation failed.
192 : * @retval false This interface is not supported.
193 : *
194 : **/
195 1809 : bool libspdm_sha256_hash_all(const void *data, size_t data_size,
196 : uint8_t *hash_value)
197 : {
198 : int ret;
199 :
200 1809 : if (hash_value == NULL) {
201 0 : return false;
202 : }
203 1809 : if (data == NULL && data_size != 0) {
204 0 : return false;
205 : }
206 1809 : if (data_size > INT_MAX) {
207 0 : return false;
208 : }
209 :
210 1809 : ret = mbedtls_sha256(data, data_size, hash_value, false);
211 1809 : if (ret != 0) {
212 0 : return false;
213 : }
214 1809 : return true;
215 : }
216 :
217 : /**
218 : * Allocates and initializes one HASH_CTX context for subsequent SHA384 use.
219 : *
220 : * @return Pointer to the HASH_CTX context that has been initialized.
221 : * If the allocations fails, libspdm_sha384_new() returns NULL.
222 : *
223 : **/
224 0 : void *libspdm_sha384_new(void)
225 : {
226 : void *hmac_md_ctx;
227 :
228 0 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha512_context));
229 0 : if (hmac_md_ctx == NULL) {
230 0 : return NULL;
231 : }
232 :
233 0 : return hmac_md_ctx;
234 : }
235 :
236 : /**
237 : * Release the specified HASH_CTX context.
238 : *
239 : * @param[in] sha384_ctx Pointer to the HASH_CTX context to be released.
240 : *
241 : **/
242 0 : void libspdm_sha384_free(void *sha384_ctx)
243 : {
244 0 : mbedtls_sha512_free(sha384_ctx);
245 0 : free_pool (sha384_ctx);
246 0 : }
247 :
248 : /**
249 : * Initializes user-supplied memory pointed by sha384_context as SHA-384 hash context for
250 : * subsequent use.
251 : *
252 : * If sha384_context is NULL, then return false.
253 : *
254 : * @param[out] sha384_context Pointer to SHA-384 context being initialized.
255 : *
256 : * @retval true SHA-384 context initialization succeeded.
257 : * @retval false SHA-384 context initialization failed.
258 : *
259 : **/
260 0 : bool libspdm_sha384_init(void *sha384_context)
261 : {
262 : int ret;
263 :
264 0 : if (sha384_context == NULL) {
265 0 : return false;
266 : }
267 :
268 0 : mbedtls_sha512_init(sha384_context);
269 :
270 0 : ret = mbedtls_sha512_starts(sha384_context, true);
271 0 : if (ret != 0) {
272 0 : return false;
273 : }
274 0 : return true;
275 : }
276 :
277 : /**
278 : * Makes a copy of an existing SHA-384 context.
279 : *
280 : * If sha384_context is NULL, then return false.
281 : * If new_sha384_context is NULL, then return false.
282 : * If this interface is not supported, then return false.
283 : *
284 : * @param[in] sha384_context Pointer to SHA-384 context being copied.
285 : * @param[out] new_sha384_context Pointer to new SHA-384 context.
286 : *
287 : * @retval true SHA-384 context copy succeeded.
288 : * @retval false SHA-384 context copy failed.
289 : * @retval false This interface is not supported.
290 : *
291 : **/
292 0 : bool libspdm_sha384_duplicate(const void *sha384_context,
293 : void *new_sha384_context)
294 : {
295 0 : if (sha384_context == NULL || new_sha384_context == NULL) {
296 0 : return false;
297 : }
298 :
299 0 : mbedtls_sha512_clone(new_sha384_context, sha384_context);
300 :
301 0 : return true;
302 : }
303 :
304 : /**
305 : * Digests the input data and updates SHA-384 context.
306 : *
307 : * This function performs SHA-384 digest on a data buffer of the specified size.
308 : * It can be called multiple times to compute the digest of long or discontinuous data streams.
309 : * SHA-384 context should be already correctly initialized by libspdm_sha384_init(), and should not be finalized
310 : * by libspdm_sha384_final(). Behavior with invalid context is undefined.
311 : *
312 : * If sha384_context is NULL, then return false.
313 : *
314 : * @param[in, out] sha384_context Pointer to the SHA-384 context.
315 : * @param[in] data Pointer to the buffer containing the data to be hashed.
316 : * @param[in] data_size size of data buffer in bytes.
317 : *
318 : * @retval true SHA-384 data digest succeeded.
319 : * @retval false SHA-384 data digest failed.
320 : *
321 : **/
322 0 : bool libspdm_sha384_update(void *sha384_context, const void *data,
323 : size_t data_size)
324 : {
325 : int ret;
326 :
327 0 : if (sha384_context == NULL) {
328 0 : return false;
329 : }
330 :
331 0 : if (data == NULL && data_size != 0) {
332 0 : return false;
333 : }
334 0 : if (data_size > INT_MAX) {
335 0 : return false;
336 : }
337 :
338 0 : ret = mbedtls_sha512_update(sha384_context, data, data_size);
339 0 : if (ret != 0) {
340 0 : return false;
341 : }
342 0 : return true;
343 : }
344 :
345 : /**
346 : * Completes computation of the SHA-384 digest value.
347 : *
348 : * This function completes SHA-384 hash computation and retrieves the digest value into
349 : * the specified memory. After this function has been called, the SHA-384 context cannot
350 : * be used again.
351 : * SHA-384 context should be already correctly initialized by libspdm_sha384_init(), and should not be
352 : * finalized by libspdm_sha384_final(). Behavior with invalid SHA-384 context is undefined.
353 : *
354 : * If sha384_context is NULL, then return false.
355 : * If hash_value is NULL, then return false.
356 : *
357 : * @param[in, out] sha384_context Pointer to the SHA-384 context.
358 : * @param[out] hash_value Pointer to a buffer that receives the SHA-384 digest
359 : * value (48 bytes).
360 : *
361 : * @retval true SHA-384 digest computation succeeded.
362 : * @retval false SHA-384 digest computation failed.
363 : *
364 : **/
365 0 : bool libspdm_sha384_final(void *sha384_context, uint8_t *hash_value)
366 : {
367 : int ret;
368 :
369 0 : if (sha384_context == NULL || hash_value == NULL) {
370 0 : return false;
371 : }
372 :
373 0 : ret = mbedtls_sha512_finish(sha384_context, hash_value);
374 :
375 0 : mbedtls_sha512_free(sha384_context);
376 0 : if (ret != 0) {
377 0 : return false;
378 : }
379 0 : return true;
380 : }
381 :
382 : /**
383 : * Computes the SHA-384 message digest of a input data buffer.
384 : *
385 : * This function performs the SHA-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 SHA-384 digest
393 : * value (48 bytes).
394 : *
395 : * @retval true SHA-384 digest computation succeeded.
396 : * @retval false SHA-384 digest computation failed.
397 : * @retval false This interface is not supported.
398 : *
399 : **/
400 214 : bool libspdm_sha384_hash_all(const void *data, size_t data_size,
401 : uint8_t *hash_value)
402 : {
403 : int ret;
404 :
405 214 : if (hash_value == NULL) {
406 0 : return false;
407 : }
408 214 : if (data == NULL && data_size != 0) {
409 0 : return false;
410 : }
411 214 : if (data_size > INT_MAX) {
412 0 : return false;
413 : }
414 :
415 214 : ret = mbedtls_sha512(data, data_size, hash_value, true);
416 214 : if (ret != 0) {
417 0 : return false;
418 : }
419 214 : return true;
420 : }
421 :
422 : /**
423 : * Allocates and initializes one HASH_CTX context for subsequent SHA512 use.
424 : *
425 : * @return Pointer to the HASH_CTX context that has been initialized.
426 : * If the allocations fails, libspdm_sha512_new() returns NULL.
427 : *
428 : **/
429 0 : void *libspdm_sha512_new(void)
430 : {
431 : void *hmac_md_ctx;
432 :
433 0 : hmac_md_ctx = allocate_zero_pool(sizeof(mbedtls_sha512_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] sha512_ctx Pointer to the HASH_CTX context to be released.
445 : *
446 : **/
447 0 : void libspdm_sha512_free(void *sha512_ctx)
448 : {
449 0 : mbedtls_sha512_free(sha512_ctx);
450 0 : free_pool (sha512_ctx);
451 0 : }
452 :
453 : /**
454 : * Initializes user-supplied memory pointed by sha512_context as SHA-512 hash context for
455 : * subsequent use.
456 : *
457 : * If sha512_context is NULL, then return false.
458 : *
459 : * @param[out] sha512_context Pointer to SHA-512 context being initialized.
460 : *
461 : * @retval true SHA-512 context initialization succeeded.
462 : * @retval false SHA-512 context initialization failed.
463 : *
464 : **/
465 0 : bool libspdm_sha512_init(void *sha512_context)
466 : {
467 : int ret;
468 :
469 0 : if (sha512_context == NULL) {
470 0 : return false;
471 : }
472 :
473 0 : mbedtls_sha512_init(sha512_context);
474 :
475 0 : ret = mbedtls_sha512_starts(sha512_context, false);
476 0 : if (ret != 0) {
477 0 : return false;
478 : }
479 0 : return true;
480 : }
481 :
482 : /**
483 : * Makes a copy of an existing SHA-512 context.
484 : *
485 : * If sha512_context is NULL, then return false.
486 : * If new_sha512_context is NULL, then return false.
487 : * If this interface is not supported, then return false.
488 : *
489 : * @param[in] sha512_context Pointer to SHA-512 context being copied.
490 : * @param[out] new_sha512_context Pointer to new SHA-512 context.
491 : *
492 : * @retval true SHA-512 context copy succeeded.
493 : * @retval false SHA-512 context copy failed.
494 : * @retval false This interface is not supported.
495 : *
496 : **/
497 0 : bool libspdm_sha512_duplicate(const void *sha512_context,
498 : void *new_sha512_context)
499 : {
500 0 : if (sha512_context == NULL || new_sha512_context == NULL) {
501 0 : return false;
502 : }
503 :
504 0 : mbedtls_sha512_clone(new_sha512_context, sha512_context);
505 :
506 0 : return true;
507 : }
508 :
509 : /**
510 : * Digests the input data and updates SHA-512 context.
511 : *
512 : * This function performs SHA-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 : * SHA-512 context should be already correctly initialized by libspdm_sha512_init(), and should not be finalized
515 : * by libspdm_sha512_final(). Behavior with invalid context is undefined.
516 : *
517 : * If sha512_context is NULL, then return false.
518 : *
519 : * @param[in, out] sha512_context Pointer to the SHA-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 SHA-512 data digest succeeded.
524 : * @retval false SHA-512 data digest failed.
525 : *
526 : **/
527 0 : bool libspdm_sha512_update(void *sha512_context, const void *data,
528 : size_t data_size)
529 : {
530 : int ret;
531 :
532 0 : if (sha512_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_sha512_update(sha512_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 SHA-512 digest value.
552 : *
553 : * This function completes SHA-512 hash computation and retrieves the digest value into
554 : * the specified memory. After this function has been called, the SHA-512 context cannot
555 : * be used again.
556 : * SHA-512 context should be already correctly initialized by libspdm_sha512_init(), and should not be
557 : * finalized by libspdm_sha512_final(). Behavior with invalid SHA-512 context is undefined.
558 : *
559 : * If sha512_context is NULL, then return false.
560 : * If hash_value is NULL, then return false.
561 : *
562 : * @param[in, out] sha512_context Pointer to the SHA-512 context.
563 : * @param[out] hash_value Pointer to a buffer that receives the SHA-512 digest
564 : * value (64 bytes).
565 : *
566 : * @retval true SHA-512 digest computation succeeded.
567 : * @retval false SHA-512 digest computation failed.
568 : *
569 : **/
570 0 : bool libspdm_sha512_final(void *sha512_context, uint8_t *hash_value)
571 : {
572 : int ret;
573 :
574 0 : if (sha512_context == NULL || hash_value == NULL) {
575 0 : return false;
576 : }
577 :
578 0 : ret = mbedtls_sha512_finish(sha512_context, hash_value);
579 0 : mbedtls_sha512_free(sha512_context);
580 0 : if (ret != 0) {
581 0 : return false;
582 : }
583 0 : return true;
584 : }
585 :
586 : /**
587 : * Computes the SHA-512 message digest of a input data buffer.
588 : *
589 : * This function performs the SHA-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 SHA-512 digest
597 : * value (64 bytes).
598 : *
599 : * @retval true SHA-512 digest computation succeeded.
600 : * @retval false SHA-512 digest computation failed.
601 : * @retval false This interface is not supported.
602 : *
603 : **/
604 0 : bool libspdm_sha512_hash_all(const void *data, size_t data_size,
605 : uint8_t *hash_value)
606 : {
607 : int ret;
608 :
609 0 : if (hash_value == NULL) {
610 0 : return false;
611 : }
612 0 : if (data == NULL && data_size != 0) {
613 0 : return false;
614 : }
615 0 : if (data_size > INT_MAX) {
616 0 : return false;
617 : }
618 :
619 0 : ret = mbedtls_sha512(data, data_size, hash_value, false);
620 0 : if (ret != 0) {
621 0 : return false;
622 : }
623 0 : return true;
624 : }
|