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