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