From 6c023864035191a1efe8e349fc57812803eabec8 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Tue, 18 Aug 2020 14:26:13 +0800 Subject: IntelFsp2WrapperPkg/FspMeasurementLib: Add BaseFspMeasurementLib. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2376 Cc: Jiewen Yao Cc: Chasel Chiu Cc: Nate DeSimone Cc: Star Zeng Cc: Qi Zhang Signed-off-by: Jiewen Yao Message-Id: <20200818062618.3698-4-qi1.zhang@intel.com> Reviewed-by: Jian J Wang Reviewed-by: Chasel Chiu --- .../BaseFspMeasurementLib.inf | 54 +++++ .../BaseFspMeasurementLib/FspMeasurementLib.c | 248 +++++++++++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf create mode 100644 IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c (limited to 'IntelFsp2WrapperPkg') diff --git a/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf new file mode 100644 index 0000000000..1b5f0012aa --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf @@ -0,0 +1,54 @@ +## @file +# Provides FSP measurement functions. +# +# This library provides MeasureFspFirmwareBlob() to measure FSP binary. +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspMeasurementLib + FILE_GUID = 890B12B4-56CC-453E-B062-4597FC6D3D8C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspMeasurementLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspMeasurementLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + PrintLib + PcdLib + PeiServicesLib + PeiServicesTablePointerLib + FspWrapperApiLib + TcgEventLogRecordLib + HashLib + +[Ppis] + gEdkiiTcgPpiGuid ## CONSUMES + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES + diff --git a/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c new file mode 100644 index 0000000000..0fe0606a6d --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c @@ -0,0 +1,248 @@ +/** @file + This library is used by FSP modules to measure data to TPM. + +Copyright (c) 2020, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + 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); +} + -- cgit v1.2.3