]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Hmac/CryptHmac.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Hmac / CryptHmac.c
1 /** @file
2 HMAC-SHA256/SHA384 Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "InternalCryptLib.h"
10 #include <openssl/hmac.h>
11
12 /**
13 Allocates and initializes one HMAC_CTX context for subsequent HMAC-MD use.
14
15 @return Pointer to the HMAC_CTX context that has been initialized.
16 If the allocations fails, HmacMdNew() returns NULL.
17
18 **/
19 STATIC
20 VOID *
21 HmacMdNew (
22 VOID
23 )
24 {
25 //
26 // Allocates & Initializes HMAC_CTX Context by OpenSSL HMAC_CTX_new()
27 //
28 return (VOID *)HMAC_CTX_new ();
29 }
30
31 /**
32 Release the specified HMAC_CTX context.
33
34 @param[in] HmacMdCtx Pointer to the HMAC_CTX context to be released.
35
36 **/
37 STATIC
38 VOID
39 HmacMdFree (
40 IN VOID *HmacMdCtx
41 )
42 {
43 //
44 // Free OpenSSL HMAC_CTX Context
45 //
46 HMAC_CTX_free ((HMAC_CTX *)HmacMdCtx);
47 }
48
49 /**
50 Set user-supplied key for subsequent use. It must be done before any
51 calling to HmacMdUpdate().
52
53 If HmacMdContext is NULL, then return FALSE.
54
55 @param[in] Md Message Digest.
56 @param[out] HmacMdContext Pointer to HMAC-MD context.
57 @param[in] Key Pointer to the user-supplied key.
58 @param[in] KeySize Key size in bytes.
59
60 @retval TRUE The Key is set successfully.
61 @retval FALSE The Key is set unsuccessfully.
62
63 **/
64 STATIC
65 BOOLEAN
66 HmacMdSetKey (
67 IN CONST EVP_MD *Md,
68 OUT VOID *HmacMdContext,
69 IN CONST UINT8 *Key,
70 IN UINTN KeySize
71 )
72 {
73 //
74 // Check input parameters.
75 //
76 if ((HmacMdContext == NULL) || (KeySize > INT_MAX)) {
77 return FALSE;
78 }
79
80 if (HMAC_Init_ex ((HMAC_CTX *)HmacMdContext, Key, (UINT32)KeySize, Md, NULL) != 1) {
81 return FALSE;
82 }
83
84 return TRUE;
85 }
86
87 /**
88 Makes a copy of an existing HMAC-MD context.
89
90 If HmacMdContext is NULL, then return FALSE.
91 If NewHmacMdContext is NULL, then return FALSE.
92
93 @param[in] HmacMdContext Pointer to HMAC-MD context being copied.
94 @param[out] NewHmacMdContext Pointer to new HMAC-MD context.
95
96 @retval TRUE HMAC-MD context copy succeeded.
97 @retval FALSE HMAC-MD context copy failed.
98
99 **/
100 STATIC
101 BOOLEAN
102 HmacMdDuplicate (
103 IN CONST VOID *HmacMdContext,
104 OUT VOID *NewHmacMdContext
105 )
106 {
107 //
108 // Check input parameters.
109 //
110 if ((HmacMdContext == NULL) || (NewHmacMdContext == NULL)) {
111 return FALSE;
112 }
113
114 if (HMAC_CTX_copy ((HMAC_CTX *)NewHmacMdContext, (HMAC_CTX *)HmacMdContext) != 1) {
115 return FALSE;
116 }
117
118 return TRUE;
119 }
120
121 /**
122 Digests the input data and updates HMAC-MD context.
123
124 This function performs HMAC-MD digest on a data buffer of the specified size.
125 It can be called multiple times to compute the digest of long or discontinuous data streams.
126 HMAC-MD context should be initialized by HmacMdNew(), and should not be finalized
127 by HmacMdFinal(). Behavior with invalid context is undefined.
128
129 If HmacMdContext is NULL, then return FALSE.
130
131 @param[in, out] HmacMdContext Pointer to the HMAC-MD context.
132 @param[in] Data Pointer to the buffer containing the data to be digested.
133 @param[in] DataSize Size of Data buffer in bytes.
134
135 @retval TRUE HMAC-MD data digest succeeded.
136 @retval FALSE HMAC-MD data digest failed.
137
138 **/
139 STATIC
140 BOOLEAN
141 HmacMdUpdate (
142 IN OUT VOID *HmacMdContext,
143 IN CONST VOID *Data,
144 IN UINTN DataSize
145 )
146 {
147 //
148 // Check input parameters.
149 //
150 if (HmacMdContext == NULL) {
151 return FALSE;
152 }
153
154 //
155 // Check invalid parameters, in case that only DataLength was checked in OpenSSL
156 //
157 if ((Data == NULL) && (DataSize != 0)) {
158 return FALSE;
159 }
160
161 //
162 // OpenSSL HMAC-MD digest update
163 //
164 if (HMAC_Update ((HMAC_CTX *)HmacMdContext, Data, DataSize) != 1) {
165 return FALSE;
166 }
167
168 return TRUE;
169 }
170
171 /**
172 Completes computation of the HMAC-MD digest value.
173
174 This function completes HMAC-MD hash computation and retrieves the digest value into
175 the specified memory. After this function has been called, the HMAC-MD context cannot
176 be used again.
177 HMAC-MD context should be initialized by HmacMdNew(), and should not be finalized
178 by HmacMdFinal(). Behavior with invalid HMAC-MD context is undefined.
179
180 If HmacMdContext is NULL, then return FALSE.
181 If HmacValue is NULL, then return FALSE.
182
183 @param[in, out] HmacMdContext Pointer to the HMAC-MD context.
184 @param[out] HmacValue Pointer to a buffer that receives the HMAC-MD digest
185 value.
186
187 @retval TRUE HMAC-MD digest computation succeeded.
188 @retval FALSE HMAC-MD digest computation failed.
189
190 **/
191 STATIC
192 BOOLEAN
193 HmacMdFinal (
194 IN OUT VOID *HmacMdContext,
195 OUT UINT8 *HmacValue
196 )
197 {
198 UINT32 Length;
199
200 //
201 // Check input parameters.
202 //
203 if ((HmacMdContext == NULL) || (HmacValue == NULL)) {
204 return FALSE;
205 }
206
207 //
208 // OpenSSL HMAC-MD digest finalization
209 //
210 if (HMAC_Final ((HMAC_CTX *)HmacMdContext, HmacValue, &Length) != 1) {
211 return FALSE;
212 }
213
214 if (HMAC_CTX_reset ((HMAC_CTX *)HmacMdContext) != 1) {
215 return FALSE;
216 }
217
218 return TRUE;
219 }
220
221 /**
222 Computes the HMAC-MD digest of a input data buffer.
223
224 This function performs the HMAC-MD digest of a given data buffer, and places
225 the digest value into the specified memory.
226
227 If this interface is not supported, then return FALSE.
228
229 @param[in] Md Message Digest.
230 @param[in] Data Pointer to the buffer containing the data to be digested.
231 @param[in] DataSize Size of Data buffer in bytes.
232 @param[in] Key Pointer to the user-supplied key.
233 @param[in] KeySize Key size in bytes.
234 @param[out] HmacValue Pointer to a buffer that receives the HMAC-MD digest
235 value.
236
237 @retval TRUE HMAC-MD digest computation succeeded.
238 @retval FALSE HMAC-MD digest computation failed.
239 @retval FALSE This interface is not supported.
240
241 **/
242 STATIC
243 BOOLEAN
244 HmacMdAll (
245 IN CONST EVP_MD *Md,
246 IN CONST VOID *Data,
247 IN UINTN DataSize,
248 IN CONST UINT8 *Key,
249 IN UINTN KeySize,
250 OUT UINT8 *HmacValue
251 )
252 {
253 UINT32 Length;
254 HMAC_CTX *Ctx;
255 BOOLEAN RetVal;
256
257 Ctx = HMAC_CTX_new ();
258 if (Ctx == NULL) {
259 return FALSE;
260 }
261
262 RetVal = (BOOLEAN)HMAC_CTX_reset (Ctx);
263 if (!RetVal) {
264 goto Done;
265 }
266
267 RetVal = (BOOLEAN)HMAC_Init_ex (Ctx, Key, (UINT32)KeySize, Md, NULL);
268 if (!RetVal) {
269 goto Done;
270 }
271
272 RetVal = (BOOLEAN)HMAC_Update (Ctx, Data, DataSize);
273 if (!RetVal) {
274 goto Done;
275 }
276
277 RetVal = (BOOLEAN)HMAC_Final (Ctx, HmacValue, &Length);
278 if (!RetVal) {
279 goto Done;
280 }
281
282 Done:
283 HMAC_CTX_free (Ctx);
284
285 return RetVal;
286 }
287
288 /**
289 Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA256 use.
290
291 @return Pointer to the HMAC_CTX context that has been initialized.
292 If the allocations fails, HmacSha256New() returns NULL.
293
294 **/
295 VOID *
296 EFIAPI
297 HmacSha256New (
298 VOID
299 )
300 {
301 return HmacMdNew ();
302 }
303
304 /**
305 Release the specified HMAC_CTX context.
306
307 @param[in] HmacSha256Ctx Pointer to the HMAC_CTX context to be released.
308
309 **/
310 VOID
311 EFIAPI
312 HmacSha256Free (
313 IN VOID *HmacSha256Ctx
314 )
315 {
316 HmacMdFree (HmacSha256Ctx);
317 }
318
319 /**
320 Set user-supplied key for subsequent use. It must be done before any
321 calling to HmacSha256Update().
322
323 If HmacSha256Context is NULL, then return FALSE.
324
325 @param[out] HmacSha256Context Pointer to HMAC-SHA256 context.
326 @param[in] Key Pointer to the user-supplied key.
327 @param[in] KeySize Key size in bytes.
328
329 @retval TRUE The Key is set successfully.
330 @retval FALSE The Key is set unsuccessfully.
331
332 **/
333 BOOLEAN
334 EFIAPI
335 HmacSha256SetKey (
336 OUT VOID *HmacSha256Context,
337 IN CONST UINT8 *Key,
338 IN UINTN KeySize
339 )
340 {
341 return HmacMdSetKey (EVP_sha256 (), HmacSha256Context, Key, KeySize);
342 }
343
344 /**
345 Makes a copy of an existing HMAC-SHA256 context.
346
347 If HmacSha256Context is NULL, then return FALSE.
348 If NewHmacSha256Context is NULL, then return FALSE.
349
350 @param[in] HmacSha256Context Pointer to HMAC-SHA256 context being copied.
351 @param[out] NewHmacSha256Context Pointer to new HMAC-SHA256 context.
352
353 @retval TRUE HMAC-SHA256 context copy succeeded.
354 @retval FALSE HMAC-SHA256 context copy failed.
355
356 **/
357 BOOLEAN
358 EFIAPI
359 HmacSha256Duplicate (
360 IN CONST VOID *HmacSha256Context,
361 OUT VOID *NewHmacSha256Context
362 )
363 {
364 return HmacMdDuplicate (HmacSha256Context, NewHmacSha256Context);
365 }
366
367 /**
368 Digests the input data and updates HMAC-SHA256 context.
369
370 This function performs HMAC-SHA256 digest on a data buffer of the specified size.
371 It can be called multiple times to compute the digest of long or discontinuous data streams.
372 HMAC-SHA256 context should be initialized by HmacSha256New(), and should not be finalized
373 by HmacSha256Final(). Behavior with invalid context is undefined.
374
375 If HmacSha256Context is NULL, then return FALSE.
376
377 @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
378 @param[in] Data Pointer to the buffer containing the data to be digested.
379 @param[in] DataSize Size of Data buffer in bytes.
380
381 @retval TRUE HMAC-SHA256 data digest succeeded.
382 @retval FALSE HMAC-SHA256 data digest failed.
383
384 **/
385 BOOLEAN
386 EFIAPI
387 HmacSha256Update (
388 IN OUT VOID *HmacSha256Context,
389 IN CONST VOID *Data,
390 IN UINTN DataSize
391 )
392 {
393 return HmacMdUpdate (HmacSha256Context, Data, DataSize);
394 }
395
396 /**
397 Completes computation of the HMAC-SHA256 digest value.
398
399 This function completes HMAC-SHA256 hash computation and retrieves the digest value into
400 the specified memory. After this function has been called, the HMAC-SHA256 context cannot
401 be used again.
402 HMAC-SHA256 context should be initialized by HmacSha256New(), and should not be finalized
403 by HmacSha256Final(). Behavior with invalid HMAC-SHA256 context is undefined.
404
405 If HmacSha256Context is NULL, then return FALSE.
406 If HmacValue is NULL, then return FALSE.
407
408 @param[in, out] HmacSha256Context Pointer to the HMAC-SHA256 context.
409 @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest
410 value (32 bytes).
411
412 @retval TRUE HMAC-SHA256 digest computation succeeded.
413 @retval FALSE HMAC-SHA256 digest computation failed.
414
415 **/
416 BOOLEAN
417 EFIAPI
418 HmacSha256Final (
419 IN OUT VOID *HmacSha256Context,
420 OUT UINT8 *HmacValue
421 )
422 {
423 return HmacMdFinal (HmacSha256Context, HmacValue);
424 }
425
426 /**
427 Computes the HMAC-SHA256 digest of a input data buffer.
428
429 This function performs the HMAC-SHA256 digest of a given data buffer, and places
430 the digest value into the specified memory.
431
432 If this interface is not supported, then return FALSE.
433
434 @param[in] Data Pointer to the buffer containing the data to be digested.
435 @param[in] DataSize Size of Data buffer in bytes.
436 @param[in] Key Pointer to the user-supplied key.
437 @param[in] KeySize Key size in bytes.
438 @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA256 digest
439 value (32 bytes).
440
441 @retval TRUE HMAC-SHA256 digest computation succeeded.
442 @retval FALSE HMAC-SHA256 digest computation failed.
443 @retval FALSE This interface is not supported.
444
445 **/
446 BOOLEAN
447 EFIAPI
448 HmacSha256All (
449 IN CONST VOID *Data,
450 IN UINTN DataSize,
451 IN CONST UINT8 *Key,
452 IN UINTN KeySize,
453 OUT UINT8 *HmacValue
454 )
455 {
456 return HmacMdAll (EVP_sha256 (), Data, DataSize, Key, KeySize, HmacValue);
457 }
458
459 /**
460 Allocates and initializes one HMAC_CTX context for subsequent HMAC-SHA384 use.
461
462 @return Pointer to the HMAC_CTX context that has been initialized.
463 If the allocations fails, HmacSha384New() returns NULL.
464
465 **/
466 VOID *
467 EFIAPI
468 HmacSha384New (
469 VOID
470 )
471 {
472 return HmacMdNew ();
473 }
474
475 /**
476 Release the specified HMAC_CTX context.
477
478 @param[in] HmacSha384Ctx Pointer to the HMAC_CTX context to be released.
479
480 **/
481 VOID
482 EFIAPI
483 HmacSha384Free (
484 IN VOID *HmacSha384Ctx
485 )
486 {
487 HmacMdFree (HmacSha384Ctx);
488 }
489
490 /**
491 Set user-supplied key for subsequent use. It must be done before any
492 calling to HmacSha384Update().
493
494 If HmacSha384Context is NULL, then return FALSE.
495 If this interface is not supported, then return FALSE.
496
497 @param[out] HmacSha384Context Pointer to HMAC-SHA384 context.
498 @param[in] Key Pointer to the user-supplied key.
499 @param[in] KeySize Key size in bytes.
500
501 @retval TRUE The Key is set successfully.
502 @retval FALSE The Key is set unsuccessfully.
503 @retval FALSE This interface is not supported.
504
505 **/
506 BOOLEAN
507 EFIAPI
508 HmacSha384SetKey (
509 OUT VOID *HmacSha384Context,
510 IN CONST UINT8 *Key,
511 IN UINTN KeySize
512 )
513 {
514 return HmacMdSetKey (EVP_sha384 (), HmacSha384Context, Key, KeySize);
515 }
516
517 /**
518 Makes a copy of an existing HMAC-SHA384 context.
519
520 If HmacSha384Context is NULL, then return FALSE.
521 If NewHmacSha384Context is NULL, then return FALSE.
522 If this interface is not supported, then return FALSE.
523
524 @param[in] HmacSha384Context Pointer to HMAC-SHA384 context being copied.
525 @param[out] NewHmacSha384Context Pointer to new HMAC-SHA384 context.
526
527 @retval TRUE HMAC-SHA384 context copy succeeded.
528 @retval FALSE HMAC-SHA384 context copy failed.
529 @retval FALSE This interface is not supported.
530
531 **/
532 BOOLEAN
533 EFIAPI
534 HmacSha384Duplicate (
535 IN CONST VOID *HmacSha384Context,
536 OUT VOID *NewHmacSha384Context
537 )
538 {
539 return HmacMdDuplicate (HmacSha384Context, NewHmacSha384Context);
540 }
541
542 /**
543 Digests the input data and updates HMAC-SHA384 context.
544
545 This function performs HMAC-SHA384 digest on a data buffer of the specified size.
546 It can be called multiple times to compute the digest of long or discontinuous data streams.
547 HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized
548 by HmacSha384Final(). Behavior with invalid context is undefined.
549
550 If HmacSha384Context is NULL, then return FALSE.
551 If this interface is not supported, then return FALSE.
552
553 @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context.
554 @param[in] Data Pointer to the buffer containing the data to be digested.
555 @param[in] DataSize Size of Data buffer in bytes.
556
557 @retval TRUE HMAC-SHA384 data digest succeeded.
558 @retval FALSE HMAC-SHA384 data digest failed.
559 @retval FALSE This interface is not supported.
560
561 **/
562 BOOLEAN
563 EFIAPI
564 HmacSha384Update (
565 IN OUT VOID *HmacSha384Context,
566 IN CONST VOID *Data,
567 IN UINTN DataSize
568 )
569 {
570 return HmacMdUpdate (HmacSha384Context, Data, DataSize);
571 }
572
573 /**
574 Completes computation of the HMAC-SHA384 digest value.
575
576 This function completes HMAC-SHA384 hash computation and retrieves the digest value into
577 the specified memory. After this function has been called, the HMAC-SHA384 context cannot
578 be used again.
579 HMAC-SHA384 context should be initialized by HmacSha384New(), and should not be finalized
580 by HmacSha384Final(). Behavior with invalid HMAC-SHA384 context is undefined.
581
582 If HmacSha384Context is NULL, then return FALSE.
583 If HmacValue is NULL, then return FALSE.
584 If this interface is not supported, then return FALSE.
585
586 @param[in, out] HmacSha384Context Pointer to the HMAC-SHA384 context.
587 @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest
588 value (48 bytes).
589
590 @retval TRUE HMAC-SHA384 digest computation succeeded.
591 @retval FALSE HMAC-SHA384 digest computation failed.
592 @retval FALSE This interface is not supported.
593
594 **/
595 BOOLEAN
596 EFIAPI
597 HmacSha384Final (
598 IN OUT VOID *HmacSha384Context,
599 OUT UINT8 *HmacValue
600 )
601 {
602 return HmacMdFinal (HmacSha384Context, HmacValue);
603 }
604
605 /**
606 Computes the HMAC-SHA384 digest of a input data buffer.
607
608 This function performs the HMAC-SHA384 digest of a given data buffer, and places
609 the digest value into the specified memory.
610
611 If this interface is not supported, then return FALSE.
612
613 @param[in] Data Pointer to the buffer containing the data to be digested.
614 @param[in] DataSize Size of Data buffer in bytes.
615 @param[in] Key Pointer to the user-supplied key.
616 @param[in] KeySize Key size in bytes.
617 @param[out] HmacValue Pointer to a buffer that receives the HMAC-SHA384 digest
618 value (48 bytes).
619
620 @retval TRUE HMAC-SHA384 digest computation succeeded.
621 @retval FALSE HMAC-SHA384 digest computation failed.
622 @retval FALSE This interface is not supported.
623
624 **/
625 BOOLEAN
626 EFIAPI
627 HmacSha384All (
628 IN CONST VOID *Data,
629 IN UINTN DataSize,
630 IN CONST UINT8 *Key,
631 IN UINTN KeySize,
632 OUT UINT8 *HmacValue
633 )
634 {
635 return HmacMdAll (EVP_sha384 (), Data, DataSize, Key, KeySize, HmacValue);
636 }