summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c72
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h38
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c300
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf51
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.uni18
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c433
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf57
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.uni18
8 files changed, 987 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c
new file mode 100644
index 00000000..2e550e64
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.c
@@ -0,0 +1,72 @@
+/** @file
+ This is BaseCrypto router support function.
+
+Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HashLib.h>
+#include <Protocol/Tcg2Protocol.h>
+
+typedef struct {
+ EFI_GUID Guid;
+ UINT32 Mask;
+} TPM2_HASH_MASK;
+
+TPM2_HASH_MASK mTpm2HashMask[] = {
+ {HASH_ALGORITHM_SHA1_GUID, HASH_ALG_SHA1},
+ {HASH_ALGORITHM_SHA256_GUID, HASH_ALG_SHA256},
+ {HASH_ALGORITHM_SHA384_GUID, HASH_ALG_SHA384},
+ {HASH_ALGORITHM_SHA512_GUID, HASH_ALG_SHA512},
+ {HASH_ALGORITHM_SM3_256_GUID, HASH_ALG_SM3_256},
+};
+
+/**
+ The function get hash mask info from algorithm.
+
+ @param HashGuid Hash Guid
+
+ @return HashMask
+**/
+UINT32
+EFIAPI
+Tpm2GetHashMaskFromAlgo (
+ IN EFI_GUID *HashGuid
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < sizeof(mTpm2HashMask)/sizeof(mTpm2HashMask[0]); Index++) {
+ if (CompareGuid (HashGuid, &mTpm2HashMask[Index].Guid)) {
+ return mTpm2HashMask[Index].Mask;
+ }
+ }
+ return 0;
+}
+
+/**
+ The function set digest to digest list.
+
+ @param DigestList digest list
+ @param Digest digest data
+**/
+VOID
+EFIAPI
+Tpm2SetHashToDigestList (
+ IN OUT TPML_DIGEST_VALUES *DigestList,
+ IN TPML_DIGEST_VALUES *Digest
+ )
+{
+ CopyMem (
+ &DigestList->digests[DigestList->count],
+ &Digest->digests[0],
+ sizeof(Digest->digests[0])
+ );
+ DigestList->count ++;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h
new file mode 100644
index 00000000..6af53aa2
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterCommon.h
@@ -0,0 +1,38 @@
+/** @file
+ This is BaseCrypto router support function definition.
+
+Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_
+#define _HASH_LIB_BASE_CRYPTO_ROUTER_COMMON_H_
+
+/**
+ The function get hash mask info from algorithm.
+
+ @param HashGuid Hash Guid
+
+ @return HashMask
+**/
+UINT32
+EFIAPI
+Tpm2GetHashMaskFromAlgo (
+ IN EFI_GUID *HashGuid
+ );
+
+/**
+ The function set digest to digest list.
+
+ @param DigestList digest list
+ @param Digest digest data
+**/
+VOID
+EFIAPI
+Tpm2SetHashToDigestList (
+ IN OUT TPML_DIGEST_VALUES *DigestList,
+ IN TPML_DIGEST_VALUES *Digest
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
new file mode 100644
index 00000000..f44edffa
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
@@ -0,0 +1,300 @@
+/** @file
+ This library is BaseCrypto router. It will redirect hash request to each individual
+ hash handler registered, such as SHA1, SHA256.
+ Platform can use PcdTpm2HashMask to mask some hash engines.
+
+Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HashLib.h>
+
+#include "HashLibBaseCryptoRouterCommon.h"
+
+HASH_INTERFACE mHashInterface[HASH_COUNT] = {{{0}, NULL, NULL, NULL}};
+UINTN mHashInterfaceCount = 0;
+
+UINT32 mSupportedHashMaskLast = 0;
+UINT32 mSupportedHashMaskCurrent = 0;
+
+/**
+ Check mismatch of supported HashMask between modules
+ that may link different HashInstanceLib instances.
+
+**/
+VOID
+CheckSupportedHashMaskMismatch (
+ VOID
+ )
+{
+ if (mSupportedHashMaskCurrent != mSupportedHashMaskLast) {
+ DEBUG ((
+ DEBUG_WARN,
+ "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
+ mSupportedHashMaskCurrent,
+ mSupportedHashMaskLast
+ ));
+ DEBUG ((DEBUG_WARN, "that are linking different HashInstanceLib instances!\n"));
+ }
+}
+
+/**
+ Start hash sequence.
+
+ @param HashHandle Hash handle.
+
+ @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
+**/
+EFI_STATUS
+EFIAPI
+HashStart (
+ OUT HASH_HANDLE *HashHandle
+ )
+{
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ UINT32 HashMask;
+
+ if (mHashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch ();
+
+ HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
+ ASSERT (HashCtx != NULL);
+
+ for (Index = 0; Index < mHashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ mHashInterface[Index].HashInit (&HashCtx[Index]);
+ }
+ }
+
+ *HashHandle = (HASH_HANDLE)HashCtx;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Update hash sequence data.
+
+ @param HashHandle Hash handle.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+
+ @retval EFI_SUCCESS Hash sequence updated.
+**/
+EFI_STATUS
+EFIAPI
+HashUpdate (
+ IN HASH_HANDLE HashHandle,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen
+ )
+{
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ UINT32 HashMask;
+
+ if (mHashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch ();
+
+ HashCtx = (HASH_HANDLE *)HashHandle;
+
+ for (Index = 0; Index < mHashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Hash sequence complete and extend to PCR.
+
+ @param HashHandle Hash handle.
+ @param PcrIndex PCR to be extended.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+ @param DigestList Digest list.
+
+ @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
+**/
+EFI_STATUS
+EFIAPI
+HashCompleteAndExtend (
+ IN HASH_HANDLE HashHandle,
+ IN TPMI_DH_PCR PcrIndex,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen,
+ OUT TPML_DIGEST_VALUES *DigestList
+ )
+{
+ TPML_DIGEST_VALUES Digest;
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ EFI_STATUS Status;
+ UINT32 HashMask;
+
+ if (mHashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch ();
+
+ HashCtx = (HASH_HANDLE *)HashHandle;
+ ZeroMem (DigestList, sizeof(*DigestList));
+
+ for (Index = 0; Index < mHashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
+ mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
+ Tpm2SetHashToDigestList (DigestList, &Digest);
+ }
+ }
+
+ FreePool (HashCtx);
+
+ Status = Tpm2PcrExtend (
+ PcrIndex,
+ DigestList
+ );
+ return Status;
+}
+
+/**
+ Hash data and extend to PCR.
+
+ @param PcrIndex PCR to be extended.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+ @param DigestList Digest list.
+
+ @retval EFI_SUCCESS Hash data and DigestList is returned.
+**/
+EFI_STATUS
+EFIAPI
+HashAndExtend (
+ IN TPMI_DH_PCR PcrIndex,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen,
+ OUT TPML_DIGEST_VALUES *DigestList
+ )
+{
+ HASH_HANDLE HashHandle;
+ EFI_STATUS Status;
+
+ if (mHashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch ();
+
+ HashStart (&HashHandle);
+ HashUpdate (HashHandle, DataToHash, DataToHashLen);
+ Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
+
+ return Status;
+}
+
+/**
+ This service register Hash.
+
+ @param HashInterface Hash interface
+
+ @retval EFI_SUCCESS This hash interface is registered successfully.
+ @retval EFI_UNSUPPORTED System does not support register this interface.
+ @retval EFI_ALREADY_STARTED System already register this interface.
+**/
+EFI_STATUS
+EFIAPI
+RegisterHashInterfaceLib (
+ IN HASH_INTERFACE *HashInterface
+ )
+{
+ UINTN Index;
+ UINT32 HashMask;
+ EFI_STATUS Status;
+
+ //
+ // Check allow
+ //
+ HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Check duplication
+ //
+ for (Index = 0; Index < mHashInterfaceCount; Index++) {
+ if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
+ DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid));
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ //
+ // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
+ //
+ mSupportedHashMaskCurrent = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask;
+ Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, mSupportedHashMaskCurrent);
+ ASSERT_EFI_ERROR (Status);
+
+ CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
+ mHashInterfaceCount ++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The constructor function of HashLibBaseCryptoRouterDxe.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor executed correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+HashLibBaseCryptoRouterDxeConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Record hash algorithm bitmap of LAST module which also consumes HashLib.
+ //
+ mSupportedHashMaskLast = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
+
+ //
+ // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
+ //
+ Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
new file mode 100644
index 00000000..548576f9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# Provides hash service by registered hash handler
+#
+# This library is BaseCrypto router. It will redirect hash request to each individual
+# hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to
+# mask some hash engines.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HashLibBaseCryptoRouterDxe
+ MODULE_UNI_FILE = HashLibBaseCryptoRouterDxe.uni
+ FILE_GUID = 158DC712-F15A-44dc-93BB-1675045BE066
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HashLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = HashLibBaseCryptoRouterDxeConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ HashLibBaseCryptoRouterCommon.h
+ HashLibBaseCryptoRouterCommon.c
+ HashLibBaseCryptoRouterDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ Tpm2CommandLib
+ MemoryAllocationLib
+ PcdLib
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask ## CONSUMES
+ ## SOMETIMES_CONSUMES
+ ## SOMETIMES_PRODUCES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap
+
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.uni b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.uni
new file mode 100644
index 00000000..d8b03ea4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Provides hash service by registered hash handler
+//
+// This library is BaseCrypto router. It will redirect hash request to each individual
+// hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to
+// mask some hash engines.
+//
+// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides hash service by registered hash handler"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This library is BaseCrypto router. It will redirect hash request to each individual hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to mask some hash engines."
+
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
new file mode 100644
index 00000000..5e3d0ba5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.c
@@ -0,0 +1,433 @@
+/** @file
+ This library is BaseCrypto router. It will redirect hash request to each individual
+ hash handler registered, such as SHA1, SHA256.
+ Platform can use PcdTpm2HashMask to mask some hash engines.
+
+Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/HashLib.h>
+#include <Guid/ZeroGuid.h>
+
+#include "HashLibBaseCryptoRouterCommon.h"
+
+#define HASH_LIB_PEI_ROUTER_GUID \
+ { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
+
+EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;
+
+typedef struct {
+ //
+ // If gZeroGuid, SupportedHashMask is 0 for FIRST module which consumes HashLib
+ // or the hash algorithm bitmap of LAST module which consumes HashLib.
+ // HashInterfaceCount and HashInterface are all 0.
+ // If gEfiCallerIdGuid, HashInterfaceCount, HashInterface and SupportedHashMask
+ // are the hash interface information of CURRENT module which consumes HashLib.
+ //
+ EFI_GUID Identifier;
+ UINTN HashInterfaceCount;
+ HASH_INTERFACE HashInterface[HASH_COUNT];
+ UINT32 SupportedHashMask;
+} HASH_INTERFACE_HOB;
+
+/**
+ This function gets hash interface hob.
+
+ @param Identifier Identifier to get hash interface hob.
+
+ @retval hash interface hob.
+**/
+HASH_INTERFACE_HOB *
+InternalGetHashInterfaceHob (
+ EFI_GUID *Identifier
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+
+ Hob.Raw = GetFirstGuidHob (&mHashLibPeiRouterGuid);
+ while (Hob.Raw != NULL) {
+ HashInterfaceHob = GET_GUID_HOB_DATA (Hob);
+ if (CompareGuid (&HashInterfaceHob->Identifier, Identifier)) {
+ //
+ // Found the matched one.
+ //
+ return HashInterfaceHob;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&mHashLibPeiRouterGuid, Hob.Raw);
+ }
+ return NULL;
+}
+
+/**
+ This function creates hash interface hob.
+
+ @param Identifier Identifier to create hash interface hob.
+
+ @retval hash interface hob.
+**/
+HASH_INTERFACE_HOB *
+InternalCreateHashInterfaceHob (
+ EFI_GUID *Identifier
+ )
+{
+ HASH_INTERFACE_HOB LocalHashInterfaceHob;
+
+ ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
+ CopyGuid (&LocalHashInterfaceHob.Identifier, Identifier);
+ return BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
+}
+
+/**
+ Check mismatch of supported HashMask between modules
+ that may link different HashInstanceLib instances.
+
+ @param HashInterfaceHobCurrent Pointer to hash interface hob for CURRENT module.
+
+**/
+VOID
+CheckSupportedHashMaskMismatch (
+ IN HASH_INTERFACE_HOB *HashInterfaceHobCurrent
+ )
+{
+ HASH_INTERFACE_HOB *HashInterfaceHobLast;
+
+ HashInterfaceHobLast = InternalGetHashInterfaceHob (&gZeroGuid);
+ ASSERT (HashInterfaceHobLast != NULL);
+
+ if ((HashInterfaceHobLast->SupportedHashMask != 0) &&
+ (HashInterfaceHobCurrent->SupportedHashMask != HashInterfaceHobLast->SupportedHashMask)) {
+ DEBUG ((
+ DEBUG_WARN,
+ "WARNING: There is mismatch of supported HashMask (0x%x - 0x%x) between modules\n",
+ HashInterfaceHobCurrent->SupportedHashMask,
+ HashInterfaceHobLast->SupportedHashMask
+ ));
+ DEBUG ((DEBUG_WARN, "that are linking different HashInstanceLib instances!\n"));
+ }
+}
+
+/**
+ Start hash sequence.
+
+ @param HashHandle Hash handle.
+
+ @retval EFI_SUCCESS Hash sequence start and HandleHandle returned.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
+**/
+EFI_STATUS
+EFIAPI
+HashStart (
+ OUT HASH_HANDLE *HashHandle
+ )
+{
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ UINT32 HashMask;
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HashInterfaceHob->HashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch (HashInterfaceHob);
+
+ HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);
+ ASSERT (HashCtx != NULL);
+
+ for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);
+ }
+ }
+
+ *HashHandle = (HASH_HANDLE)HashCtx;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Update hash sequence data.
+
+ @param HashHandle Hash handle.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+
+ @retval EFI_SUCCESS Hash sequence updated.
+**/
+EFI_STATUS
+EFIAPI
+HashUpdate (
+ IN HASH_HANDLE HashHandle,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen
+ )
+{
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ UINT32 HashMask;
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HashInterfaceHob->HashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch (HashInterfaceHob);
+
+ HashCtx = (HASH_HANDLE *)HashHandle;
+
+ for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Hash sequence complete and extend to PCR.
+
+ @param HashHandle Hash handle.
+ @param PcrIndex PCR to be extended.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+ @param DigestList Digest list.
+
+ @retval EFI_SUCCESS Hash sequence complete and DigestList is returned.
+**/
+EFI_STATUS
+EFIAPI
+HashCompleteAndExtend (
+ IN HASH_HANDLE HashHandle,
+ IN TPMI_DH_PCR PcrIndex,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen,
+ OUT TPML_DIGEST_VALUES *DigestList
+ )
+{
+ TPML_DIGEST_VALUES Digest;
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+ HASH_HANDLE *HashCtx;
+ UINTN Index;
+ EFI_STATUS Status;
+ UINT32 HashMask;
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HashInterfaceHob->HashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch (HashInterfaceHob);
+
+ HashCtx = (HASH_HANDLE *)HashHandle;
+ ZeroMem (DigestList, sizeof(*DigestList));
+
+ for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
+ HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
+ HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
+ HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);
+ Tpm2SetHashToDigestList (DigestList, &Digest);
+ }
+ }
+
+ FreePool (HashCtx);
+
+ Status = Tpm2PcrExtend (
+ PcrIndex,
+ DigestList
+ );
+ return Status;
+}
+
+/**
+ Hash data and extend to PCR.
+
+ @param PcrIndex PCR to be extended.
+ @param DataToHash Data to be hashed.
+ @param DataToHashLen Data size.
+ @param DigestList Digest list.
+
+ @retval EFI_SUCCESS Hash data and DigestList is returned.
+**/
+EFI_STATUS
+EFIAPI
+HashAndExtend (
+ IN TPMI_DH_PCR PcrIndex,
+ IN VOID *DataToHash,
+ IN UINTN DataToHashLen,
+ OUT TPML_DIGEST_VALUES *DigestList
+ )
+{
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+ HASH_HANDLE HashHandle;
+ EFI_STATUS Status;
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HashInterfaceHob->HashInterfaceCount == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CheckSupportedHashMaskMismatch (HashInterfaceHob);
+
+ HashStart (&HashHandle);
+ HashUpdate (HashHandle, DataToHash, DataToHashLen);
+ Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
+
+ return Status;
+}
+
+/**
+ This service register Hash.
+
+ @param HashInterface Hash interface
+
+ @retval EFI_SUCCESS This hash interface is registered successfully.
+ @retval EFI_UNSUPPORTED System does not support register this interface.
+ @retval EFI_ALREADY_STARTED System already register this interface.
+**/
+EFI_STATUS
+EFIAPI
+RegisterHashInterfaceLib (
+ IN HASH_INTERFACE *HashInterface
+ )
+{
+ UINTN Index;
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+ UINT32 HashMask;
+ EFI_STATUS Status;
+
+ //
+ // Check allow
+ //
+ HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
+ if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Check duplication
+ //
+ for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
+ if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
+ DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid));
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ //
+ // Record hash algorithm bitmap of CURRENT module which consumes HashLib.
+ //
+ HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask;
+ Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, HashInterfaceHob->SupportedHashMask);
+ ASSERT_EFI_ERROR (Status);
+
+ CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
+ HashInterfaceHob->HashInterfaceCount ++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The constructor function of HashLibBaseCryptoRouterPei.
+
+ @param FileHandle The handle of FFS header the loaded driver.
+ @param PeiServices The pointer to the PEI services.
+
+ @retval EFI_SUCCESS The constructor executes successfully.
+ @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor.
+
+**/
+EFI_STATUS
+EFIAPI
+HashLibBaseCryptoRouterPeiConstructor (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ HASH_INTERFACE_HOB *HashInterfaceHob;
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gZeroGuid);
+ if (HashInterfaceHob == NULL) {
+ //
+ // No HOB with gZeroGuid Identifier has been created,
+ // this is FIRST module which consumes HashLib.
+ // Create the HOB with gZeroGuid Identifier.
+ //
+ HashInterfaceHob = InternalCreateHashInterfaceHob (&gZeroGuid);
+ if (HashInterfaceHob == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // Record hash algorithm bitmap of LAST module which also consumes HashLib.
+ //
+ HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
+ }
+
+ HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid);
+ if (HashInterfaceHob != NULL) {
+ //
+ // In PEI phase, some modules may call RegisterForShadow and will be
+ // shadowed and executed again after memory is discovered.
+ // This is the second execution of this module, clear the hash interface
+ // information registered at its first execution.
+ //
+ ZeroMem (&HashInterfaceHob->HashInterface, sizeof (HashInterfaceHob->HashInterface));
+ HashInterfaceHob->HashInterfaceCount = 0;
+ HashInterfaceHob->SupportedHashMask = 0;
+ }
+
+ //
+ // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module.
+ //
+ Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
new file mode 100644
index 00000000..57502427
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf
@@ -0,0 +1,57 @@
+## @file
+# Provides hash service by registered hash handler
+#
+# This library is BaseCrypto router. It will redirect hash request to each individual
+# hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to
+# mask some hash engines.
+#
+# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HashLibBaseCryptoRouterPei
+ MODULE_UNI_FILE = HashLibBaseCryptoRouterPei.uni
+ FILE_GUID = DDCBCFBA-8EEB-488a-96D6-097831A6E50B
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HashLib|PEIM
+ CONSTRUCTOR = HashLibBaseCryptoRouterPeiConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ HashLibBaseCryptoRouterCommon.h
+ HashLibBaseCryptoRouterCommon.c
+ HashLibBaseCryptoRouterPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ Tpm2CommandLib
+ MemoryAllocationLib
+ PcdLib
+ HobLib
+
+[Guids]
+ ## SOMETIMES_CONSUMES ## GUID
+ gZeroGuid
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask ## CONSUMES
+ ## SOMETIMES_CONSUMES
+ ## SOMETIMES_PRODUCES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap
+
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.uni b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.uni
new file mode 100644
index 00000000..d8b03ea4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Provides hash service by registered hash handler
+//
+// This library is BaseCrypto router. It will redirect hash request to each individual
+// hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to
+// mask some hash engines.
+//
+// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides hash service by registered hash handler"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This library is BaseCrypto router. It will redirect hash request to each individual hash handler registered, such as SHA1, SHA256. Platform can use PcdTpm2HashMask to mask some hash engines."
+