mirror of https://github.com/acidanthera/audk.git
249 lines
8.6 KiB
C
249 lines
8.6 KiB
C
/** @file
|
|
This library is used by FSP modules to measure data to TPM.
|
|
|
|
Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <PiPei.h>
|
|
#include <Uefi.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/PeiServicesLib.h>
|
|
#include <Library/PeiServicesTablePointerLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/FspWrapperApiLib.h>
|
|
#include <Library/TpmMeasurementLib.h>
|
|
#include <Library/FspMeasurementLib.h>
|
|
#include <Library/TcgEventLogRecordLib.h>
|
|
#include <Library/HashLib.h>
|
|
|
|
#include <Ppi/Tcg.h>
|
|
#include <IndustryStandard/UefiTcgPlatform.h>
|
|
|
|
/**
|
|
Tpm measure and log data, and extend the measurement result into a specific PCR.
|
|
|
|
@param[in] PcrIndex PCR Index.
|
|
@param[in] EventType Event type.
|
|
@param[in] EventLog Measurement event log.
|
|
@param[in] LogLen Event log length in bytes.
|
|
@param[in] HashData The start of the data buffer to be hashed, extended.
|
|
@param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
|
|
@param[in] Flags Bitmap providing additional information.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval EFI_UNSUPPORTED TPM device not available.
|
|
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
|
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
TpmMeasureAndLogDataWithFlags (
|
|
IN UINT32 PcrIndex,
|
|
IN UINT32 EventType,
|
|
IN VOID *EventLog,
|
|
IN UINT32 LogLen,
|
|
IN VOID *HashData,
|
|
IN UINT64 HashDataLen,
|
|
IN UINT64 Flags
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EDKII_TCG_PPI *TcgPpi;
|
|
TCG_PCR_EVENT_HDR TcgEventHdr;
|
|
|
|
Status = PeiServicesLocatePpi(
|
|
&gEdkiiTcgPpiGuid,
|
|
0,
|
|
NULL,
|
|
(VOID**)&TcgPpi
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TcgEventHdr.PCRIndex = PcrIndex;
|
|
TcgEventHdr.EventType = EventType;
|
|
TcgEventHdr.EventSize = LogLen;
|
|
|
|
Status = TcgPpi->HashLogExtendEvent (
|
|
TcgPpi,
|
|
Flags,
|
|
HashData,
|
|
(UINTN)HashDataLen,
|
|
&TcgEventHdr,
|
|
EventLog
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Measure a FSP FirmwareBlob.
|
|
|
|
@param[in] Description Description for this FirmwareBlob.
|
|
@param[in] FirmwareBlobBase Base address of this FirmwareBlob.
|
|
@param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.
|
|
@param[in] CfgRegionOffset Configuration region offset in bytes.
|
|
@param[in] CfgRegionSize Configuration region in bytes.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval EFI_UNSUPPORTED TPM device not available.
|
|
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
|
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MeasureFspFirmwareBlobWithCfg (
|
|
IN CHAR8 *Description OPTIONAL,
|
|
IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,
|
|
IN UINT64 FirmwareBlobLength,
|
|
IN UINT32 CfgRegionOffset,
|
|
IN UINT32 CfgRegionSize
|
|
)
|
|
{
|
|
EFI_PLATFORM_FIRMWARE_BLOB FvBlob, UpdBlob;
|
|
PLATFORM_FIRMWARE_BLOB2_STRUCT FvBlob2, UpdBlob2;
|
|
VOID *FvName;
|
|
UINT32 FvEventType;
|
|
VOID *FvEventLog, *UpdEventLog;
|
|
UINT32 FvEventLogSize, UpdEventLogSize;
|
|
EFI_STATUS Status;
|
|
HASH_HANDLE HashHandle;
|
|
UINT8 *HashBase;
|
|
UINTN HashSize;
|
|
TPML_DIGEST_VALUES DigestList;
|
|
|
|
FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength);
|
|
|
|
if (((Description != NULL) || (FvName != NULL)) &&
|
|
(PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {
|
|
if (Description != NULL) {
|
|
AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description);
|
|
AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "%aUDP", Description);
|
|
} else {
|
|
AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);
|
|
AsciiSPrint((CHAR8*)UpdBlob2.BlobDescription, sizeof(UpdBlob2.BlobDescription), "(%g)UDP", FvName);
|
|
}
|
|
|
|
FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);
|
|
FvBlob2.BlobBase = FirmwareBlobBase;
|
|
FvBlob2.BlobLength = FirmwareBlobLength;
|
|
FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
|
|
FvEventLog = &FvBlob2;
|
|
FvEventLogSize = sizeof(FvBlob2);
|
|
|
|
UpdBlob2.BlobDescriptionSize = sizeof(UpdBlob2.BlobDescription);
|
|
UpdBlob2.BlobBase = CfgRegionOffset;
|
|
UpdBlob2.BlobLength = CfgRegionSize;
|
|
UpdEventLog = &UpdBlob2;
|
|
UpdEventLogSize = sizeof(UpdBlob2);
|
|
} else {
|
|
FvBlob.BlobBase = FirmwareBlobBase;
|
|
FvBlob.BlobLength = FirmwareBlobLength;
|
|
FvEventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
|
|
FvEventLog = &FvBlob;
|
|
FvEventLogSize = sizeof(FvBlob);
|
|
|
|
UpdBlob.BlobBase = CfgRegionOffset;
|
|
UpdBlob.BlobLength = CfgRegionSize;
|
|
UpdEventLog = &UpdBlob;
|
|
UpdEventLogSize = sizeof(UpdBlob);
|
|
}
|
|
|
|
/** Initialize a SHA hash context. **/
|
|
Status = HashStart (&HashHandle);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
/** Hash FSP binary before UDP **/
|
|
HashBase = (UINT8 *) (UINTN) FirmwareBlobBase;
|
|
HashSize = (UINTN) CfgRegionOffset;
|
|
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
/** Hash FSP binary after UDP **/
|
|
HashBase = (UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset + CfgRegionSize;
|
|
HashSize = (UINTN)(FirmwareBlobLength - CfgRegionOffset - CfgRegionSize);
|
|
Status = HashUpdate (HashHandle, HashBase, HashSize);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
/** Finalize the SHA hash. **/
|
|
Status = HashCompleteAndExtend (HashHandle, 0, NULL, 0, &DigestList);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "HashCompleteAndExtend failed - %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
Status = TpmMeasureAndLogDataWithFlags (
|
|
0,
|
|
FvEventType,
|
|
FvEventLog,
|
|
FvEventLogSize,
|
|
(UINT8 *) &DigestList,
|
|
(UINTN) sizeof(DigestList),
|
|
EDKII_TCG_PRE_HASH_LOG_ONLY
|
|
);
|
|
|
|
Status = TpmMeasureAndLogData (
|
|
1,
|
|
EV_PLATFORM_CONFIG_FLAGS,
|
|
UpdEventLog,
|
|
UpdEventLogSize,
|
|
(UINT8 *) (UINTN) FirmwareBlobBase + CfgRegionOffset,
|
|
CfgRegionSize
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Measure a FSP FirmwareBlob.
|
|
|
|
@param[in] PcrIndex PCR Index.
|
|
@param[in] Description Description for this FirmwareBlob.
|
|
@param[in] FirmwareBlobBase Base address of this FirmwareBlob.
|
|
@param[in] FirmwareBlobLength Size in bytes of this FirmwareBlob.
|
|
|
|
@retval EFI_SUCCESS Operation completed successfully.
|
|
@retval EFI_UNSUPPORTED TPM device not available.
|
|
@retval EFI_OUT_OF_RESOURCES Out of memory.
|
|
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MeasureFspFirmwareBlob (
|
|
IN UINT32 PcrIndex,
|
|
IN CHAR8 *Description OPTIONAL,
|
|
IN EFI_PHYSICAL_ADDRESS FirmwareBlobBase,
|
|
IN UINT64 FirmwareBlobLength
|
|
)
|
|
{
|
|
UINT32 FspMeasureMask;
|
|
FSP_INFO_HEADER *FspHeaderPtr;
|
|
|
|
FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
|
|
if ((FspMeasureMask & FSP_MEASURE_FSPUPD) != 0) {
|
|
FspHeaderPtr = (FSP_INFO_HEADER *) FspFindFspHeader (FirmwareBlobBase);
|
|
if (FspHeaderPtr != NULL) {
|
|
return MeasureFspFirmwareBlobWithCfg(Description, FirmwareBlobBase, FirmwareBlobLength,
|
|
FspHeaderPtr->CfgRegionOffset, FspHeaderPtr->CfgRegionSize);
|
|
}
|
|
}
|
|
|
|
return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase, FirmwareBlobLength);
|
|
}
|
|
|