+/** @file\r
+ This module implements Hash2 Protocol.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <Protocol/Hash2.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
+#include "Driver.h"\r
+\r
+/**\r
+ Retrieves the size, in bytes, of the context buffer required for hash operations.\r
+\r
+ If this interface is not supported, then return zero.\r
+\r
+ @return The size, in bytes, of the context buffer required for hash operations.\r
+ @retval 0 This interface is not supported.\r
+\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE) (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Initializes user-supplied memory pointed by Sha1Context as hash context for\r
+ subsequent use.\r
+\r
+ If HashContext is NULL, then return FALSE.\r
+ If this interface is not supported, then return FALSE.\r
+\r
+ @param[out] HashContext Pointer to Hashcontext being initialized.\r
+\r
+ @retval TRUE Hash context initialization succeeded.\r
+ @retval FALSE Hash context initialization failed.\r
+ @retval FALSE This interface is not supported.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_HASH_INIT) (\r
+ OUT VOID *HashContext\r
+ );\r
+\r
+/**\r
+ Digests the input data and updates Hash context.\r
+\r
+ This function performs Hash digest on a data buffer of the specified size.\r
+ It can be called multiple times to compute the digest of long or discontinuous data streams.\r
+ Hash context should be already correctly intialized by HashInit(), and should not be finalized\r
+ by HashFinal(). Behavior with invalid context is undefined.\r
+\r
+ If HashContext is NULL, then return FALSE.\r
+ If this interface is not supported, then return FALSE.\r
+\r
+ @param[in, out] HashContext Pointer to the Hash context.\r
+ @param[in] Data Pointer to the buffer containing the data to be hashed.\r
+ @param[in] DataSize Size of Data buffer in bytes.\r
+\r
+ @retval TRUE SHA-1 data digest succeeded.\r
+ @retval FALSE SHA-1 data digest failed.\r
+ @retval FALSE This interface is not supported.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_HASH_UPDATE) (\r
+ IN OUT VOID *HashContext,\r
+ IN CONST VOID *Data,\r
+ IN UINTN DataSize\r
+ );\r
+\r
+/**\r
+ Completes computation of the Hash digest value.\r
+\r
+ This function completes hash computation and retrieves the digest value into\r
+ the specified memory. After this function has been called, the Hash context cannot\r
+ be used again.\r
+ Hash context should be already correctly intialized by HashInit(), and should not be\r
+ finalized by HashFinal(). Behavior with invalid Hash context is undefined.\r
+\r
+ If HashContext is NULL, then return FALSE.\r
+ If HashValue is NULL, then return FALSE.\r
+ If this interface is not supported, then return FALSE.\r
+\r
+ @param[in, out] HashContext Pointer to the Hash context.\r
+ @param[out] HashValue Pointer to a buffer that receives the Hash digest\r
+ value.\r
+\r
+ @retval TRUE Hash digest computation succeeded.\r
+ @retval FALSE Hash digest computation failed.\r
+ @retval FALSE This interface is not supported.\r
+\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_HASH_FINAL) (\r
+ IN OUT VOID *HashContext,\r
+ OUT UINT8 *HashValue\r
+ );\r
+\r
+typedef struct {\r
+ EFI_GUID *Guid;\r
+ UINT32 HashSize;\r
+ EFI_HASH_GET_CONTEXT_SIZE GetContextSize;\r
+ EFI_HASH_INIT Init;\r
+ EFI_HASH_UPDATE Update;\r
+ EFI_HASH_FINAL Final;\r
+} EFI_HASH_INFO;\r
+\r
+EFI_HASH_INFO mHashInfo[] = {\r
+ {&gEfiHashAlgorithmSha1Guid, sizeof(EFI_SHA1_HASH2), Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final },\r
+ {&gEfiHashAlgorithmSha256Guid, sizeof(EFI_SHA256_HASH2), Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },\r
+ {&gEfiHashAlgorithmSha384Guid, sizeof(EFI_SHA384_HASH2), Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },\r
+ {&gEfiHashAlgorithmSha512Guid, sizeof(EFI_SHA512_HASH2), Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final },\r
+};\r
+\r
+/**\r
+ Returns the size of the hash which results from a specific algorithm.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+ @param[out] HashSize Holds the returned size of the algorithm's hash.\r
+\r
+ @retval EFI_SUCCESS Hash size returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or HashSize is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is null.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2GetHashSize (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm,\r
+ OUT UINTN *HashSize\r
+ );\r
+\r
+/**\r
+ Creates a hash for the specified message text. The hash is not extendable.\r
+ The output is final with any algorithm-required padding added by the function.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+ @param[in] Message Points to the start of the message.\r
+ @param[in] MessageSize The size of Message, in bytes.\r
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size\r
+ returned by GetHashSize() for the specified HashAlgorithm.\r
+ On output, the buffer holds the resulting hash computed from the message.\r
+\r
+ @retval EFI_SUCCESS Hash returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is Null.\r
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available\r
+ or MessageSize is greater than platform maximum.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2Hash (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm,\r
+ IN CONST UINT8 *Message,\r
+ IN UINTN MessageSize,\r
+ IN OUT EFI_HASH2_OUTPUT *Hash\r
+ );\r
+\r
+/**\r
+ This function must be called to initialize a digest calculation to be subsequently performed using the\r
+ EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+\r
+ @retval EFI_SUCCESS Initialized successfully.\r
+ @retval EFI_INVALID_PARAMETER This is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is Null.\r
+ @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.\r
+ @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),\r
+ or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashInit (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm\r
+ );\r
+\r
+/**\r
+ Updates the hash of a computation in progress by adding a message text.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] Message Points to the start of the message.\r
+ @param[in] MessageSize The size of Message, in bytes.\r
+\r
+ @retval EFI_SUCCESS Digest in progress updated successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available\r
+ or MessageSize is greater than platform maximum.\r
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),\r
+ or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashUpdate (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST UINT8 *Message,\r
+ IN UINTN MessageSize\r
+ );\r
+\r
+/**\r
+ Finalizes a hash operation in progress and returns calculation result.\r
+ The output is final with any necessary padding added by the function.\r
+ The hash may not be further updated or extended after HashFinal().\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size\r
+ returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().\r
+ On output, the buffer holds the resulting hash computed from the message.\r
+\r
+ @retval EFI_SUCCESS Hash returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),\r
+ or the operation in progress was canceled by a call to Hash() on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashFinal (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN OUT EFI_HASH2_OUTPUT *Hash\r
+ );\r
+\r
+EFI_HASH2_PROTOCOL mHash2Protocol = {\r
+ BaseCrypto2GetHashSize,\r
+ BaseCrypto2Hash,\r
+ BaseCrypto2HashInit,\r
+ BaseCrypto2HashUpdate,\r
+ BaseCrypto2HashFinal,\r
+};\r
+\r
+/**\r
+ Returns hash information.\r
+\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+\r
+ @return Hash information.\r
+**/\r
+EFI_HASH_INFO *\r
+GetHashInfo (\r
+ IN CONST EFI_GUID *HashAlgorithm\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) {\r
+ if (CompareGuid (HashAlgorithm, mHashInfo[Index].Guid)) {\r
+ return &mHashInfo[Index];\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Returns the size of the hash which results from a specific algorithm.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+ @param[out] HashSize Holds the returned size of the algorithm's hash.\r
+\r
+ @retval EFI_SUCCESS Hash size returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or HashSize is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is null.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2GetHashSize (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm,\r
+ OUT UINTN *HashSize\r
+ )\r
+{\r
+ EFI_HASH_INFO *HashInfo;\r
+\r
+ if ((This == NULL) || (HashSize == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (HashAlgorithm == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ HashInfo = GetHashInfo (HashAlgorithm);\r
+ if (HashInfo == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ *HashSize = HashInfo->HashSize;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Creates a hash for the specified message text. The hash is not extendable.\r
+ The output is final with any algorithm-required padding added by the function.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+ @param[in] Message Points to the start of the message.\r
+ @param[in] MessageSize The size of Message, in bytes.\r
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size\r
+ returned by GetHashSize() for the specified HashAlgorithm.\r
+ On output, the buffer holds the resulting hash computed from the message.\r
+\r
+ @retval EFI_SUCCESS Hash returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is Null.\r
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available\r
+ or MessageSize is greater than platform maximum.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2Hash (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm,\r
+ IN CONST UINT8 *Message,\r
+ IN UINTN MessageSize,\r
+ IN OUT EFI_HASH2_OUTPUT *Hash\r
+ )\r
+{\r
+ EFI_HASH_INFO *HashInfo;\r
+ VOID *HashCtx;\r
+ UINTN CtxSize;\r
+ BOOLEAN Ret;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if ((This == NULL) || (Hash == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (HashAlgorithm == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ HashInfo = GetHashInfo (HashAlgorithm);\r
+ if (HashInfo == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Start hash sequence\r
+ //\r
+ CtxSize = HashInfo->GetContextSize ();\r
+ if (CtxSize == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ HashCtx = AllocatePool (CtxSize);\r
+ if (HashCtx == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Ret = HashInfo->Init (HashCtx);\r
+ if (!Ret) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ Ret = HashInfo->Update (HashCtx, Message, MessageSize);\r
+ if (!Ret) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+\r
+ Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);\r
+ if (!Ret) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Done;\r
+ }\r
+Done:\r
+ FreePool (HashCtx);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function must be called to initialize a digest calculation to be subsequently performed using the\r
+ EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal().\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.\r
+\r
+ @retval EFI_SUCCESS Initialized successfully.\r
+ @retval EFI_INVALID_PARAMETER This is NULL.\r
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver\r
+ or HashAlgorithm is Null.\r
+ @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource.\r
+ @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(),\r
+ or HashInit() is already called before and not terminated by HashFinal() yet on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashInit (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST EFI_GUID *HashAlgorithm\r
+ )\r
+{\r
+ EFI_HASH_INFO *HashInfo;\r
+ VOID *HashCtx;\r
+ UINTN CtxSize;\r
+ BOOLEAN Ret;\r
+ HASH2_INSTANCE_DATA *Instance;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (HashAlgorithm == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ HashInfo = GetHashInfo (HashAlgorithm);\r
+ if (HashInfo == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Consistency Check\r
+ //\r
+ Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);\r
+ if ((Instance->HashContext != NULL) || (Instance->HashInfoContext != HashInfo)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Start hash sequence\r
+ //\r
+ CtxSize = HashInfo->GetContextSize ();\r
+ if (CtxSize == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ HashCtx = AllocatePool (CtxSize);\r
+ if (HashCtx == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Ret = HashInfo->Init (HashCtx);\r
+ if (!Ret) {\r
+ FreePool (HashCtx);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Setup the context\r
+ //\r
+ Instance->HashContext = HashCtx;\r
+ Instance->HashInfoContext = HashInfo;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Updates the hash of a computation in progress by adding a message text.\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in] Message Points to the start of the message.\r
+ @param[in] MessageSize The size of Message, in bytes.\r
+\r
+ @retval EFI_SUCCESS Digest in progress updated successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available\r
+ or MessageSize is greater than platform maximum.\r
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(),\r
+ or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashUpdate (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN CONST UINT8 *Message,\r
+ IN UINTN MessageSize\r
+ )\r
+{\r
+ EFI_HASH_INFO *HashInfo;\r
+ VOID *HashCtx;\r
+ BOOLEAN Ret;\r
+ HASH2_INSTANCE_DATA *Instance;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Consistency Check\r
+ //\r
+ Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);\r
+ if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ HashInfo = Instance->HashInfoContext;\r
+ HashCtx = Instance->HashContext;\r
+\r
+ Ret = HashInfo->Update (HashCtx, Message, MessageSize);\r
+ if (!Ret) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Finalizes a hash operation in progress and returns calculation result.\r
+ The output is final with any necessary padding added by the function.\r
+ The hash may not be further updated or extended after HashFinal().\r
+\r
+ @param[in] This Points to this instance of EFI_HASH2_PROTOCOL.\r
+ @param[in,out] Hash On input, points to a caller-allocated buffer of the size\r
+ returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit().\r
+ On output, the buffer holds the resulting hash computed from the message.\r
+\r
+ @retval EFI_SUCCESS Hash returned successfully.\r
+ @retval EFI_INVALID_PARAMETER This or Hash is NULL.\r
+ @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(),\r
+ or the operation in progress was canceled by a call to Hash() on the same instance.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BaseCrypto2HashFinal (\r
+ IN CONST EFI_HASH2_PROTOCOL *This,\r
+ IN OUT EFI_HASH2_OUTPUT *Hash\r
+ )\r
+{\r
+ EFI_HASH_INFO *HashInfo;\r
+ VOID *HashCtx;\r
+ BOOLEAN Ret;\r
+ HASH2_INSTANCE_DATA *Instance;\r
+\r
+ if ((This == NULL) || (Hash == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Consistency Check\r
+ //\r
+ Instance = HASH2_INSTANCE_DATA_FROM_THIS(This);\r
+ if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) {\r
+ return EFI_NOT_READY;\r
+ }\r
+ HashInfo = Instance->HashInfoContext;\r
+ HashCtx = Instance->HashContext;\r
+\r
+ Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash);\r
+\r
+ //\r
+ // Cleanup the context\r
+ //\r
+ FreePool (HashCtx);\r
+ Instance->HashInfoContext = NULL;\r
+ Instance->HashContext = NULL;\r
+\r
+ if (!Ret) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r