From: Yao, Jiewen Date: Tue, 5 May 2015 01:40:16 +0000 (+0000) Subject: Add UEFI2.5 HASH protocol implementation. X-Git-Tag: edk2-stable201903~9963 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=724dcbb27247de46b1f09bc082198598cc9bad0d;hp=6e9eca81a96c3b313a206163f49670446745d7df Add UEFI2.5 HASH protocol implementation. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Long, Qin" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17288 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/SecurityPkg/Hash2DxeCrypto/Driver.c b/SecurityPkg/Hash2DxeCrypto/Driver.c new file mode 100644 index 0000000000..ba2fe6a2c4 --- /dev/null +++ b/SecurityPkg/Hash2DxeCrypto/Driver.c @@ -0,0 +1,242 @@ +/** @file + This is service binding for Hash driver. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Driver.h" + +EFI_SERVICE_BINDING_PROTOCOL mHash2ServiceBindingProtocol = { + Hash2ServiceBindingCreateChild, + Hash2ServiceBindingDestroyChild +}; + +/** + Creates a child handle with a set of I/O services. + + @param[in] This Protocol instance pointer. + @param[in, out] ChildHandle Pointer to the handle of the child to create. If + it is NULL, then a new handle is created. If + it is not NULL, then the I/O services are added + to the existing child handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to + create the child. + @retval Others The child handle was not created. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN OUT EFI_HANDLE *ChildHandle + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + HASH2_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This); + + // + // Allocate buffer for the new instance. + // + Instance = AllocateZeroPool (sizeof (HASH2_INSTANCE_DATA)); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Init the instance data. + // + Instance->Signature = HASH2_INSTANCE_DATA_SIGNATURE; + CopyMem (&Instance->Hash2Protocol, &mHash2Protocol, sizeof (Instance->Hash2Protocol)); + Instance->Hash2ServiceData = Hash2ServiceData; + + Status = gBS->InstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiHash2ProtocolGuid, + &Instance->Hash2Protocol, + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (Instance); + return Status; + } + + Instance->Handle = *ChildHandle; + + // + // Add the child instance into ChildrenList. + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + InsertTailList (&Hash2ServiceData->ChildrenList, &Instance->InstEntry); + + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + Destroys a child handle with a set of I/O services. + + The DestroyChild() function does the opposite of CreateChild(). It removes a + protocol that was installed by CreateChild() from ChildHandle. If the removed + protocol is the last protocol on ChildHandle, then ChildHandle is destroyed. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL + instance. + @param[in] ChildHandle Handle of the child to destroy. + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that + is being removed. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the + ChildHandle because its services are being + used. + @retval Others The child handle was not destroyed. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + EFI_HASH2_PROTOCOL *Hash2Protocol; + HASH2_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; + LIST_ENTRY *Entry; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This); + + // + // Check if this ChildHandle is valid + // + Instance = NULL; + for(Entry = (&Hash2ServiceData->ChildrenList)->ForwardLink; Entry != (&Hash2ServiceData->ChildrenList); Entry = Entry->ForwardLink) { + Instance = HASH2_INSTANCE_DATA_FROM_LINK (Entry); + if (Instance->Handle == ChildHandle) { + break; + } else { + Instance = NULL; + } + } + if (Instance == NULL) { + DEBUG ((EFI_D_ERROR, "Hash2ServiceBindingDestroyChild - Invalid handle\n")); + return EFI_UNSUPPORTED; + } + + // + // Get HashProtocol + // + Status = gBS->HandleProtocol ( + ChildHandle, + &gEfiHash2ProtocolGuid, + (VOID **)&Hash2Protocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (Hash2Protocol == &Instance->Hash2Protocol); + + // + // Uninstall the Hash protocol. + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiHash2ProtocolGuid, + &Instance->Hash2Protocol, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + // + // Remove this instance from the ChildrenList. + // + RemoveEntryList (&Instance->InstEntry); + + gBS->RestoreTPL (OldTpl); + + FreePool (Instance); + + return Status; +} + +/** + The entry point for Hash driver which installs the service binding protocol. + + @param[in] ImageHandle The image handle of the driver. + @param[in] SystemTable The system table. + + @retval EFI_SUCCES The service binding protocols is successfully installed. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +Hash2DriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + + // + // Initialize the Hash Service Data. + // + Hash2ServiceData = AllocateZeroPool (sizeof (HASH2_SERVICE_DATA)); + if (Hash2ServiceData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Hash2ServiceData->Signature = HASH2_SERVICE_DATA_SIGNATURE; + CopyMem (&Hash2ServiceData->ServiceBinding, &mHash2ServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL)); + InitializeListHead (&Hash2ServiceData->ChildrenList); + + // + // Install the HASH Service Binding Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Hash2ServiceData->ServiceHandle, + &gEfiHash2ServiceBindingProtocolGuid, + &Hash2ServiceData->ServiceBinding, + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (Hash2ServiceData); + } + + return Status; +} \ No newline at end of file diff --git a/SecurityPkg/Hash2DxeCrypto/Driver.h b/SecurityPkg/Hash2DxeCrypto/Driver.h new file mode 100644 index 0000000000..771aedc1ed --- /dev/null +++ b/SecurityPkg/Hash2DxeCrypto/Driver.h @@ -0,0 +1,131 @@ +/** @file + This is definition for service binding for Hash driver. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _HASH2_DRIVER_H_ +#define _HASH2_DRIVER_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define HASH2_SERVICE_DATA_SIGNATURE SIGNATURE_32 ('H', 'S', '2', 'S') + +typedef struct { + UINT32 Signature; + EFI_HANDLE ServiceHandle; + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; + + LIST_ENTRY ChildrenList; +} HASH2_SERVICE_DATA; + +#define HASH2_SERVICE_DATA_FROM_THIS(a) \ + CR ( \ + (a), \ + HASH2_SERVICE_DATA, \ + ServiceBinding, \ + HASH2_SERVICE_DATA_SIGNATURE \ + ) + +#define HASH2_INSTANCE_DATA_SIGNATURE SIGNATURE_32 ('H', 's', '2', 'I') + +typedef struct { + UINT32 Signature; + HASH2_SERVICE_DATA *Hash2ServiceData; + EFI_HANDLE Handle; + LIST_ENTRY InstEntry; + EFI_HASH2_PROTOCOL Hash2Protocol; + VOID *HashContext; + VOID *HashInfoContext; +} HASH2_INSTANCE_DATA; + +#define HASH2_INSTANCE_DATA_FROM_THIS(a) \ + CR ( \ + (a), \ + HASH2_INSTANCE_DATA, \ + Hash2Protocol, \ + HASH2_INSTANCE_DATA_SIGNATURE \ + ) + +#define HASH2_INSTANCE_DATA_FROM_LINK(a) \ + CR ( \ + (a), \ + HASH2_INSTANCE_DATA, \ + InstEntry, \ + HASH2_INSTANCE_DATA_SIGNATURE \ + ) + +/** + Creates a child handle with a set of I/O services. + + @param[in] This Protocol instance pointer. + @param[in, out] ChildHandle Pointer to the handle of the child to create. If + it is NULL, then a new handle is created. If + it is not NULL, then the I/O services are added + to the existing child handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to + create the child. + @retval Others The child handle was not created. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN OUT EFI_HANDLE *ChildHandle + ); + +/** + Destroys a child handle with a set of I/O services. + + The DestroyChild() function does the opposite of CreateChild(). It removes a + protocol that was installed by CreateChild() from ChildHandle. If the removed + protocol is the last protocol on ChildHandle, then ChildHandle is destroyed. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL + instance. + @param[in] ChildHandle Handle of the child to destroy. + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that + is being removed. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the + ChildHandle because its services are being + used. + @retval Others The child handle was not destroyed. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ); + +extern EFI_HASH2_PROTOCOL mHash2Protocol; + +#endif diff --git a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c new file mode 100644 index 0000000000..92cda36455 --- /dev/null +++ b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.c @@ -0,0 +1,592 @@ +/** @file + This module implements Hash2 Protocol. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Driver.h" + +/** + Retrieves the size, in bytes, of the context buffer required for hash operations. + + If this interface is not supported, then return zero. + + @return The size, in bytes, of the context buffer required for hash operations. + @retval 0 This interface is not supported. + +**/ +typedef +UINTN +(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE) ( + VOID + ); + +/** + Initializes user-supplied memory pointed by Sha1Context as hash context for + subsequent use. + + If HashContext is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[out] HashContext Pointer to Hashcontext being initialized. + + @retval TRUE Hash context initialization succeeded. + @retval FALSE Hash context initialization failed. + @retval FALSE This interface is not supported. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_HASH_INIT) ( + OUT VOID *HashContext + ); + +/** + Digests the input data and updates Hash context. + + This function performs Hash digest on a data buffer of the specified size. + It can be called multiple times to compute the digest of long or discontinuous data streams. + Hash context should be already correctly intialized by HashInit(), and should not be finalized + by HashFinal(). Behavior with invalid context is undefined. + + If HashContext is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HashContext Pointer to the Hash context. + @param[in] Data Pointer to the buffer containing the data to be hashed. + @param[in] DataSize Size of Data buffer in bytes. + + @retval TRUE SHA-1 data digest succeeded. + @retval FALSE SHA-1 data digest failed. + @retval FALSE This interface is not supported. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_HASH_UPDATE) ( + IN OUT VOID *HashContext, + IN CONST VOID *Data, + IN UINTN DataSize + ); + +/** + Completes computation of the Hash digest value. + + This function completes hash computation and retrieves the digest value into + the specified memory. After this function has been called, the Hash context cannot + be used again. + Hash context should be already correctly intialized by HashInit(), and should not be + finalized by HashFinal(). Behavior with invalid Hash context is undefined. + + If HashContext is NULL, then return FALSE. + If HashValue is NULL, then return FALSE. + If this interface is not supported, then return FALSE. + + @param[in, out] HashContext Pointer to the Hash context. + @param[out] HashValue Pointer to a buffer that receives the Hash digest + value. + + @retval TRUE Hash digest computation succeeded. + @retval FALSE Hash digest computation failed. + @retval FALSE This interface is not supported. + +**/ +typedef +BOOLEAN +(EFIAPI *EFI_HASH_FINAL) ( + IN OUT VOID *HashContext, + OUT UINT8 *HashValue + ); + +typedef struct { + EFI_GUID *Guid; + UINT32 HashSize; + EFI_HASH_GET_CONTEXT_SIZE GetContextSize; + EFI_HASH_INIT Init; + EFI_HASH_UPDATE Update; + EFI_HASH_FINAL Final; +} EFI_HASH_INFO; + +EFI_HASH_INFO mHashInfo[] = { + {&gEfiHashAlgorithmSha1Guid, sizeof(EFI_SHA1_HASH2), Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final }, + {&gEfiHashAlgorithmSha256Guid, sizeof(EFI_SHA256_HASH2), Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final }, + {&gEfiHashAlgorithmSha384Guid, sizeof(EFI_SHA384_HASH2), Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final }, + {&gEfiHashAlgorithmSha512Guid, sizeof(EFI_SHA512_HASH2), Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final }, +}; + +/** + Returns the size of the hash which results from a specific algorithm. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + @param[out] HashSize Holds the returned size of the algorithm's hash. + + @retval EFI_SUCCESS Hash size returned successfully. + @retval EFI_INVALID_PARAMETER This or HashSize is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is null. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2GetHashSize ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + OUT UINTN *HashSize + ); + +/** + Creates a hash for the specified message text. The hash is not extendable. + The output is final with any algorithm-required padding added by the function. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + @param[in] Message Points to the start of the message. + @param[in] MessageSize The size of Message, in bytes. + @param[in,out] Hash On input, points to a caller-allocated buffer of the size + returned by GetHashSize() for the specified HashAlgorithm. + On output, the buffer holds the resulting hash computed from the message. + + @retval EFI_SUCCESS Hash returned successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is Null. + @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available + or MessageSize is greater than platform maximum. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2Hash ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + IN CONST UINT8 *Message, + IN UINTN MessageSize, + IN OUT EFI_HASH2_OUTPUT *Hash + ); + +/** + This function must be called to initialize a digest calculation to be subsequently performed using the + EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal(). + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + + @retval EFI_SUCCESS Initialized successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is Null. + @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource. + @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(), + or HashInit() is already called before and not terminated by HashFinal() yet on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashInit ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm + ); + +/** + Updates the hash of a computation in progress by adding a message text. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] Message Points to the start of the message. + @param[in] MessageSize The size of Message, in bytes. + + @retval EFI_SUCCESS Digest in progress updated successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available + or MessageSize is greater than platform maximum. + @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(), + or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashUpdate ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST UINT8 *Message, + IN UINTN MessageSize + ); + +/** + Finalizes a hash operation in progress and returns calculation result. + The output is final with any necessary padding added by the function. + The hash may not be further updated or extended after HashFinal(). + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in,out] Hash On input, points to a caller-allocated buffer of the size + returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit(). + On output, the buffer holds the resulting hash computed from the message. + + @retval EFI_SUCCESS Hash returned successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(), + or the operation in progress was canceled by a call to Hash() on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashFinal ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN OUT EFI_HASH2_OUTPUT *Hash + ); + +EFI_HASH2_PROTOCOL mHash2Protocol = { + BaseCrypto2GetHashSize, + BaseCrypto2Hash, + BaseCrypto2HashInit, + BaseCrypto2HashUpdate, + BaseCrypto2HashFinal, +}; + +/** + Returns hash information. + + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + + @return Hash information. +**/ +EFI_HASH_INFO * +GetHashInfo ( + IN CONST EFI_GUID *HashAlgorithm + ) +{ + UINTN Index; + + for (Index = 0; Index < sizeof(mHashInfo)/sizeof(mHashInfo[0]); Index++) { + if (CompareGuid (HashAlgorithm, mHashInfo[Index].Guid)) { + return &mHashInfo[Index]; + } + } + return NULL; +} + +/** + Returns the size of the hash which results from a specific algorithm. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + @param[out] HashSize Holds the returned size of the algorithm's hash. + + @retval EFI_SUCCESS Hash size returned successfully. + @retval EFI_INVALID_PARAMETER This or HashSize is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is null. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2GetHashSize ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + OUT UINTN *HashSize + ) +{ + EFI_HASH_INFO *HashInfo; + + if ((This == NULL) || (HashSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (HashAlgorithm == NULL) { + return EFI_UNSUPPORTED; + } + + HashInfo = GetHashInfo (HashAlgorithm); + if (HashInfo == NULL) { + return EFI_UNSUPPORTED; + } + + *HashSize = HashInfo->HashSize; + return EFI_SUCCESS; +} + +/** + Creates a hash for the specified message text. The hash is not extendable. + The output is final with any algorithm-required padding added by the function. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + @param[in] Message Points to the start of the message. + @param[in] MessageSize The size of Message, in bytes. + @param[in,out] Hash On input, points to a caller-allocated buffer of the size + returned by GetHashSize() for the specified HashAlgorithm. + On output, the buffer holds the resulting hash computed from the message. + + @retval EFI_SUCCESS Hash returned successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is Null. + @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available + or MessageSize is greater than platform maximum. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2Hash ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + IN CONST UINT8 *Message, + IN UINTN MessageSize, + IN OUT EFI_HASH2_OUTPUT *Hash + ) +{ + EFI_HASH_INFO *HashInfo; + VOID *HashCtx; + UINTN CtxSize; + BOOLEAN Ret; + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if ((This == NULL) || (Hash == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (HashAlgorithm == NULL) { + return EFI_UNSUPPORTED; + } + + HashInfo = GetHashInfo (HashAlgorithm); + if (HashInfo == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Start hash sequence + // + CtxSize = HashInfo->GetContextSize (); + if (CtxSize == 0) { + return EFI_UNSUPPORTED; + } + HashCtx = AllocatePool (CtxSize); + if (HashCtx == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ret = HashInfo->Init (HashCtx); + if (!Ret) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Ret = HashInfo->Update (HashCtx, Message, MessageSize); + if (!Ret) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash); + if (!Ret) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } +Done: + FreePool (HashCtx); + return Status; +} + +/** + This function must be called to initialize a digest calculation to be subsequently performed using the + EFI_HASH2_PROTOCOL functions HashUpdate() and HashFinal(). + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use. + + @retval EFI_SUCCESS Initialized successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this driver + or HashAlgorithm is Null. + @retval EFI_OUT_OF_RESOURCES Process failed due to lack of required resource. + @retval EFI_ALREADY_STARTED This function is called when the operation in progress is still in processing Hash(), + or HashInit() is already called before and not terminated by HashFinal() yet on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashInit ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm + ) +{ + EFI_HASH_INFO *HashInfo; + VOID *HashCtx; + UINTN CtxSize; + BOOLEAN Ret; + HASH2_INSTANCE_DATA *Instance; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (HashAlgorithm == NULL) { + return EFI_UNSUPPORTED; + } + + HashInfo = GetHashInfo (HashAlgorithm); + if (HashInfo == NULL) { + return EFI_UNSUPPORTED; + } + + // + // Consistency Check + // + Instance = HASH2_INSTANCE_DATA_FROM_THIS(This); + if ((Instance->HashContext != NULL) || (Instance->HashInfoContext != HashInfo)) { + return EFI_ALREADY_STARTED; + } + + // + // Start hash sequence + // + CtxSize = HashInfo->GetContextSize (); + if (CtxSize == 0) { + return EFI_UNSUPPORTED; + } + HashCtx = AllocatePool (CtxSize); + if (HashCtx == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Ret = HashInfo->Init (HashCtx); + if (!Ret) { + FreePool (HashCtx); + return EFI_OUT_OF_RESOURCES; + } + + // + // Setup the context + // + Instance->HashContext = HashCtx; + Instance->HashInfoContext = HashInfo; + + return EFI_SUCCESS; +} + +/** + Updates the hash of a computation in progress by adding a message text. + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in] Message Points to the start of the message. + @param[in] MessageSize The size of Message, in bytes. + + @retval EFI_SUCCESS Digest in progress updated successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_OUT_OF_RESOURCES Some resource required by the function is not available + or MessageSize is greater than platform maximum. + @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit(), + or the operation in progress was terminated by a call to Hash() or HashFinal() on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashUpdate ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN CONST UINT8 *Message, + IN UINTN MessageSize + ) +{ + EFI_HASH_INFO *HashInfo; + VOID *HashCtx; + BOOLEAN Ret; + HASH2_INSTANCE_DATA *Instance; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Consistency Check + // + Instance = HASH2_INSTANCE_DATA_FROM_THIS(This); + if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) { + return EFI_NOT_READY; + } + HashInfo = Instance->HashInfoContext; + HashCtx = Instance->HashContext; + + Ret = HashInfo->Update (HashCtx, Message, MessageSize); + if (!Ret) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Finalizes a hash operation in progress and returns calculation result. + The output is final with any necessary padding added by the function. + The hash may not be further updated or extended after HashFinal(). + + @param[in] This Points to this instance of EFI_HASH2_PROTOCOL. + @param[in,out] Hash On input, points to a caller-allocated buffer of the size + returned by GetHashSize() for the specified HashAlgorithm specified in preceding HashInit(). + On output, the buffer holds the resulting hash computed from the message. + + @retval EFI_SUCCESS Hash returned successfully. + @retval EFI_INVALID_PARAMETER This or Hash is NULL. + @retval EFI_NOT_READY This call was not preceded by a valid call to HashInit() and at least one call to HashUpdate(), + or the operation in progress was canceled by a call to Hash() on the same instance. + +**/ +EFI_STATUS +EFIAPI +BaseCrypto2HashFinal ( + IN CONST EFI_HASH2_PROTOCOL *This, + IN OUT EFI_HASH2_OUTPUT *Hash + ) +{ + EFI_HASH_INFO *HashInfo; + VOID *HashCtx; + BOOLEAN Ret; + HASH2_INSTANCE_DATA *Instance; + + if ((This == NULL) || (Hash == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Consistency Check + // + Instance = HASH2_INSTANCE_DATA_FROM_THIS(This); + if ((Instance->HashContext == NULL) || (Instance->HashInfoContext == NULL)) { + return EFI_NOT_READY; + } + HashInfo = Instance->HashInfoContext; + HashCtx = Instance->HashContext; + + Ret = HashInfo->Final (HashCtx, (UINT8 *)Hash->Sha1Hash); + + // + // Cleanup the context + // + FreePool (HashCtx); + Instance->HashInfoContext = NULL; + Instance->HashContext = NULL; + + if (!Ret) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf new file mode 100644 index 0000000000..c4e6271e89 --- /dev/null +++ b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf @@ -0,0 +1,62 @@ +## @file +# Produces the UEFI HASH2 protocol +# +# This module will use EDKII crypto libary to HASH2 protocol. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Hash2DxeCrypto + FILE_GUID = 63E3BDCF-2AC7-4ac0-9B92-03A7541422FF + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Hash2DriverEntryPoint + MODULE_UNI_FILE = Hash2DxeCrypto.uni + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[Sources.common] + Hash2DxeCrypto.c + Driver.h + Driver.c + +[Packages] + MdePkg/MdePkg.dec + CryptoPkg/CryptoPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + BaseLib + BaseMemoryLib + BaseCryptLib + MemoryAllocationLib + UefiDriverEntryPoint + DebugLib + UefiLib + +[Guids] + gEfiHashAlgorithmSha1Guid + gEfiHashAlgorithmSha256Guid + gEfiHashAlgorithmSha384Guid + gEfiHashAlgorithmSha512Guid + +[Protocols] + gEfiHash2ProtocolGuid + gEfiHash2ServiceBindingProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + Hash2DxeCryptoExtra.uni \ No newline at end of file diff --git a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.uni b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.uni new file mode 100644 index 0000000000..087cee683c Binary files /dev/null and b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.uni differ diff --git a/SecurityPkg/Hash2DxeCrypto/Hash2DxeCryptoExtra.uni b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCryptoExtra.uni new file mode 100644 index 0000000000..123b0b460a Binary files /dev/null and b/SecurityPkg/Hash2DxeCrypto/Hash2DxeCryptoExtra.uni differ diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 68a7326e03..8bd4e7ae56 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -170,6 +170,14 @@ SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf + # + # Hash2 + # + SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf + + # + # Other + # SecurityPkg/Library/DxeRsa2048Sha256GuidedSectionExtractLib/DxeRsa2048Sha256GuidedSectionExtractLib.inf SecurityPkg/Library/PeiRsa2048Sha256GuidedSectionExtractLib/PeiRsa2048Sha256GuidedSectionExtractLib.inf