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