2 This module implements Hash2 Protocol.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Protocol/Hash2.h>
12 #include <Library/BaseLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
14 #include <Library/MemoryAllocationLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseCryptLib.h>
22 Retrieves the size, in bytes, of the context buffer required for hash operations.
24 If this interface is not supported, then return zero.
26 @return The size, in bytes, of the context buffer required for hash operations.
27 @retval 0 This interface is not supported.
32 (EFIAPI
*EFI_HASH_GET_CONTEXT_SIZE
) (
37 Initializes user-supplied memory pointed by Sha1Context as hash context for
40 If HashContext is NULL, then return FALSE.
41 If this interface is not supported, then return FALSE.
43 @param[out] HashContext Pointer to Hashcontext being initialized.
45 @retval TRUE Hash context initialization succeeded.
46 @retval FALSE Hash context initialization failed.
47 @retval FALSE This interface is not supported.
52 (EFIAPI
*EFI_HASH_INIT
) (
57 Digests the input data and updates Hash context.
59 This function performs Hash digest on a data buffer of the specified size.
60 It can be called multiple times to compute the digest of long or discontinuous data streams.
61 Hash context should be already correctly initialized by HashInit(), and should not be finalized
62 by HashFinal(). Behavior with invalid context is undefined.
64 If HashContext is NULL, then return FALSE.
65 If this interface is not supported, then return FALSE.
67 @param[in, out] HashContext Pointer to the Hash context.
68 @param[in] Data Pointer to the buffer containing the data to be hashed.
69 @param[in] DataSize Size of Data buffer in bytes.
71 @retval TRUE SHA-1 data digest succeeded.
72 @retval FALSE SHA-1 data digest failed.
73 @retval FALSE This interface is not supported.
78 (EFIAPI
*EFI_HASH_UPDATE
) (
79 IN OUT VOID
*HashContext
,
85 Completes computation of the Hash digest value.
87 This function completes hash computation and retrieves the digest value into
88 the specified memory. After this function has been called, the Hash context cannot
90 Hash context should be already correctly intialized by HashInit(), and should not be
91 finalized by HashFinal(). Behavior with invalid Hash context is undefined.
93 If HashContext is NULL, then return FALSE.
94 If HashValue is NULL, then return FALSE.
95 If this interface is not supported, then return FALSE.
97 @param[in, out] HashContext Pointer to the Hash context.
98 @param[out] HashValue Pointer to a buffer that receives the Hash digest
101 @retval TRUE Hash digest computation succeeded.
102 @retval FALSE Hash digest computation failed.
103 @retval FALSE This interface is not supported.
108 (EFIAPI
*EFI_HASH_FINAL
) (
109 IN OUT VOID
*HashContext
,
116 EFI_HASH_GET_CONTEXT_SIZE GetContextSize
;
118 EFI_HASH_UPDATE Update
;
119 EFI_HASH_FINAL Final
;
122 EFI_HASH_INFO mHashInfo
[] = {
123 {&gEfiHashAlgorithmMD5Guid
, sizeof(EFI_MD5_HASH2
), Md5GetContextSize
, Md5Init
, Md5Update
, Md5Final
},
124 {&gEfiHashAlgorithmSha1Guid
, sizeof(EFI_SHA1_HASH2
), Sha1GetContextSize
, Sha1Init
, Sha1Update
, Sha1Final
},
125 {&gEfiHashAlgorithmSha256Guid
, sizeof(EFI_SHA256_HASH2
), Sha256GetContextSize
, Sha256Init
, Sha256Update
, Sha256Final
},
126 {&gEfiHashAlgorithmSha384Guid
, sizeof(EFI_SHA384_HASH2
), Sha384GetContextSize
, Sha384Init
, Sha384Update
, Sha384Final
},
127 {&gEfiHashAlgorithmSha512Guid
, sizeof(EFI_SHA512_HASH2
), Sha512GetContextSize
, Sha512Init
, Sha512Update
, Sha512Final
},
131 Returns the size of the hash which results from a specific algorithm.
133 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
134 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
135 @param[out] HashSize Holds the returned size of the algorithm's hash.
137 @retval EFI_SUCCESS Hash size returned successfully.
138 @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
139 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
140 or HashAlgorithm is null.
145 BaseCrypto2GetHashSize (
146 IN CONST EFI_HASH2_PROTOCOL
*This
,
147 IN CONST EFI_GUID
*HashAlgorithm
,
152 Creates a hash for the specified message text. The hash is not extendable.
153 The output is final with any algorithm-required padding added by the function.
155 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
156 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
157 @param[in] Message Points to the start of the message.
158 @param[in] MessageSize The size of Message, in bytes.
159 @param[in,out] Hash On input, points to a caller-allocated buffer of the size
160 returned by GetHashSize() for the specified HashAlgorithm.
161 On output, the buffer holds the resulting hash computed from the message.
163 @retval EFI_SUCCESS Hash returned successfully.
164 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
165 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
166 or HashAlgorithm is Null.
167 @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
168 or MessageSize is greater than platform maximum.
174 IN CONST EFI_HASH2_PROTOCOL
*This
,
175 IN CONST EFI_GUID
*HashAlgorithm
,
176 IN CONST UINT8
*Message
,
177 IN UINTN MessageSize
,
178 IN OUT EFI_HASH2_OUTPUT
*Hash
182 This function must be called to initialize a digest calculation to be subsequently performed using the
183 EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
185 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
186 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
188 @retval EFI_SUCCESS Initialized successfully.
189 @retval EFI_INVALID_PARAMETER This is NULL.
190 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
191 or HashAlgorithm is Null.
192 @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.
193 @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),
194 or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
199 BaseCrypto2HashInit (
200 IN CONST EFI_HASH2_PROTOCOL
*This
,
201 IN CONST EFI_GUID
*HashAlgorithm
205 Updates the hash of a computation in progress by adding a message text.
207 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
208 @param[in] Message Points to the start of the message.
209 @param[in] MessageSize The size of Message, in bytes.
211 @retval EFI_SUCCESS Digest in progress updated successfully.
212 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
213 @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
214 or MessageSize is greater than platform maximum.
215 @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),
216 or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
221 BaseCrypto2HashUpdate (
222 IN CONST EFI_HASH2_PROTOCOL
*This
,
223 IN CONST UINT8
*Message
,
228 Finalizes a hash operation in progress and returns calculation result.
229 The output is final with any necessary padding added by the function.
230 The hash may not be further updated or extended after HashFinal().
232 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
233 @param[in,out] Hash On input, points to a caller-allocated buffer of the size
234 returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
235 On output, the buffer holds the resulting hash computed from the message.
237 @retval EFI_SUCCESS Hash returned successfully.
238 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
239 @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
240 or the operation in progress was canceled by a call to Hash() on the same instance.
245 BaseCrypto2HashFinal (
246 IN CONST EFI_HASH2_PROTOCOL
*This
,
247 IN OUT EFI_HASH2_OUTPUT
*Hash
250 EFI_HASH2_PROTOCOL mHash2Protocol
= {
251 BaseCrypto2GetHashSize
,
254 BaseCrypto2HashUpdate
,
255 BaseCrypto2HashFinal
,
259 Returns hash information.
261 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
263 @return Hash information.
267 IN CONST EFI_GUID
*HashAlgorithm
272 for (Index
= 0; Index
< sizeof(mHashInfo
)/sizeof(mHashInfo
[0]); Index
++) {
273 if (CompareGuid (HashAlgorithm
, mHashInfo
[Index
].Guid
)) {
274 return &mHashInfo
[Index
];
281 Returns the size of the hash which results from a specific algorithm.
283 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
284 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
285 @param[out] HashSize Holds the returned size of the algorithm's hash.
287 @retval EFI_SUCCESS Hash size returned successfully.
288 @retval EFI_INVALID_PARAMETER This or HashSize is NULL.
289 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
290 or HashAlgorithm is null.
295 BaseCrypto2GetHashSize (
296 IN CONST EFI_HASH2_PROTOCOL
*This
,
297 IN CONST EFI_GUID
*HashAlgorithm
,
301 EFI_HASH_INFO
*HashInfo
;
303 if ((This
== NULL
) || (HashSize
== NULL
)) {
304 return EFI_INVALID_PARAMETER
;
307 if (HashAlgorithm
== NULL
) {
308 return EFI_UNSUPPORTED
;
311 HashInfo
= GetHashInfo (HashAlgorithm
);
312 if (HashInfo
== NULL
) {
313 return EFI_UNSUPPORTED
;
316 *HashSize
= HashInfo
->HashSize
;
321 Creates a hash for the specified message text. The hash is not extendable.
322 The output is final with any algorithm-required padding added by the function.
324 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
325 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
326 @param[in] Message Points to the start of the message.
327 @param[in] MessageSize The size of Message, in bytes.
328 @param[in,out] Hash On input, points to a caller-allocated buffer of the size
329 returned by GetHashSize() for the specified HashAlgorithm.
330 On output, the buffer holds the resulting hash computed from the message.
332 @retval EFI_SUCCESS Hash returned successfully.
333 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
334 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
335 or HashAlgorithm is Null.
336 @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
337 or MessageSize is greater than platform maximum.
343 IN CONST EFI_HASH2_PROTOCOL
*This
,
344 IN CONST EFI_GUID
*HashAlgorithm
,
345 IN CONST UINT8
*Message
,
346 IN UINTN MessageSize
,
347 IN OUT EFI_HASH2_OUTPUT
*Hash
350 EFI_HASH_INFO
*HashInfo
;
355 HASH2_INSTANCE_DATA
*Instance
;
357 Status
= EFI_SUCCESS
;
359 if ((This
== NULL
) || (Hash
== NULL
)) {
360 return EFI_INVALID_PARAMETER
;
363 if (HashAlgorithm
== NULL
) {
364 return EFI_UNSUPPORTED
;
367 HashInfo
= GetHashInfo (HashAlgorithm
);
368 if (HashInfo
== NULL
) {
369 return EFI_UNSUPPORTED
;
372 Instance
= HASH2_INSTANCE_DATA_FROM_THIS(This
);
373 if (Instance
->HashContext
!= NULL
) {
374 FreePool (Instance
->HashContext
);
376 Instance
->HashInfoContext
= NULL
;
377 Instance
->HashContext
= NULL
;
380 // Start hash sequence
382 CtxSize
= HashInfo
->GetContextSize ();
384 return EFI_UNSUPPORTED
;
386 HashCtx
= AllocatePool (CtxSize
);
387 if (HashCtx
== NULL
) {
388 return EFI_OUT_OF_RESOURCES
;
391 Ret
= HashInfo
->Init (HashCtx
);
393 Status
= EFI_OUT_OF_RESOURCES
;
400 Instance
->HashContext
= HashCtx
;
401 Instance
->HashInfoContext
= HashInfo
;
403 Ret
= HashInfo
->Update (HashCtx
, Message
, MessageSize
);
405 Status
= EFI_OUT_OF_RESOURCES
;
409 Ret
= HashInfo
->Final (HashCtx
, (UINT8
*)Hash
->Sha1Hash
);
411 Status
= EFI_OUT_OF_RESOURCES
;
416 // Cleanup the context
419 Instance
->HashInfoContext
= NULL
;
420 Instance
->HashContext
= NULL
;
425 This function must be called to initialize a digest calculation to be subsequently performed using the
426 EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().
428 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
429 @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
431 @retval EFI_SUCCESS Initialized successfully.
432 @retval EFI_INVALID_PARAMETER This is NULL.
433 @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver
434 or HashAlgorithm is Null.
435 @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.
436 @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),
437 or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.
442 BaseCrypto2HashInit (
443 IN CONST EFI_HASH2_PROTOCOL
*This
,
444 IN CONST EFI_GUID
*HashAlgorithm
447 EFI_HASH_INFO
*HashInfo
;
451 HASH2_INSTANCE_DATA
*Instance
;
454 return EFI_INVALID_PARAMETER
;
457 if (HashAlgorithm
== NULL
) {
458 return EFI_UNSUPPORTED
;
461 HashInfo
= GetHashInfo (HashAlgorithm
);
462 if (HashInfo
== NULL
) {
463 return EFI_UNSUPPORTED
;
469 Instance
= HASH2_INSTANCE_DATA_FROM_THIS(This
);
470 if ((Instance
->HashContext
!= NULL
) || (Instance
->HashInfoContext
!= NULL
)) {
471 return EFI_ALREADY_STARTED
;
475 // Start hash sequence
477 CtxSize
= HashInfo
->GetContextSize ();
479 return EFI_UNSUPPORTED
;
481 HashCtx
= AllocatePool (CtxSize
);
482 if (HashCtx
== NULL
) {
483 return EFI_OUT_OF_RESOURCES
;
486 Ret
= HashInfo
->Init (HashCtx
);
489 return EFI_OUT_OF_RESOURCES
;
495 Instance
->HashContext
= HashCtx
;
496 Instance
->HashInfoContext
= HashInfo
;
497 Instance
->Updated
= FALSE
;
503 Updates the hash of a computation in progress by adding a message text.
505 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
506 @param[in] Message Points to the start of the message.
507 @param[in] MessageSize The size of Message, in bytes.
509 @retval EFI_SUCCESS Digest in progress updated successfully.
510 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
511 @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available
512 or MessageSize is greater than platform maximum.
513 @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),
514 or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.
519 BaseCrypto2HashUpdate (
520 IN CONST EFI_HASH2_PROTOCOL
*This
,
521 IN CONST UINT8
*Message
,
525 EFI_HASH_INFO
*HashInfo
;
528 HASH2_INSTANCE_DATA
*Instance
;
531 return EFI_INVALID_PARAMETER
;
537 Instance
= HASH2_INSTANCE_DATA_FROM_THIS(This
);
538 if ((Instance
->HashContext
== NULL
) || (Instance
->HashInfoContext
== NULL
)) {
539 return EFI_NOT_READY
;
541 HashInfo
= Instance
->HashInfoContext
;
542 HashCtx
= Instance
->HashContext
;
544 Ret
= HashInfo
->Update (HashCtx
, Message
, MessageSize
);
546 return EFI_OUT_OF_RESOURCES
;
549 Instance
->Updated
= TRUE
;
555 Finalizes a hash operation in progress and returns calculation result.
556 The output is final with any necessary padding added by the function.
557 The hash may not be further updated or extended after HashFinal().
559 @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.
560 @param[in,out] Hash On input, points to a caller-allocated buffer of the size
561 returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().
562 On output, the buffer holds the resulting hash computed from the message.
564 @retval EFI_SUCCESS Hash returned successfully.
565 @retval EFI_INVALID_PARAMETER This or Hash is NULL.
566 @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),
567 or the operation in progress was canceled by a call to Hash() on the same instance.
572 BaseCrypto2HashFinal (
573 IN CONST EFI_HASH2_PROTOCOL
*This
,
574 IN OUT EFI_HASH2_OUTPUT
*Hash
577 EFI_HASH_INFO
*HashInfo
;
580 HASH2_INSTANCE_DATA
*Instance
;
582 if ((This
== NULL
) || (Hash
== NULL
)) {
583 return EFI_INVALID_PARAMETER
;
589 Instance
= HASH2_INSTANCE_DATA_FROM_THIS(This
);
590 if ((Instance
->HashContext
== NULL
) || (Instance
->HashInfoContext
== NULL
) ||
591 (!Instance
->Updated
)) {
592 return EFI_NOT_READY
;
594 HashInfo
= Instance
->HashInfoContext
;
595 HashCtx
= Instance
->HashContext
;
597 Ret
= HashInfo
->Final (HashCtx
, (UINT8
*)Hash
->Sha1Hash
);
600 // Cleanup the context
603 Instance
->HashInfoContext
= NULL
;
604 Instance
->HashContext
= NULL
;
605 Instance
->Updated
= FALSE
;
608 return EFI_OUT_OF_RESOURCES
;