mirror of https://github.com/acidanthera/audk.git
310 lines
7.8 KiB
C
310 lines
7.8 KiB
C
/** @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 - 2021, 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;
|
|
UINT32 Tpm2HashMask;
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Check allow
|
|
//
|
|
HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
|
|
Tpm2HashMask = PcdGet32 (PcdTpm2HashMask);
|
|
|
|
if ((Tpm2HashMask != 0) &&
|
|
((HashMask & Tpm2HashMask) == 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;
|
|
}
|