From 1e231f77da4eaff755cb6e956db4e1b13c8f67c8 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Wed, 1 Jul 2026 20:21:28 +0000 Subject: [PATCH 01/11] Revert "ArmPkg/PeilessSec: Consume Tpm2StartupLib (#1692)" This reverts commit 4de8ea12ab555394a74df0cb1857d406304661f1. --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - ArmPlatformPkg/PeilessSec/PeilessSec.c | 17 ----------------- ArmPlatformPkg/PeilessSec/PeilessSec.inf | 1 - 3 files changed, 19 deletions(-) diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 3bcffdeeae5..80b476af691 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -99,7 +99,6 @@ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2DeviceSecLibFfa.inf HashLib|SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf PeilessSecMeasureLib|SecurityPkg/Library/PeilessSecMeasureLib/PeilessSecMeasureLib.inf - Tpm2StartupLib|SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf # MU_CHANGE [LibraryClasses.AARCH64.MM_STANDALONE] HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c index defb2584daa..286c00e2a55 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.c +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c @@ -7,7 +7,6 @@ **/ #include "PeilessSec.h" -#include // MU_CHANGE #define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\ ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase))) @@ -206,22 +205,6 @@ SecMain ( // SEC phase needs to run library constructors by hand. ProcessLibraryConstructorList (); - // MU_CHANGE [BEGIN] - Add Tpm2StartupInit call - // Initialize the TPM before loading the DXE core - Status = Tpm2StartupInit (); - - /* NOTE: EFI_UNSUPPORTED is treated as a success due to the possibility of there - * not being a TPM on the system and if so, the NULL instance of the startup - * lib should be linked in which returns UNSUPPORTED. Also, even if TPM is - * enabled, Tpm2StartupInit could return UNSUPPORTED depending on the TPM - * instance. */ - if ((Status != EFI_SUCCESS) && (Status != EFI_UNSUPPORTED)) { - DEBUG ((DEBUG_ERROR, "Failed to initialize the TPM\n")); - ASSERT_EFI_ERROR (Status); - } - - // MU_CHANGE [END] - // MU_CHANGE [BEGIN] - Remove DXE Core FV placement assumption // Decompress firmware volumes and load the DXE Core diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf index fd4c063994e..a70afcf91db 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.inf +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf @@ -51,7 +51,6 @@ TimerLib StackCheckLib ArmTransferListLib - Tpm2StartupLib # MU_CHANGE [Ppis] gArmMpCoreInfoPpiGuid From eb22094d46ab490e8cb47f7510b79cbd2ad53550 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 13 Jul 2026 19:47:11 +0000 Subject: [PATCH 02/11] Updated the Tpm2StartupLib to consolidate the functionality from Tcg2Pei. This functionality was updated such that it can be used in both SEC and PEI. Updated PeilessSec to include the updated Tpm2StartupLib functionality. Verified boot to UEFI shell on both Q35 (PEI path) and VIRT (SEC path). Moved the SyncPcrs functionality to Tcg2Dxe; this is only able to be done when the PCD lib is available due to dynamic PCDs. This gives us a common location for syncing to occur on both PEI and PEI-less platforms. Created a fixed version of the DeviceStateLib. This was required due to the use of another dynamic PCD which is not available in SEC. Moved the PCD in MdeModulePkg.dec such that it can be set as FixedAtBuild. --- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 + ArmPlatformPkg/PeilessSec/PeilessSec.c | 32 +- ArmPlatformPkg/PeilessSec/PeilessSec.h | 1 + ArmPlatformPkg/PeilessSec/PeilessSec.inf | 1 + .../DeviceStateLib/DeviceStateLibFixed.c | 33 + .../DeviceStateLib/DeviceStateLibFixed.inf | 36 + MdeModulePkg/MdeModulePkg.dec | 10 +- SecurityPkg/Include/Guid/PrehashedFvHob.h | 39 + SecurityPkg/Include/Library/Tpm2StartupLib.h | 97 +- .../HashLibTpm2/HashLibTpm2PeilessSecLib.c | 111 +-- .../HashLibTpm2/HashLibTpm2PeilessSecLib.inf | 14 +- .../Library/Tpm2StartupLib/Tpm2StartupLib.c | 930 +++++++++++++++++- .../Library/Tpm2StartupLib/Tpm2StartupLib.inf | 119 ++- .../Tpm2StartupLibNull/Tpm2StartupLibNull.c | 65 +- .../Tpm2StartupLibNull/Tpm2StartupLibNull.inf | 1 - SecurityPkg/SecurityPkg.dec | 7 + SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c | 85 ++ SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf | 3 + SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 312 +++++- SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 50 +- 20 files changed, 1691 insertions(+), 256 deletions(-) create mode 100644 MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c create mode 100644 MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf create mode 100644 SecurityPkg/Include/Guid/PrehashedFvHob.h diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 80b476af691..4a3d425c4ac 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -99,6 +99,7 @@ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibFfa/Tpm2DeviceSecLibFfa.inf HashLib|SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf PeilessSecMeasureLib|SecurityPkg/Library/PeilessSecMeasureLib/PeilessSecMeasureLib.inf + Tpm2StartupLib|SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf ## MU_CHANGE [LibraryClasses.AARCH64.MM_STANDALONE] HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c index 286c00e2a55..b7659d9c7e8 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.c +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c @@ -104,6 +104,7 @@ SecMain ( FIRMWARE_SEC_PERFORMANCE Performance; VOID *TransferListBase; UINTN *TransferListHobData; + EFI_PEI_HOB_POINTERS FvHob; // MU_CHANGE // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP) ASSERT ( @@ -210,8 +211,35 @@ SecMain ( // Decompress firmware volumes and load the DXE Core DecompressFvs (); - Status = MeasurePeilessSec (); - ASSERT_EFI_ERROR (Status); + // MU_CHANGE - [BEGIN] + + Status = Tpm2StartupInitializeTpm (FALSE); + if (!EFI_ERROR (Status)) { + Status = Tpm2StartupMeasureCoreEvents (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Tpm2StartupMeasureCoreEvents failed: %r\n", __func__, Status)); + } + + // Walk every FV HOB and measure each FV into PCR 0. Excluded FVs and + // pre-hashed FVs are handled inside Tpm2StartupMeasureFvImage via + // gExcludedFvHobGuid / gPrehashedFvHobGuid HOB lookups. + FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GetHobList ()); + while (FvHob.Raw != NULL) { + (VOID)Tpm2StartupMeasureFvImage ( + FvHob.FirmwareVolume->BaseAddress, + FvHob.FirmwareVolume->Length + ); + FvHob.Raw = GET_NEXT_HOB (FvHob); + FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw); + } + + Tpm2StartupPublishMeasuredFvHob (); + } else if (Status != EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, "%a: Tpm2StartupInitializeTpm failed: %r\n", __func__, Status)); + ASSERT_EFI_ERROR (FALSE); + } + + // MU_CHANGE - [END] // Load the DXE Core and transfer control to it Status = LoadDxeCoreFromFv (NULL, 0); diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.h b/ArmPlatformPkg/PeilessSec/PeilessSec.h index abe885e689e..9e289625c10 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.h +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.h @@ -26,6 +26,7 @@ #include #include #include +#include // MU_CHANGE #include #include diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf index a70afcf91db..fd4c063994e 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.inf +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf @@ -51,6 +51,7 @@ TimerLib StackCheckLib ArmTransferListLib + Tpm2StartupLib # MU_CHANGE [Ppis] gArmMpCoreInfoPpiGuid diff --git a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c new file mode 100644 index 00000000000..aa2fe2e6a2a --- /dev/null +++ b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c @@ -0,0 +1,33 @@ +/** @file + Read-only DeviceStateLib for platforms that pin PcdDeviceStateBitmask as + FixedAtBuild. GetDeviceState returns the compile-time value; AddDeviceState + is unsupported (Fixed PCDs cannot be updated). + + Copyright (C) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +DEVICE_STATE +EFIAPI +GetDeviceState ( + VOID + ) +{ + return (DEVICE_STATE)FixedPcdGet32 (PcdDeviceStateBitmask); +} + +RETURN_STATUS +EFIAPI +AddDeviceState ( + DEVICE_STATE AdditionalState + ) +{ + (VOID)AdditionalState; + DEBUG ((DEBUG_WARN, "%a: AddDeviceState is unsupported when PcdDeviceStateBitmask is FixedAtBuild\n", __func__)); + return RETURN_UNSUPPORTED; +} diff --git a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf new file mode 100644 index 00000000000..cf60903d29b --- /dev/null +++ b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf @@ -0,0 +1,36 @@ +## @file +# Read-only DeviceStateLib variant for platforms that resolve +# PcdDeviceStateBitmask as FixedAtBuild. +# +# Peiless SEC platforms (e.g. QemuArmVirtPkg) have no dynamic PCD store, +# so the PCD must be Fixed. PcdSet32S is not legal on a Fixed PCD, so this +# variant omits the write path from AddDeviceState. The read path is +# preserved so consumers such as Tpm2StartupLib continue to see the +# platform's build-time device state and emit the appropriate PCR +# measurements. +# +# Copyright (C) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = DeviceStateLibFixed +FILE_GUID = 6c7b1d1a-9c8e-4c2f-8b3a-1e5f2a7d4c60 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = DeviceStateLib + +[LibraryClasses] +DebugLib +PcdLib + +[Packages] +MdePkg/MdePkg.dec +MdeModulePkg/MdeModulePkg.dec + +[Sources] +DeviceStateLibFixed.c + +[FixedPcd] +gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index a9cf584a20b..40610ec4eaa 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -2573,6 +2573,11 @@ # @Prompt Max size to accept in PCIe Resizable BAR Capability register. gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarMaxSize|43|UINT8|0x10000030 + ## MU_CHANGE - Add DeviceStateLib to MdeModulePkg + ## This PCD holds the device state bitmap as described in Include/Library/DeviceStateLib.h. + # @Prompt Describes device state + gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask|0x00000000|UINT32|0x00040009 + [PcdsPatchableInModule] ## Specify memory size with page number for PEI code when # Loading Module at Fixed Address feature is enabled. @@ -2638,11 +2643,6 @@ # The amount of memory allocated for GHCBs is dependent on the number of APs. # @Prompt GHCB Pool Size gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize|0|UINT64|0x00030008 - - ## MU_CHANGE - Add DeviceStateLib to MdeModulePkg - ## This dynamic PCD holds the device state bitmap as described in Include/Library/DeviceStateLib.h - # @Prompt Describes device state - gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask|0x00000000|UINT32|0x00040009 [PcdsDynamicEx] ## This dynamic PCD enables the default variable setting. diff --git a/SecurityPkg/Include/Guid/PrehashedFvHob.h b/SecurityPkg/Include/Guid/PrehashedFvHob.h new file mode 100644 index 00000000000..18e5704e32f --- /dev/null +++ b/SecurityPkg/Include/Guid/PrehashedFvHob.h @@ -0,0 +1,39 @@ +/** @file + HOB used to declare pre-hashed firmware volumes to Tpm2StartupLib + (or any consumer that needs to know a FV's digests without hashing it). + + This is the phase-agnostic equivalent of + gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid. Producers include: + - Tcg2Pei, which translates the PPI to this HOB early in its flow so + the consolidated Tpm2StartupLib can find pre-hashed FVs without + depending on PEI services. + - PEI-less platforms (SEC / early DXE), which can BuildGuidHob directly + when they have pre-computed FV digests (typically obtained from a + prior firmware stage such as TF-A). + + One HOB is produced per pre-hashed FV. The HOB payload begins with a + PREHASHED_FV_HOB header identifying the FV, immediately followed by + Count HASH_INFO records; each HASH_INFO is followed inline by its + digest bytes (HashSize bytes). This mirrors the PPI payload layout to + keep any PPI-to-HOB translator trivial. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PREHASHED_FV_HOB_H_ +#define PREHASHED_FV_HOB_H_ + +#include + +extern EFI_GUID gPrehashedFvHobGuid; + +typedef struct { + EFI_PHYSICAL_ADDRESS FvBase; + UINT64 FvLength; + UINT32 Count; + // HASH_INFO HashInfo[]; each followed inline by HashSize bytes of digest +} PREHASHED_FV_HOB; + +#endif diff --git a/SecurityPkg/Include/Library/Tpm2StartupLib.h b/SecurityPkg/Include/Library/Tpm2StartupLib.h index 8de35e1a474..83ed07e80a7 100644 --- a/SecurityPkg/Include/Library/Tpm2StartupLib.h +++ b/SecurityPkg/Include/Library/Tpm2StartupLib.h @@ -1,26 +1,103 @@ /** @file - Definitions for TPM 2.0 startup and initialization + Declarations for TPM 2.0 startup and initialization. + + A single library instance consolidates the TPM startup and pre-DXE + measurement work that previously lived in PEI so it can be driven + from either PEI or from SEC on PEI-less platforms. Copyright (c), Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#ifndef TPM2_STARTUP_LIB_H_ -#define TPM2_STARTUP_LIB_H_ +#pragma once + +/** + Initialize the TPM 2.0 device. Requests use of the TPM, invokes + the OEM pre-startup hook, runs TPM startup (with S3-state fallback + to SU_CLEAR and PCR 0..7 separator error events on fallback), + runs TPM self test, the OEM post-selftest hook, and a debug PCR read. + On failure, produces an ERROR HOB so later phases exit early. + + @param[in] IsS3Resume TRUE when the platform is resuming from S3. + Drives TPM_SU_STATE vs TPM_SU_CLEAR selection, + whether self-test runs, and whether error + separator events are generated on PCRs 0..7. + + @retval EFI_SUCCESS Initialization completed. + @retval EFI_UNSUPPORTED TPM2 is not required. + @retval EFI_NOT_FOUND TPM device not detected. + @retval EFI_DEVICE_ERROR A TPM command failed; error HOB was produced, + or a prior error HOB was found. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupInitializeTpm ( + IN BOOLEAN IsS3Resume + ); /** - This function initializes the TPM if required + Generates the pre-Tcg2 core measurement events. Runs the OEM + pre-measurement hook, seeds the pre-UEFI event log, measures the + firmware debugger state (when enabled), and measures the CRTM version + (when enabled). On failure, produces an ERROR HOB so later phases exit + early. - @retval EFI_SUCCESS TPM successfully initialized - @retval EFI_UNSUPPORTED TPM is not supported - @retval EFI_NOT_FOUND TPM device not found - @retval EFI_DEVICE_ERROR Unexpected device error + @retval EFI_SUCCESS All applicable events measured. + @retval EFI_UNSUPPORTED TPM2 is not required. + @retval EFI_NOT_FOUND TPM device not detected. + @retval EFI_DEVICE_ERROR A TPM command failed; error HOB was produced, + or a prior error HOB was found. **/ EFI_STATUS EFIAPI -Tpm2StartupInit ( +Tpm2StartupMeasureCoreEvents ( VOID ); -#endif +/** + Measure a single firmware volume image into PCR 0. Handles + excluded FV HOBs, pre-hashed FV HOBs (where digests are provided + to prevent re-hashing), and migrated FV HOBs. + + @param[in] FvBase Base address of the FV image. + @param[in] FvLength Length of the FV image. + + @retval EFI_SUCCESS FV was measured or was already + measured/excluded. + @retval EFI_INVALID_PARAMETER Malformed data. + @retval EFI_OUT_OF_RESOURCES Allocation failure. + @retval EFI_DEVICE_ERROR A TPM command failed. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupMeasureFvImage ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ); + +/** + Record a child FV (an FV embedded inside a file inside its parent) so + that when the same address range is presented again during a later + FV-notify, it is not measured a second time. The child's content was + already covered by the parent measurement. + + @param[in] FvBase Base address of the child FV. + @param[in] FvLength Length of the child FV. +**/ +VOID +EFIAPI +Tpm2StartupRecordChildFv ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ); + +/** + Publish gMeasuredFvHobGuid containing every base and child FV that + was measured. +**/ +VOID +EFIAPI +Tpm2StartupPublishMeasuredFvHob ( + VOID + ); diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c index 8e2b08789f0..44a97cedd14 100644 --- a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c +++ b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c @@ -11,23 +11,21 @@ **/ -#include - -#include -#include -#include - -#include - -#include +#include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE #include #include #include #include #include -#include +// #include // MU_CHANGE #include -#include +// #include // MU_CHANGE // MU_CHANGE - [BEGIN] #include @@ -51,8 +49,6 @@ STATIC TPM2_HASH_MASK mTpm2HashMask[] = { STATIC UINT32 mSupportedHashBitmap; STATIC BOOLEAN mHashLibDisabled; -#endif -// MU_CHANGE - [END] /** Get transfer list header. @@ -92,18 +88,18 @@ GetTransferList ( return EFI_SUCCESS; } - -// MU_CHANGE - [BEGIN] +#endif /** - Get supported hash bitmap + Get the hash algorithm bitmap to drive per-operation. The set matches the + TPM's currently active PCR banks, obtained directly from the device. - @param[out] SupportedHashBitmap + @param[out] SupportedHashBitmap Bitmap of currently active PCR banks. - @retval EFI_SUCCESS Bitmap populated - @retval EFI_INVALID_PARAMETER Invalid pointer - @retval EFI_NOT_FOUND Error accessing data - @retval EFI_DEVICE_ERROR TPM device error + @retval EFI_SUCCESS Bitmap populated. + @retval EFI_INVALID_PARAMETER SupportedHashBitmap is NULL. + @retval EFI_DEVICE_ERROR TPM not available or capability query + failed. **/ STATIC @@ -113,18 +109,9 @@ GetSupportedHashBitmap ( OUT UINT32 *SupportedHashBitmap ) { - EFI_STATUS Status; - TRANSFER_LIST_HEADER *TransferList; - VOID *EventLog; - UINTN EventLogSize; - TCG_PCR_EVENT *TcgPcrEvent; - TCG_EfiSpecIDEventStruct *TcgEfiSpecIdEventStruct; - TCG_EfiSpecIdEventAlgorithmSize *DigestSize; - UINTN Idx; - UINT32 NumberOfAlgorithms; - UINT32 TpmHashBitmap; - UINT32 PcrHashBitmap; - BOOLEAN UseTlHashBitmap; + EFI_STATUS Status; + UINT32 TpmHashAlgorithmBitmap; + UINT32 ActivePCRBanks; if (SupportedHashBitmap == NULL) { return EFI_INVALID_PARAMETER; @@ -132,67 +119,21 @@ GetSupportedHashBitmap ( Status = Tpm2RequestUseTpm (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: TPM2 not detected!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a: TPM2 not detected: %r\n", __func__, Status)); return Status; } - Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashBitmap, &PcrHashBitmap); + Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: Failed to get Tpm capability... Status: %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a: Failed to get Tpm capability: %r\n", __func__, Status)); return Status; } - // NOTE: TpmHashBitmap is what the TPM supports, PcrHashBitmap is what is currently active - DEBUG ((DEBUG_INFO, "TpmHashBitmap: %x, PcrHashBitmap: %x\n", TpmHashBitmap, PcrHashBitmap)); - - UseTlHashBitmap = FALSE; - Status = GetTransferList (&TransferList); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: Unable to acquire Transfer list...\n", __func__)); - goto Exit; - } - - if (TransferListCheckHeader (TransferList) == TRANSFER_LIST_OPS_INVALID) { - DEBUG ((DEBUG_ERROR, "%a: Invalid Transfer list...\n", __func__)); - goto Exit; - } - - Status = TransferListGetEventLog (TransferList, &EventLog, &EventLogSize, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: No data for TPM event log...\n", __func__)); - goto Exit; - } - - UseTlHashBitmap = TRUE; - TcgPcrEvent = (TCG_PCR_EVENT *)EventLog; - TcgEfiSpecIdEventStruct = (TCG_EfiSpecIDEventStruct *) - (EventLog + OFFSET_OF (TCG_PCR_EVENT, Event)); - - CopyMem (&NumberOfAlgorithms, TcgEfiSpecIdEventStruct + 1, sizeof (NumberOfAlgorithms)); - DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof (*TcgEfiSpecIdEventStruct) + sizeof (NumberOfAlgorithms)); - DEBUG ((DEBUG_INFO, "%a: Transfer list TPM event log available\n", __func__)); - - // Update the supported hash bitmap based on the info from the TCG event log - for (Idx = 0; Idx < NumberOfAlgorithms; Idx++) { - *SupportedHashBitmap |= GetHashMaskFromAlgo (DigestSize[Idx].algorithmId); - } - - // The active PCR banks should match what is reported in the TCG event log - if (PcrHashBitmap != *SupportedHashBitmap) { - DEBUG ((DEBUG_ERROR, "Active PCRs & Transfer List mismatch!\n")); - UseTlHashBitmap = FALSE; - } - -Exit: - if (!UseTlHashBitmap) { - // Use the information from the TPM to update the supported hash bitmap - *SupportedHashBitmap = TpmHashBitmap; - DEBUG ((DEBUG_INFO, "%a: No Transfer List or TPM event log available\n", __func__)); - } + DEBUG ((DEBUG_INFO, "%a: TpmHashAlgorithmBitmap=0x%x, ActivePCRBanks=0x%x\n", __func__, TpmHashAlgorithmBitmap, ActivePCRBanks)); - *SupportedHashBitmap &= PcrHashBitmap; + *SupportedHashBitmap = ActivePCRBanks; if (*SupportedHashBitmap == 0x00) { - DEBUG ((DEBUG_ERROR, "%a: No supported Hash algorithm with event log Spec...!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a: No active PCR banks reported by the TPM.\n", __func__)); } return EFI_SUCCESS; diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf index 4199b787e69..774c53e39af 100644 --- a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf +++ b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.inf @@ -26,23 +26,23 @@ HashLibTpm2PeilessSecLib.c [Packages] - ArmPkg/ArmPkg.dec - EmbeddedPkg/EmbeddedPkg.dec - MdeModulePkg/MdeModulePkg.dec + # ArmPkg/ArmPkg.dec # MU_CHANGE + # EmbeddedPkg/EmbeddedPkg.dec # MU_CHANGE + # MdeModulePkg/MdeModulePkg.dec # MU_CHANGE MdePkg/MdePkg.dec SecurityPkg/SecurityPkg.dec [LibraryClasses] - ArmLib - ArmFfaLib + # ArmLib # MU_CHANGE + # ArmFfaLib # MU_CHANGE BaseLib BaseMemoryLib DebugLib - HobLib + # HobLib # MU_CHANGE PrePiLib Tpm2DeviceLib Tpm2CommandLib Tpm2HelpLib # MU_CHANGE [Guids] - gTpmErrorHobGuid + # gTpmErrorHobGuid # MU_CHANGE diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c index 699528534da..2365c408593 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c @@ -1,78 +1,940 @@ /** @file - Setup and initialization of TPM 2.0 + Definitions for TPM 2.0 startup and initialization. + A single library instance consolidates the TPM startup and pre-DXE + measurement work that previously lived in PEI so it can be driven + from either PEI or from SEC on PEI-less platforms. + +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
Copyright (c), Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include + +#include + #include -#include #include #include +#include +#include +#include +#include -#include -#include #include +#include #include -#include -#include -#include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include +#include + +#define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)" + +// Flag for InternalHashLogExtend. When set, HashData points to a +// caller-supplied TPML_DIGEST_VALUES and the PCR is extended with those +// digests; otherwise HashData is hashed and extended via HashLib. +#define TPM2_STARTUP_FLAG_PRE_HASH BIT0 + +#pragma pack (1) + +// FV_HANDOFF_TABLE_POINTERS2 per TCG PC Client PFP 10.2.5. +typedef struct { + UINT8 BlobDescriptionSize; + UINT8 BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)]; + EFI_PHYSICAL_ADDRESS BlobBase; + UINT64 BlobLength; +} FV_HANDOFF_TABLE_POINTERS2; + +#pragma pack () + +// Private HOB GUID used to persist one EFI_PLATFORM_FIRMWARE_BLOB per FV +// that has been measured (or recorded as covered by a parent's +// measurement) in this phase. Tpm2StartupPublishMeasuredFvHob consolidates +// the entries into a single gMeasuredFvHobGuid HOB for downstream consumers. +STATIC CONST EFI_GUID mTpm2StartupMeasuredFvHobGuid = { + 0x8dbc7a5e, 0x2b31, 0x4a4f, { 0x9c, 0x0a, 0x36, 0x7f, 0xa4, 0x1b, 0x7d, 0xe5 } +}; + +// Table used by LogHashEvent to iterate over supported log formats. +typedef struct { + EFI_GUID *EventGuid; + EFI_TCG2_EVENT_LOG_FORMAT LogFormat; +} TCG2_EVENT_INFO_STRUCT; + +STATIC CONST TCG2_EVENT_INFO_STRUCT mTcg2EventInfo[] = { + { &gTcgEventEntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 }, + { &gTcgEvent2EntryHobGuid, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 }, +}; + +/** + Produce gTpmErrorHobGuid (if not already present) and report an interface + error status code. Downstream consumers use presence of the HOB to skip + further TPM interaction. +**/ +STATIC +VOID +ReportTpmErrorHob ( + VOID + ) +{ + if (GetFirstGuidHob (&gTpmErrorHobGuid) == NULL) { + BuildGuidHob (&gTpmErrorHobGuid, 0); + } + + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) + ); +} /** - This function initializes the TPM if required + Common checks that ensure the platform enables valid TPM instance, no prior + TPM error was reported, and the device is successfully requested. On failure, + produces an ERROR HOB so later phases exit early. - @retval EFI_SUCCESS TPM successfully initialized - @retval EFI_UNSUPPORTED TPM is not supported - @retval EFI_NOT_FOUND TPM device not found - @retval EFI_DEVICE_ERROR Unexpected device error + @retval EFI_SUCCESS Valid TPM instance, no prior error, and the device + was acquired. + @retval EFI_UNSUPPORTED Invalid TPM instance. + @retval EFI_DEVICE_ERROR Prior TPM error detected or device error. + @retval EFI_NOT_FOUND TPM2 not found. **/ +STATIC EFI_STATUS -EFIAPI -Tpm2StartupInit ( +Tpm2StartupCheckPrereqs ( VOID ) { EFI_STATUS Status; - DEBUG ((DEBUG_INFO, "%a - Entry\n", __func__)); - if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || - CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) - { - DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n")); + CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) { + DEBUG ((DEBUG_INFO, "%a - No TPM2 instance required.\n", __func__)); return EFI_UNSUPPORTED; } - // Request use of the TPM + if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { + DEBUG ((DEBUG_ERROR, "%a - gTpmErrorHobGuid present.\n", __func__)); + return EFI_DEVICE_ERROR; + } + Status = Tpm2RequestUseTpm (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "TPM2 not detected! Status: %r\n", Status)); - goto Done; + DEBUG ((DEBUG_ERROR, "%a - Tpm2RequestUseTpm failed: %r\n", __func__, Status)); + ReportTpmErrorHob (); + return Status; + } + + return EFI_SUCCESS; +} + +/** + Walk gExcludedFvHobGuid HOB list for a matching FV. + + @param[in] FvBase Base address of the FV to check. + @param[in] FvLength Length of the FV to check. + + @retval TRUE The FV is present and must not be measured. + @retval FALSE The FV is not present and may be measured. +**/ +STATIC +BOOLEAN +IsFvMeasurementExcluded ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EXCLUDED_HOB_DATA *ExcludedHobData; + UINT32 Index; + + GuidHob = GetFirstGuidHob (&gExcludedFvHobGuid); + while (GuidHob != NULL) { + ExcludedHobData = GET_GUID_HOB_DATA (GuidHob); + for (Index = 0; Index < ExcludedHobData->Num; Index++) { + if ((ExcludedHobData->ExcludedFvs[Index].FvBase == FvBase) && + (ExcludedHobData->ExcludedFvs[Index].FvLength == FvLength)) { + return TRUE; + } + } + + GuidHob = GetNextGuidHob (&gExcludedFvHobGuid, GET_NEXT_HOB (GuidHob)); + } + + return FALSE; +} + +/** + Walk gPrehashedFvHobGuid HOBs for a matching FV; populate DigestList with + digests whose algorithms intersect the mask provided. The mask bits are + cleared when found. When the mask reaches 0 the caller can skip hashing. + + @param[in] FvBase Base address of the FV to look up. + @param[in] FvLength Length of the FV to look up. + @param[out] DigestList Populated with matching digests. + @param[in,out] RemainingTpm2HashMask Hash to acquire, cleared when found. + + @retval EFI_SUCCESS Found a matching FV and hash algorithm. + @retval EFI_NOT_FOUND No pre-hashed HOB found. +**/ +STATIC +EFI_STATUS +GetPrehashedFvDigests ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength, + OUT TPML_DIGEST_VALUES *DigestList, + IN OUT UINT32 *RemainingTpm2HashMask + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + PREHASHED_FV_HOB *Hdr; + HASH_INFO *PreHashInfo; + UINT32 HashAlgoMask; + UINT32 Index; + UINT32 DigestCount; + + GuidHob = GetFirstGuidHob (&gPrehashedFvHobGuid); + while (GuidHob != NULL) { + Hdr = GET_GUID_HOB_DATA (GuidHob); + if ((Hdr->FvBase == FvBase) && (Hdr->FvLength == FvLength)) { + PreHashInfo = (HASH_INFO *)(Hdr + 1); + DigestCount = 0; + for (Index = 0; Index < Hdr->Count; Index++) { + HashAlgoMask = GetHashMaskFromAlgo (PreHashInfo->HashAlgoId); + if ((*RemainingTpm2HashMask & HashAlgoMask) != 0) { + WriteUnaligned16 (&(DigestList->digests[DigestCount].hashAlg), PreHashInfo->HashAlgoId); + CopyMem (&DigestList->digests[DigestCount].digest, PreHashInfo + 1, PreHashInfo->HashSize); + DigestCount++; + *RemainingTpm2HashMask &= ~HashAlgoMask; + } + + PreHashInfo = (HASH_INFO *)((UINT8 *)(PreHashInfo + 1) + PreHashInfo->HashSize); + } + + WriteUnaligned32 (&DigestList->count, DigestCount); + return EFI_SUCCESS; + } + + GuidHob = GetNextGuidHob (&gPrehashedFvHobGuid, GET_NEXT_HOB (GuidHob)); + } + + return EFI_NOT_FOUND; +} + +/** + Emit event-log HOBs (TCG 1.2 and TCG 2.0 formats) for a completed extend. + Both formats are always emitted; downstream consumers pick the one they + need. + + @param[in] DigestList Event digest list. + @param[in,out] NewEventHdr Event header. + @param[in] NewEventData Event data. + + @retval EFI_SUCCESS HOBs were built successfully. + @retval EFI_OUT_OF_RESOURCES A HOB allocation failed. + @retval EFI_DEVICE_ERROR Device communication failed. +**/ +STATIC +EFI_STATUS +LogHashEvent ( + IN TPML_DIGEST_VALUES *DigestList, + IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, + IN UINT8 *NewEventData + ) +{ + VOID *HobData; + EFI_STATUS Status; + UINTN Index; + EFI_STATUS RetStatus; + UINT32 SupportedEventLogs; + TCG_PCR_EVENT2 *TcgPcrEvent2; + UINT8 *DigestBuffer; + UINT32 HashAlgorithmBitmap; + UINT32 ActivePcrBanks; + + Status = Tpm2GetCapabilitySupportedAndActivePcrs (&HashAlgorithmBitmap, &ActivePcrBanks); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; + RetStatus = EFI_SUCCESS; + + for (Index = 0; Index < sizeof (mTcg2EventInfo) / sizeof (mTcg2EventInfo[0]); Index++) { + if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) == 0) { + continue; + } + + switch (mTcg2EventInfo[Index].LogFormat) { + case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: + Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest); + if (!EFI_ERROR (Status)) { + HobData = BuildGuidHob ( + &gTcgEventEntryHobGuid, + sizeof (*NewEventHdr) + NewEventHdr->EventSize + ); + if (HobData == NULL) { + RetStatus = EFI_OUT_OF_RESOURCES; + break; + } + + CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); + HobData = (VOID *)((UINT8 *)HobData + sizeof (*NewEventHdr)); + CopyMem (HobData, NewEventData, NewEventHdr->EventSize); + } + + break; + + case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: + HobData = BuildGuidHob ( + &gTcgEvent2EntryHobGuid, + sizeof (TcgPcrEvent2->PCRIndex) + sizeof (TcgPcrEvent2->EventType) + + GetDigestListSize (DigestList) + + sizeof (TcgPcrEvent2->EventSize) + NewEventHdr->EventSize + ); + if (HobData == NULL) { + RetStatus = EFI_OUT_OF_RESOURCES; + break; + } + + TcgPcrEvent2 = HobData; + TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex; + TcgPcrEvent2->EventType = NewEventHdr->EventType; + DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest; + DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, ActivePcrBanks); + CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof (TcgPcrEvent2->EventSize)); + DigestBuffer = DigestBuffer + sizeof (TcgPcrEvent2->EventSize); + CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize); + break; + } + } + + return RetStatus; +} + +/** + Hash (or accept a pre-hashed digest for) a buffer, extend the target PCR, + and emit the corresponding event-log HOBs. When TPM2_STARTUP_FLAG_PRE_HASH + is set, HashData points to a caller-supplied TPML_DIGEST_VALUES and the PCR + is extended with those digests. Otherwise HashData is hashed and extended + via the HashLib. On failure, produces an ERROR HOB so later phases exit + early. + + @param[in] Flags Combination of TPM2_STARTUP_FLAG_* bits. + @param[in] HashData Buffer to hash, or a TPML_DIGEST_VALUES when + TPM2_STARTUP_FLAG_PRE_HASH is set. + @param[in] HashDataLen Length of HashData in bytes (ignored on the + pre-hash path). + @param[in] NewEventHdr Event header for logging (PCR, type, size). + @param[in] NewEventData Event data buffer for logging. + + @retval EFI_SUCCESS PCR extended and event logged. + @retval EFI_DEVICE_ERROR Prior TPM error detected or device error. + @retval EFI_OUT_OF_RESOURCES A HOB allocation failed. +**/ +STATIC +EFI_STATUS +InternalHashLogExtend ( + IN UINT64 Flags, + IN UINT8 *HashData, + IN UINTN HashDataLen, + IN TCG_PCR_EVENT_HDR *NewEventHdr, + IN UINT8 *NewEventData + ) +{ + EFI_STATUS Status; + TPML_DIGEST_VALUES DigestList; + + if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { + return EFI_DEVICE_ERROR; + } + + if ((Flags & TPM2_STARTUP_FLAG_PRE_HASH) != 0) { + ZeroMem (&DigestList, sizeof (DigestList)); + CopyMem (&DigestList, HashData, sizeof (DigestList)); + Status = Tpm2PcrExtend (NewEventHdr->PCRIndex, &DigestList); + } else { + Status = HashAndExtend ( + NewEventHdr->PCRIndex, + HashData, + HashDataLen, + &DigestList + ); + } + + if (!EFI_ERROR (Status)) { + Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData); } - // Determine if initialization is requested + if (Status == EFI_DEVICE_ERROR) { + DEBUG ((DEBUG_ERROR, "%a - %r. Disable TPM.\n", __func__, Status)); + ReportTpmErrorHob (); + } + + return Status; +} + +/** + Measure PcdFirmwareVersionString into PCR 0 as an EV_S_CRTM_VERSION event. + + @retval EFI_SUCCESS Measurement extended and logged. + @retval EFI_DEVICE_ERROR Prior TPM error detected or device error. + @retval EFI_OUT_OF_RESOURCES A HOB allocation failed. +**/ +STATIC +EFI_STATUS +MeasureCRTMVersion ( + VOID + ) +{ + TCG_PCR_EVENT_HDR TcgEventHdr; + + TcgEventHdr.PCRIndex = 0; + TcgEventHdr.EventType = EV_S_CRTM_VERSION; + TcgEventHdr.EventSize = (UINT32)StrSize ((CHAR16 *)PcdGetPtr (PcdFirmwareVersionString)); + + return InternalHashLogExtend ( + 0, + (UINT8 *)PcdGetPtr (PcdFirmwareVersionString), + TcgEventHdr.EventSize, + &TcgEventHdr, + (UINT8 *)PcdGetPtr (PcdFirmwareVersionString) + ); +} + +/** + Measure the FIRMWARE_DEBUGGER_EVENT_STRING marker into PCR 7 as an + EV_EFI_ACTION event. + + @retval EFI_SUCCESS Measurement extended and logged. + @retval EFI_DEVICE_ERROR Prior TPM error detected or device error. + @retval EFI_OUT_OF_RESOURCES A HOB allocation failed. +**/ +STATIC +EFI_STATUS +MeasureFirmwareDebuggerEnabled ( + VOID + ) +{ + TCG_PCR_EVENT_HDR TcgEventHdr; + + TcgEventHdr.PCRIndex = 7; + TcgEventHdr.EventType = EV_EFI_ACTION; + TcgEventHdr.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1; + + DEBUG ((DEBUG_INFO, "Measuring Device State: Firmware Debugger Enabled\n")); + return InternalHashLogExtend ( + 0, + (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING, + sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1, + &TcgEventHdr, + (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING + ); +} + +/** + Emit an EV_SEPARATOR event on the specified PCR with the error data + value defined by TCG PC Client PFP (0x00000001). Used after S3 startup + failure to record that the pre-boot state is untrustworthy. + + @param[in] PCRIndex PCR to extend with the separator event. + + @retval EFI_SUCCESS Separator extended and logged. + @retval EFI_DEVICE_ERROR Prior TPM error detected or device error. + @retval EFI_OUT_OF_RESOURCES A HOB allocation failed. +**/ +STATIC +EFI_STATUS +MeasureSeparatorEventWithError ( + IN TPM_PCRINDEX PCRIndex + ) +{ + TCG_PCR_EVENT_HDR TcgEvent; + UINT32 EventData; + + EventData = 0x1; + TcgEvent.PCRIndex = PCRIndex; + TcgEvent.EventType = EV_SEPARATOR; + TcgEvent.EventSize = (UINT32)sizeof (EventData); + return InternalHashLogExtend (0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent, (UINT8 *)&EventData); +} + +/** + Locate the FV name GUID (from the extended header) inside an FV image, + with bounds checks so a malformed or truncated FV cannot cause an + out-of-bounds read. + + @param[in] FvBase Base address of the FV image. + @param[in] FvLength Length of the FV image. + + @return Pointer to the FvName GUID inside the FV extended header, or + NULL when the FV has no extended header or fails bounds checks. +**/ +STATIC +VOID * +GetFvName ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + EFI_FIRMWARE_VOLUME_EXT_HEADER *FvExtHeader; + + if ((FvBase >= MAX_ADDRESS) || + (FvLength >= MAX_ADDRESS - FvBase) || + (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER))) { + return NULL; + } + + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase; + if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) { + return NULL; + } + + if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) { + return NULL; + } + + FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset); + return &FvExtHeader->FvName; +} + +/** + If FvBase/FvLength matches a migrated FV entry in gEdkiiMigratedFvInfoGuid, + return the original pre-migration base (for event-log correctness) and + the current in-memory data base (for hashing). Otherwise both output + addresses fall back to FvBase. + + @param[in] FvBase Current base address the caller sees. + @param[in] FvLength Length of the FV. + @param[out] FvOrgBase Original pre-migration base, or FvBase when the + FV was not migrated. + @param[out] FvDataBase Current in-memory data base to hash from, or + FvBase when the FV was not migrated. +**/ +STATIC +VOID +ResolveMigratedFvBases ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength, + OUT EFI_PHYSICAL_ADDRESS *FvOrgBase, + OUT EFI_PHYSICAL_ADDRESS *FvDataBase + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EDKII_MIGRATED_FV_INFO *MigratedFvInfo; + + *FvOrgBase = FvBase; + *FvDataBase = FvBase; + + Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid); + while (Hob.Raw != NULL) { + MigratedFvInfo = GET_GUID_HOB_DATA (Hob); + if ((MigratedFvInfo->FvNewBase == (UINT32)FvBase) && + (MigratedFvInfo->FvLength == (UINT32)FvLength)) + { + *FvOrgBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MigratedFvInfo->FvOrgBase; + *FvDataBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MigratedFvInfo->FvDataBase; + return; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw); + } +} + +/** + Walk the private measured-FV HOB store to determine whether an entry for + the given FV already exists. + + @param[in] FvBase Base address of the FV. + @param[in] FvLength Length of the FV. + + @retval TRUE A matching entry is already present. + @retval FALSE No matching entry; the FV has not been measured or + recorded in this phase. +**/ +STATIC +BOOLEAN +IsFvAlreadyRecorded ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PLATFORM_FIRMWARE_BLOB *Blob; + + GuidHob = GetFirstGuidHob (&mTpm2StartupMeasuredFvHobGuid); + while (GuidHob != NULL) { + Blob = GET_GUID_HOB_DATA (GuidHob); + if ((Blob->BlobBase == FvBase) && (Blob->BlobLength == FvLength)) { + return TRUE; + } + + GuidHob = GetNextGuidHob (&mTpm2StartupMeasuredFvHobGuid, GET_NEXT_HOB (GuidHob)); + } + + return FALSE; +} + +/** + Record an FV in the private measured-FV HOB store. + + @param[in] FvBase Base address of the FV. + @param[in] FvLength Length of the FV. + + @retval EFI_SUCCESS Entry was already present, or a new HOB + was appended. + @retval EFI_OUT_OF_RESOURCES BuildGuidHob failed. +**/ +STATIC +EFI_STATUS +RecordMeasuredFv ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_PLATFORM_FIRMWARE_BLOB *Blob; + + if (IsFvAlreadyRecorded (FvBase, FvLength)) { + return EFI_SUCCESS; + } + + Blob = BuildGuidHob (&mTpm2StartupMeasuredFvHobGuid, sizeof (EFI_PLATFORM_FIRMWARE_BLOB)); + if (Blob == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Blob->BlobBase = FvBase; + Blob->BlobLength = FvLength; + return EFI_SUCCESS; +} + +/** + See Tpm2StartupLib.h. Public API. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupMeasureFvImage ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + EFI_STATUS Status; + EFI_PLATFORM_FIRMWARE_BLOB FvBlob; + FV_HANDOFF_TABLE_POINTERS2 FvBlob2; + VOID *EventData; + VOID *FvName; + TCG_PCR_EVENT_HDR TcgEventHdr; + TPML_DIGEST_VALUES DigestList; + EFI_PHYSICAL_ADDRESS FvOrgBase; + EFI_PHYSICAL_ADDRESS FvDataBase; + UINT32 HashAlgorithmBitmap; + UINT32 ActivePcrBanks; + + Status = Tpm2GetCapabilitySupportedAndActivePcrs (&HashAlgorithmBitmap, &ActivePcrBanks); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + if (IsFvMeasurementExcluded (FvBase, FvLength)) { + DEBUG ((DEBUG_INFO, "FV excluded from measurement: base=0x%lx len=0x%lx\n", FvBase, FvLength)); + return EFI_SUCCESS; + } + + if (IsFvAlreadyRecorded (FvBase, FvLength)) { + DEBUG ((DEBUG_INFO, "FV already measured: base=0x%lx len=0x%lx\n", FvBase, FvLength)); + return EFI_SUCCESS; + } + + ZeroMem (&DigestList, sizeof (DigestList)); + (VOID)GetPrehashedFvDigests (FvBase, FvLength, &DigestList, &ActivePcrBanks); + + ResolveMigratedFvBases (FvBase, FvLength, &FvOrgBase, &FvDataBase); + + if (PcdGet32 (PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105) { + FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription); + CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription)); + FvName = GetFvName (FvBase, FvLength); + if (FvName != NULL) { + AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName); + } + + FvBlob2.BlobBase = FvOrgBase; + FvBlob2.BlobLength = FvLength; + TcgEventHdr.PCRIndex = 0; + TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2; + TcgEventHdr.EventSize = sizeof (FvBlob2); + EventData = &FvBlob2; + } else { + FvBlob.BlobBase = FvOrgBase; + FvBlob.BlobLength = FvLength; + TcgEventHdr.PCRIndex = 0; + TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB; + TcgEventHdr.EventSize = sizeof (FvBlob); + EventData = &FvBlob; + } + + if (ActivePcrBanks == 0) { + // Pre-hashed digests satisfy the full TPM hash mask; skip hashing. + Status = InternalHashLogExtend ( + TPM2_STARTUP_FLAG_PRE_HASH, + (UINT8 *)&DigestList, + (UINTN)sizeof (DigestList), + &TcgEventHdr, + EventData + ); + DEBUG ((DEBUG_INFO, "Pre-hashed FV extended & logged: base=0x%lx len=0x%lx\n", FvBase, FvLength)); + } else { + Status = InternalHashLogExtend ( + 0, + (UINT8 *)(UINTN)FvDataBase, + (UINTN)FvLength, + &TcgEventHdr, + EventData + ); + DEBUG ((DEBUG_INFO, "FV hashed & measured: base=0x%lx len=0x%lx\n", FvBase, FvLength)); + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "FV failed measurement: base=0x%lx status=%r\n", FvBase, Status)); + return Status; + } + + return RecordMeasuredFv (FvBase, FvLength); +} + +/** + See Tpm2StartupLib.h. Public API. +**/ +VOID +EFIAPI +Tpm2StartupRecordChildFv ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + (VOID)RecordMeasuredFv (FvBase, FvLength); +} + +/** + Run the pre-Tcg2 measurement sequence: pre-UEFI event log seeding, + firmware debugger state (when source-debug is enabled), and CRTM + version (when PcdTpm2ScrtmPolicy selects it). Callers measure their + FVs separately via Tpm2StartupMeasureFvImage. + + @retval EFI_SUCCESS All enabled measurements were extended and logged. + @retval other Propagated from the first failing measurement. +**/ +STATIC +EFI_STATUS +RunMeasurementPhase ( + VOID + ) +{ + EFI_STATUS Status; + DEVICE_STATE CurrentDeviceState; + + CreateTcg2PreUefiEventLogEntries (); + + CurrentDeviceState = GetDeviceState (); + if ((CurrentDeviceState & DEVICE_STATE_SOURCE_DEBUG_ENABLED) != 0) { + Status = MeasureFirmwareDebuggerEnabled (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to measure Firmware Debugger Enabled: %r\n", __func__, Status)); + return Status; + } + } + + if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) { + Status = MeasureCRTMVersion (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - MeasureCRTMVersion failed: %r\n", __func__, Status)); + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + See Tpm2StartupLib.h. Public API. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupInitializeTpm ( + IN BOOLEAN IsS3Resume + ) +{ + EFI_STATUS Status; + BOOLEAN S3ErrorReport; + TPM_PCRINDEX PcrIndex; + EFI_BOOT_MODE OemBootMode; + + DEBUG ((DEBUG_INFO, "%a - Entry (IsS3Resume=%d)\n", __func__, IsS3Resume)); + + Status = Tpm2StartupCheckPrereqs (); + if (EFI_ERROR (Status)) { + return Status; + } + + OemBootMode = IsS3Resume ? BOOT_ON_S3_RESUME : BOOT_WITH_FULL_CONFIGURATION; + + Status = OemTpm2InitPeiPreStartup (OemBootMode); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPreStartup returned %r. Aborting init.\n", Status)); + goto ErrorHob; + } + + S3ErrorReport = FALSE; if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) { - // Setup/Initialize the TPM - Status = Tpm2Startup (TPM_SU_CLEAR); + if (IsS3Resume) { + Status = Tpm2Startup (TPM_SU_STATE); + if (EFI_ERROR (Status)) { + Status = Tpm2Startup (TPM_SU_CLEAR); + if (!EFI_ERROR (Status)) { + S3ErrorReport = TRUE; + } + } + } else { + Status = Tpm2Startup (TPM_SU_CLEAR); + } + if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Tpm2Startup::%a - TPM failed Startup! Status: %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Tpm2Startup failed: %r\n", __func__, Status)); + ASSERT_EFI_ERROR (Status); + goto ErrorHob; } } -Done: + if (S3ErrorReport) { + for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) { + Status = MeasureSeparatorEventWithError (PcrIndex); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Separator Event with Error not measured on PCR %d\n", PcrIndex)); + } + } + } + + if (!IsS3Resume && (PcdGet8 (PcdTpm2SelfTestPolicy) == 1)) { + Status = Tpm2SelfTest (NO); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Tpm2SelfTest failed: %r\n", __func__, Status)); + goto ErrorHob; + } + } + + Status = OemTpm2InitPeiPostSelfTest (OemBootMode); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "TPM2 error! Building Hob.\n")); - BuildGuidHob (&gTpmErrorHobGuid, 0); - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) - ); + DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPostSelfTest returned %r. Aborting init.\n", Status)); + goto ErrorHob; + } + + DEBUG_CODE_BEGIN (); + Tpm2PcrReadForActiveBank (00, NULL); + DEBUG_CODE_END (); + + DEBUG ((DEBUG_INFO, "%a - Exit (Success)\n", __func__)); + return EFI_SUCCESS; + +ErrorHob: + ReportTpmErrorHob (); + DEBUG ((DEBUG_INFO, "%a - Exit (Status=%r)\n", __func__, Status)); + return Status; +} + +/** + See Tpm2StartupLib.h. Public API. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupMeasureCoreEvents ( + VOID + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "%a - Entry\n", __func__)); + + Status = Tpm2StartupCheckPrereqs (); + if (EFI_ERROR (Status)) { + return Status; } - DEBUG ((DEBUG_INFO, "%a - Exit\n", __func__)); + Status = OemTpm2InitPeiPreMeasurements (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPreMeasurements returned %r. Aborting measurement.\n", Status)); + goto ErrorHob; + } + Status = RunMeasurementPhase (); + if (EFI_ERROR (Status)) { + goto ErrorHob; + } + + DEBUG ((DEBUG_INFO, "%a - Exit (Success)\n", __func__)); + return EFI_SUCCESS; + +ErrorHob: + ReportTpmErrorHob (); + DEBUG ((DEBUG_INFO, "%a - Exit (Status=%r)\n", __func__, Status)); return Status; } + +/** + See Tpm2StartupLib.h. Public API. +**/ +VOID +EFIAPI +Tpm2StartupPublishMeasuredFvHob ( + VOID + ) +{ + MEASURED_HOB_DATA *MeasuredHobData; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PLATFORM_FIRMWARE_BLOB *Blob; + UINT32 Count; + UINT32 Index; + + if (GetFirstGuidHob (&gMeasuredFvHobGuid) != NULL) { + return; + } + + Count = 0; + GuidHob = GetFirstGuidHob (&mTpm2StartupMeasuredFvHobGuid); + while (GuidHob != NULL) { + Count++; + GuidHob = GetNextGuidHob (&mTpm2StartupMeasuredFvHobGuid, GET_NEXT_HOB (GuidHob)); + } + + MeasuredHobData = BuildGuidHob ( + &gMeasuredFvHobGuid, + sizeof (UINTN) + sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * Count + ); + if (MeasuredHobData == NULL) { + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate MeasuredFvHob\n", __func__)); + return; + } + + MeasuredHobData->Num = Count; + + Index = 0; + GuidHob = GetFirstGuidHob (&mTpm2StartupMeasuredFvHobGuid); + while (GuidHob != NULL) { + Blob = GET_GUID_HOB_DATA (GuidHob); + MeasuredHobData->MeasuredFvBuf[Index].BlobBase = Blob->BlobBase; + MeasuredHobData->MeasuredFvBuf[Index].BlobLength = Blob->BlobLength; + Index++; + GuidHob = GetNextGuidHob (&mTpm2StartupMeasuredFvHobGuid, GET_NEXT_HOB (GuidHob)); + } +} diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf index 69245b6fcd9..a5a11b17ad1 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf @@ -1,52 +1,67 @@ -## @file -# Handles TPM 2.0 Startup/Initialization. -# -# Includes setup of initial TPM state as well as any pre-DXE -# measurements. Also handles any pre-DXE logging by generating -# HOBs. -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Tpm2StartupLib - FILE_GUID = 2066F14F-6CBB-44D2-A619-4100AADDD2E4 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = Tpm2StartupLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 AARCH64 -# - -[Sources] - Tpm2StartupLib.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - SecurityPkg/SecurityPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - HobLib - ReportStatusCodeLib - Tpm2CommandLib - Tpm2DeviceLib - -[Pcd] - gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES - -[Guids] - gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB - gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier - gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier +## @file +# Handles TPM 2.0 startup and initialization. +# +# A single library instance consolidates the TPM startup and pre-DXE +# measurement work that previously lived in PEI so it can be driven +# from either PEI or from SEC on PEI-less platforms. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Tpm2StartupLib + FILE_GUID = 2066F14F-6CBB-44D2-A619-4100AADDD2E4 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = Tpm2StartupLib + +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + Tpm2StartupLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DeviceStateLib + HashLib + HobLib + OemTpm2InitLib + PcdLib + PrintLib + ReportStatusCodeLib + Tcg2PreUefiEventLogLib + Tpm2CommandLib + Tpm2DeviceLib + Tpm2HelpLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES + +[Guids] + gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB + gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID + gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_CONSUMES ## GUID + gTcgEventEntryHobGuid ## SOMETIMES_PRODUCES ## HOB + gTcgEvent2EntryHobGuid ## SOMETIMES_PRODUCES ## HOB + gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB + gExcludedFvHobGuid ## SOMETIMES_CONSUMES ## HOB + gPrehashedFvHobGuid ## SOMETIMES_CONSUMES ## HOB + gMeasuredFvHobGuid ## SOMETIMES_PRODUCES ## HOB diff --git a/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.c b/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.c index eda1a8b2fb5..3f006e7e9b7 100644 --- a/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.c +++ b/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.c @@ -1,24 +1,77 @@ /** @file - NULL instance of TPM 2.0 Startup + NULL instance of Tpm2StartupLib. All entry points are no-ops that + return EFI_SUCCESS, for platforms that do not need TPM 2.0 startup + work in a given phase. Copyright (c), Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include +#include #include /** - This function initializes the TPM if required + Null. See Tpm2StartupLib.h. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupInitializeTpm ( + IN BOOLEAN IsS3Resume + ) +{ + (VOID)IsS3Resume; + return EFI_SUCCESS; +} + +/** + Null. See Tpm2StartupLib.h. +**/ +EFI_STATUS +EFIAPI +Tpm2StartupMeasureCoreEvents ( + VOID + ) +{ + return EFI_SUCCESS; +} - @retval EFI_UNSUPPORTED TPM is not supported +/** + Null. See Tpm2StartupLib.h. **/ EFI_STATUS EFIAPI -Tpm2StartupInit ( +Tpm2StartupMeasureFvImage ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + (VOID)FvBase; + (VOID)FvLength; + return EFI_SUCCESS; +} + +/** + Null. See Tpm2StartupLib.h. +**/ +VOID +EFIAPI +Tpm2StartupRecordChildFv ( + IN EFI_PHYSICAL_ADDRESS FvBase, + IN UINT64 FvLength + ) +{ + (VOID)FvBase; + (VOID)FvLength; +} + +/** + Null. See Tpm2StartupLib.h. +**/ +VOID +EFIAPI +Tpm2StartupPublishMeasuredFvHob ( VOID ) { - return EFI_UNSUPPORTED; } diff --git a/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf b/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf index 14f0460a9cd..254b4986247 100644 --- a/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf +++ b/SecurityPkg/Library/Tpm2StartupLibNull/Tpm2StartupLibNull.inf @@ -29,4 +29,3 @@ [LibraryClasses] BaseLib - DebugLib diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec index 249187a5c01..c5907d4697a 100644 --- a/SecurityPkg/SecurityPkg.dec +++ b/SecurityPkg/SecurityPkg.dec @@ -214,6 +214,13 @@ # Include/Guid/ExcludedFvHob.h gExcludedFvHobGuid = { 0xdd55d497, 0x5ed5, 0x403c, { 0x92, 0xb5, 0x70, 0x3a, 0x72, 0x59, 0xae, 0x2a }} + ## MU_CHANGE + ## HOB GUID used to declare pre-hashed FVs to Tpm2StartupLib in either + ## PEI or DXE. Phase-agnostic equivalent of the PEI-only + ## gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid. + # Include/Guid/PrehashedFvHob.h + gPrehashedFvHobGuid = { 0x9d3b7f8a, 0x4c1e, 0x4a2b, { 0x8b, 0x5d, 0x2e, 0x6f, 0x9a, 0x3c, 0x71, 0x0e }} + ## GUID used to "PhysicalPresence" variable and "PhysicalPresenceFlags" variable for TPM request and response. # Include/Guid/PhysicalPresenceData.h gEfiPhysicalPresenceGuid = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }} diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index 600411cbb0a..019eac21fe3 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -42,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include // MU_CHANGE +#include // MU_CHANGE +#include // MU_CHANGE #include #include #include @@ -3224,6 +3226,81 @@ InstallTcg2 ( return Status; } +// MU_CHANGE - [BEGIN] + +/** + Sync PCR-bank state between platform PCDs and the TPM's active banks. + Checks the platform's HashMask and AlgorithmBitmap against the active + PCR banks and either updates the HashMask based on supported hash + algorithms or issues a command to the TPM to update the active PCR + banks to match the platform. If the active PCR banks are updated a + reboot is issued. Must be called from a phase in which dynamic PCD + writes are legal (PEI/DXE). On failure, produces an ERROR HOB so later + phases exit early. + + @retval EFI_SUCCESS Sync completed. + @retval EFI_DEVICE_ERROR A TPM command failed. +**/ +STATIC +EFI_STATUS +SyncPcrAllocationsAndPcrMask ( + VOID + ) +{ + EFI_STATUS Status; + EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; + UINT32 TpmActivePcrBanks; + UINT32 Tpm2PcrMask; + UINT32 NewTpm2PcrMask; + + DEBUG ((DEBUG_INFO, "%a - Entry\n", __func__)); + + Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &TpmActivePcrBanks); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to determine TPM capabilities!\n", __func__)); + ASSERT_EFI_ERROR (Status); + return Status; + } + + DEBUG ((DEBUG_INFO, "TpmHashAlgorithmBitmap: 0x%x, TpmActivePcrBanks: 0x%x\n", TpmHashAlgorithmBitmap, TpmActivePcrBanks)); + + Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask); + if (Tpm2PcrMask == 0) { + PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks); + Tpm2PcrMask = TpmActivePcrBanks; + } + + if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) { + NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap; + DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __func__, Tpm2PcrMask, NewTpm2PcrMask)); + if (NewTpm2PcrMask == 0) { + DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! PcdTpm2HashMask too restrictive.\n", __func__)); + ASSERT (FALSE); + } + + Status = PcdSet32S (PcdTpm2HashMask, NewTpm2PcrMask); + ASSERT_EFI_ERROR (Status); + Tpm2PcrMask = NewTpm2PcrMask; + } + + if ((Tpm2PcrMask != TpmActivePcrBanks) && FixedPcdGetBool (PcdForceReallocatePcrBanks)) { + DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __func__, TpmActivePcrBanks, Tpm2PcrMask)); + Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, Tpm2PcrMask); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n", __func__)); + ASSERT_EFI_ERROR (Status); + } + + ResetCold (); + } + + DEBUG ((DEBUG_INFO, "%a - Exit\n", __func__)); + + return Status; +} + +// MU_CHANGE - [END] + /** The driver's entry point. It publishes EFI Tcg2 Protocol. @@ -3270,6 +3347,14 @@ DriverEntry ( return Status; } + // MU_CHANGE - [BEGIN] + Status = SyncPcrAllocationsAndPcrMask (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask Failed - %r\n", Status)); + return Status; + } + // MU_CHANGE - [END] + // // Fill information // diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf index 98b4921a441..5b7f470bf8d 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf @@ -76,6 +76,7 @@ PanicLib ## MU_CHANGE [END] Tpm2HelpLib # MU_CHANGE + ResetSystemLib # MU_CHANGE [Guids] ## SOMETIMES_CONSUMES ## Variable:L"SecureBoot" @@ -113,6 +114,8 @@ gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass ## SOMETIMES_CONSUMES # gEfiSecurityPkgTokenSpaceGuid.PcdFirmwareDebuggerInitialized ## SOMETIMES_CONSUMES # MU_CHANGE - Remove PCD gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask ## CONSUMES # MU_CHANGE + gEfiSecurityPkgTokenSpaceGuid.PcdForceReallocatePcrBanks ## CONSUMES # MU_CHANGE gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap ## CONSUMES gEfiSecurityPkgTokenSpaceGuid.PcdTcg2NumberOfPCRBanks ## CONSUMES diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c index 0674541f93a..15b7cad8511 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c @@ -20,10 +20,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +// #include // MU_CHANGE #include // MU_CHANGE +#include // MU_CHANGE #include -#include +// #include // MU_CHANGE #include #include @@ -31,30 +32,23 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include // MU_CHANGE -#include +// #include // MU_CHANGE #include #include #include -#include +// #include // MU_CHANGE #include #include -#include +// #include // MU_CHANGE #include -#include -#include +// #include // MU_CHANGE +// #include // MU_CHANGE -// MU_CHANGE_23086 -// MU_CHANGE [BEGIN] - Add the OemTpm2InitLib -#include -// MU_CHANGE [END] -// MU_CHANGE_131467 -// MU_CHANGE [BEGIN] - Move to 256-bit PCRs. -#include -// MU_CHANGE [END] -// MU_CHANGE [BEGIN] - Measure DebugEnabled and Insecure Device State into PCR7 -#include -#include -// MU_CHANGE [END] +// #include // MU_CHANGE +// #include // MU_CHANGE +#include // MU_CHANGE +// #include // MU_CHANGE +// #include // MU_CHANGE typedef struct { EFI_GUID *EventGuid; @@ -123,6 +117,7 @@ EFI_PEI_PPI_DESCRIPTOR mTcgPpiList = { &mEdkiiTcgPpi }; +#if 0 // MU_CHANGE - [BEGIN] // // Number of firmware blobs to grow by each time we run out of room // @@ -147,6 +142,7 @@ typedef struct { } FV_HANDOFF_TABLE_POINTERS2; #pragma pack () +#endif // MU_CHANGE - [END] /** Measure and record the Firmware Volume Information once FvInfoPPI install. @@ -227,6 +223,7 @@ EndofPeiSignalNotifyCallBack ( IN VOID *Ppi ) { +#if 0 // MU_CHANGE - [BEGIN] MEASURED_HOB_DATA *MeasuredHobData; EXCLUDED_HOB_DATA *ExcludedHobData; // MU_CHANGE EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; // MU_CHANGE @@ -238,9 +235,12 @@ EndofPeiSignalNotifyCallBack ( MeasuredHobData = NULL; ExcludedHobData = NULL; // MU_CHANGE MeasurementExcludedFvPpi = NULL; // MU_CHANGE +#endif // MU_CHANGE - [END] PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid); +// MU_CHANGE - [BEGIN] +#if 0 // // Create a Guid hob to save all measured Fv // @@ -265,7 +265,11 @@ EndofPeiSignalNotifyCallBack ( // CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex], mMeasuredChildFvInfo, sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex)); } +#endif + + Tpm2StartupPublishMeasuredFvHob (); +#if 0 // // Create a guid hob to save all excluded FVs for DXE - MU_CHANGE - START // @@ -336,11 +340,13 @@ EndofPeiSignalNotifyCallBack ( } // Done with Excluded Fv Hob // MU_CHANGE - END +#endif // MU_CHANGE - [END] PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid); return EFI_SUCCESS; } +#if 0 // MU_CHANGE - [BEGIN] /** Make sure that the current PCR allocations, the TPM supported PCRs, and the PcdTpm2HashMask are all in agreement. @@ -459,6 +465,7 @@ SyncPcrAllocationsAndPcrMask ( ResetCold (); } } +#endif // MU_CHANGE - [END] /** Add a new entry to the Event Log. @@ -469,6 +476,7 @@ SyncPcrAllocationsAndPcrMask ( @retval EFI_SUCCESS The new event log entry was added. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. + @retval EFI_DEVICE_ERROR TPM communication failed. // MU_CHANGE **/ EFI_STATUS LogHashEvent ( @@ -484,6 +492,17 @@ LogHashEvent ( UINT32 SupportedEventLogs; TCG_PCR_EVENT2 *TcgPcrEvent2; UINT8 *DigestBuffer; + // MU_CHANGE - [BEGIN] + UINT32 TpmHashAlgorithmBitmap; + UINT32 ActivePcrBanks; + + Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to get active PCR banks: %r\n", __func__, Status)); + return EFI_DEVICE_ERROR; + } + + // MU_CHANGE - [END] SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; @@ -528,7 +547,7 @@ LogHashEvent ( TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex; TcgPcrEvent2->EventType = NewEventHdr->EventType; DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest; - DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, PcdGet32 (PcdTpm2HashMask)); + DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, ActivePcrBanks); // MU_CHANGE CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof (TcgPcrEvent2->EventSize)); DigestBuffer = DigestBuffer + sizeof (TcgPcrEvent2->EventSize); CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize); @@ -614,6 +633,7 @@ HashLogExtendEvent ( return Status; } +#if 0 // MU_CHANGE - [BEGIN] /** Measure CRTM version. @@ -1009,6 +1029,7 @@ MeasureMainBios ( return Status; } +#endif // MU_CHANGE - [END] /** Measure and record the Firmware Volume Information once FvInfoPPI install. @@ -1032,7 +1053,7 @@ FirmwareVolumeInfoPpiNotifyCallback ( EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv; EFI_STATUS Status; EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - UINTN Index; + // UINTN Index; // MU_CHANGE Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi; @@ -1049,6 +1070,8 @@ FirmwareVolumeInfoPpiNotifyCallback ( return EFI_SUCCESS; } +// MU_CHANGE - [BEGIN] +#if 0 // // This is an FV from an FFS file, and the parent FV must have already been measured, // No need to measure twice, so just record the FV and return @@ -1080,8 +1103,202 @@ FirmwareVolumeInfoPpiNotifyCallback ( } return MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize); +#endif + + if ((Fv->ParentFvName != NULL) || (Fv->ParentFileName != NULL)) { + Tpm2StartupRecordChildFv ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize); + return EFI_SUCCESS; + } + + return Tpm2StartupMeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize); + // MU_CHANGE [END] +} + +// MU_CHANGE - [BEGIN] +/** + Walk every installed EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI + instance and publish a single gExcludedFvHobGuid HOB containing the union + of their entries. Idempotent: does nothing if the HOB already exists. +**/ +STATIC +VOID +BuildExcludedFvHobFromPpi ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 Instance; + UINT32 Count; + UINT32 HobIndex; + EXCLUDED_HOB_DATA *ExcludedHobData; + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; + + if (GetFirstGuidHob (&gExcludedFvHobGuid) != NULL) { + return; + } + + MeasurementExcludedFvPpi = NULL; + Instance = 0; + Count = 0; + do { + Status = PeiServicesLocatePpi ( + &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, + Instance, + NULL, + (VOID **)&MeasurementExcludedFvPpi + ); + if (!EFI_ERROR (Status)) { + Count += MeasurementExcludedFvPpi->Count; + Instance++; + } + } while (!EFI_ERROR (Status)); + + if (Count == 0) { + return; + } + + DEBUG ((DEBUG_INFO, "Found %d FVs excluded. Publishing hob\n", Count)); + ExcludedHobData = BuildGuidHob ( + &gExcludedFvHobGuid, + sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) + ); + if (ExcludedHobData == NULL) { + DEBUG (( + DEBUG_ERROR, + "Failed to allocate 0x%x byte of memory for ExcludedFvHob", + sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) + )); + return; + } + + ExcludedHobData->Num = Count; + + Instance = 0; + HobIndex = 0; + do { + Status = PeiServicesLocatePpi ( + &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, + Instance, + NULL, + (VOID **)&MeasurementExcludedFvPpi + ); + if (!EFI_ERROR (Status)) { + if (MeasurementExcludedFvPpi->Count <= 0) { + DEBUG ((DEBUG_ERROR, "ExcludedFvPpi has invalid count %d", MeasurementExcludedFvPpi->Count)); + ASSERT (MeasurementExcludedFvPpi->Count > 0); + } else if (HobIndex + MeasurementExcludedFvPpi->Count > Count) { + DEBUG ((DEBUG_ERROR, "Found more ExcludedFvPpi fvs than when calculated buffer size. BufferSizeCount (0x%x) NewCount (0x%x)", Count, (HobIndex + MeasurementExcludedFvPpi->Count))); + ASSERT (HobIndex + MeasurementExcludedFvPpi->Count <= Count); + } else { + CopyMem ( + &ExcludedHobData->ExcludedFvs[HobIndex], + &MeasurementExcludedFvPpi->Fv[0], + sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * MeasurementExcludedFvPpi->Count + ); + HobIndex += MeasurementExcludedFvPpi->Count; + } + + Instance++; + } + } while (!EFI_ERROR (Status)); +} + +/** + Walk every installed gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid + instance and publish one gPrehashedFvHobGuid HOB per FV. The trailing + HASH_INFO records + digest bytes from the PPI are copied verbatim into + the HOB payload (the two layouts are identical past the header). + Idempotent per FV: skips PPIs whose FvBase/FvLength already have a HOB. +**/ +STATIC +VOID +BuildPrehashedFvHobFromPpi ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 Instance; + EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *PrehashedFvPpi; + HASH_INFO *PpiHashInfo; + UINT32 HashIndex; + UINTN TrailingSize; + PREHASHED_FV_HOB *HobHdr; + EFI_HOB_GUID_TYPE *ExistingHob; + PREHASHED_FV_HOB *ExistingHdr; + BOOLEAN AlreadyPresent; + + Instance = 0; + do { + Status = PeiServicesLocatePpi ( + &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid, + Instance, + NULL, + (VOID **)&PrehashedFvPpi + ); + if (EFI_ERROR (Status)) { + break; + } + + Instance++; + + AlreadyPresent = FALSE; + ExistingHob = GetFirstGuidHob (&gPrehashedFvHobGuid); + while (ExistingHob != NULL) { + ExistingHdr = GET_GUID_HOB_DATA (ExistingHob); + if ((ExistingHdr->FvBase == (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase) && + (ExistingHdr->FvLength == (UINT64)PrehashedFvPpi->FvLength)) { + AlreadyPresent = TRUE; + break; + } + + ExistingHob = GetNextGuidHob (&gPrehashedFvHobGuid, GET_NEXT_HOB (ExistingHob)); + } + + if (AlreadyPresent) { + continue; + } + + if (PrehashedFvPpi->Count == 0) { + DEBUG ((DEBUG_WARN, "PrehashedFvPpi[%u] has Count=0; skipping\n", Instance - 1)); + continue; + } + + // + // Sum trailing HASH_INFO + digest bytes to size the HOB. + // + TrailingSize = 0; + PpiHashInfo = (HASH_INFO *)(PrehashedFvPpi + 1); + for (HashIndex = 0; HashIndex < PrehashedFvPpi->Count; HashIndex++) { + TrailingSize += sizeof (HASH_INFO) + PpiHashInfo->HashSize; + PpiHashInfo = (HASH_INFO *)((UINT8 *)(PpiHashInfo + 1) + PpiHashInfo->HashSize); + } + + HobHdr = BuildGuidHob ( + &gPrehashedFvHobGuid, + sizeof (PREHASHED_FV_HOB) + TrailingSize + ); + if (HobHdr == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate PrehashedFvHob (trailing=0x%x)\n", (UINT32)TrailingSize)); + return; + } + + HobHdr->FvBase = (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase; + HobHdr->FvLength = (UINT64)PrehashedFvPpi->FvLength; + HobHdr->Count = PrehashedFvPpi->Count; + CopyMem (HobHdr + 1, PrehashedFvPpi + 1, TrailingSize); + + DEBUG (( + DEBUG_INFO, + "Published PrehashedFvHob: base=0x%lx len=0x%lx count=%u\n", + HobHdr->FvBase, + HobHdr->FvLength, + HobHdr->Count + )); + } while (TRUE); } +// MU_CHANGE [END] + /** Do measurement after memory is ready. @@ -1097,9 +1314,11 @@ PeimEntryMP ( IN EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_PEI_FV_HANDLE VolumeHandle; // MU_CHANGE + EFI_FV_INFO VolumeInfo; // MU_CHANGE - DEVICE_STATE CurrentDeviceState; // MU_CHANGE - Measure Firmware Debugger Enabled + // DEVICE_STATE CurrentDeviceState; // MU_CHANGE // // install Tcg Services @@ -1107,6 +1326,7 @@ PeimEntryMP ( Status = PeiServicesInstallPpi (&mTcgPpiList); ASSERT_EFI_ERROR (Status); +#if 0 // MU_CHANGE - [BEGIN] // MU_CHANGE_103691 // MU_CHANGE [BEGIN] - Add support for measurements extended before Tcg2 stack is available. CreateTcg2PreUefiEventLogEntries (); @@ -1134,6 +1354,24 @@ PeimEntryMP ( if (EFI_ERROR (Status)) { return Status; } +#endif // MU_CHANGE - [END] + + // MU_CHANGE - [BEGIN] + Status = PeiServicesFfsFindNextVolume (0, &VolumeHandle); + ASSERT_EFI_ERROR (Status); + Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo); + ASSERT_EFI_ERROR (Status); + Status = PeiServicesLocatePpi (&VolumeInfo.FvFormat, 0, NULL, NULL); + ASSERT_EFI_ERROR (Status); + + Status = Tpm2StartupMeasureFvImage ( + (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart, + VolumeInfo.FvSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + // MU_CHANGE - [END] // // Post callbacks: @@ -1146,6 +1384,7 @@ PeimEntryMP ( return Status; } +#if 0 // MU_CHANGE - [BEGIN] /** Measure and log Separator event with error, and extend the measurement result into a specific PCR. @@ -1172,6 +1411,7 @@ MeasureSeparatorEventWithError ( TcgEvent.EventSize = (UINT32)sizeof (EventData); return HashLogExtendEvent (&mEdkiiTcgPpi, 0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent, (UINT8 *)&EventData); } +#endif // MU_CHANGE - [END] /** Entry point of this module. @@ -1192,8 +1432,8 @@ PeimEntryMA ( EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; - TPM_PCRINDEX PcrIndex; - BOOLEAN S3ErrorReport; + // TPM_PCRINDEX PcrIndex; // MU_CHANGE + // BOOLEAN S3ErrorReport; // MU_CHANGE if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) @@ -1224,6 +1464,7 @@ PeimEntryMA ( } if (!mImageInMemory) { +#if 0 // MU_CHANGE - [BEGIN] // // Initialize TPM device // @@ -1324,9 +1565,29 @@ PeimEntryMA ( // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); +#endif // MU_CHANGE - [END] + + // MU_CHANGE - [BEGIN] + BuildExcludedFvHobFromPpi (); + BuildPrehashedFvHobFromPpi (); + + Status = Tpm2StartupInitializeTpm (BootMode == BOOT_ON_S3_RESUME); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = Tpm2StartupMeasureCoreEvents (); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); + ASSERT_EFI_ERROR (Status); + // MU_CHANGE - [END] } if (mImageInMemory) { +#if 0 // MU_CHANGE - [BEGIN] // MU_CHANGE_23086 // MU_CHANGE [BEGIN] - Call OEM init hook. Status = OemTpm2InitPeiPreMeasurements (); @@ -1336,6 +1597,7 @@ PeimEntryMA ( } // MU_CHANGE [END] +#endif // MU_CHANGE - [END] Status = PeimEntryMP ((EFI_PEI_SERVICES **)PeiServices); return Status; diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf index b75d4f6eba1..4527f50aa9b 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf @@ -47,36 +47,29 @@ BaseMemoryLib DebugLib Tpm2CommandLib - PeiServicesTablePointerLib - Tpm2DeviceLib +# PeiServicesTablePointerLib # MU_CHANGE +# Tpm2DeviceLib # MU_CHANGE HashLib PerformanceLib - MemoryAllocationLib +# MemoryAllocationLib # MU_CHANGE ReportStatusCodeLib - ResetSystemLib - PrintLib -## MU_CHANGE_23086 -## MU_CHANGE [BEGIN] - Add the OemTpm2InitLib - OemTpm2InitLib -## MU_CHANGE [END] -## MU_CHANGE_103691 -## MU_CHANGE [BEGIN] - Add the Tcg2PreUefiEventLogLib - Tcg2PreUefiEventLogLib -## MU_CHANGE [END] - - ## MU_CHANGE [BEGIN] - Measure Firmware Debugger Enabled - DeviceStateLib - PanicLib - ## MU_CHANGE [END] +# ResetSystemLib # MU_CHANGE +# PrintLib # MU_CHANGE +# OemTpm2InitLib # MU_CHANGE +# Tcg2PreUefiEventLogLib # MU_CHANGE + Tpm2StartupLib # MU_CHANGE +# DeviceStateLib # MU_CHANGE +# PanicLib # MU_CHANGE [Guids] gTcgEventEntryHobGuid ## PRODUCES ## HOB gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB - gMeasuredFvHobGuid ## PRODUCES ## HOB +# gMeasuredFvHobGuid ## PRODUCES ## HOB # MU_CHANGE gExcludedFvHobGuid ## SOMETIMES_PRODUCES ## HOB # MU_CHANGE + gPrehashedFvHobGuid ## SOMETIMES_PRODUCES ## HOB # MU_CHANGE gTcgEvent2EntryHobGuid ## PRODUCES ## HOB gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_PRODUCES ## GUID # TPM device identifier - gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB +# gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB # MU_CHANGE [Ppis] gEfiPeiFirmwareVolumeInfoPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY @@ -89,19 +82,18 @@ gEdkiiTcgPpiGuid ## PRODUCES [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES +# gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## SOMETIMES_CONSUMES # MU_CHANGE +# gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES # MU_CHANGE gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy ## SOMETIMES_CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy ## CONSUMES +# gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES # MU_CHANGE +# gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy ## SOMETIMES_CONSUMES # MU_CHANGE +# gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy ## CONSUMES # MU_CHANGE gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES ## SOMETIMES_CONSUMES ## SOMETIMES_PRODUCES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask - gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap ## CONSUMES - ## MU_CHANGE - Update PCR order, add PCD, enable deallocate *and* allocate. - gEfiSecurityPkgTokenSpaceGuid.PcdForceReallocatePcrBanks ## CONSUMES +# gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask # MU_CHANGE +# gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap ## CONSUMES # MU_CHANGE +# gEfiSecurityPkgTokenSpaceGuid.PcdForceReallocatePcrBanks ## CONSUMES # MU_CHANGE [Depex] gEfiPeiMasterBootModePpiGuid From 78e5a890e44f6c2c391f5841dda9b3bde8a6a811 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 27 Jul 2026 22:31:48 +0000 Subject: [PATCH 03/11] Added a default value for PcdDeviceStateBitmask --- MdeModulePkg/MdeModulePkg.dsc | 1 + SecurityPkg/SecurityPkg.dsc | 1 + 2 files changed, 2 insertions(+) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index a3227d41f84..084179068c0 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -232,6 +232,7 @@ [PcdsDynamicExDefault] gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"FVMAIN.FV" + gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask|0x00000000 ## MU_CHANGE [Components] MdeModulePkg/Application/HelloWorld/HelloWorld.inf diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 9029fa7a821..ea55ac794b8 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -199,6 +199,7 @@ gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1 gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|3 gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|3 + gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask|0x00000000 ## MU_CHANGE [PcdsDynamicHii.common.DEFAULT] gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS From ed9cf70feece4358e525a8200ebce713a82da8d1 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 27 Jul 2026 23:05:37 +0000 Subject: [PATCH 04/11] Updated line endings. --- .../DeviceStateLib/DeviceStateLibFixed.c | 66 ++++++++--------- .../DeviceStateLib/DeviceStateLibFixed.inf | 72 +++++++++---------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c index aa2fe2e6a2a..ee7c2233746 100644 --- a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c +++ b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.c @@ -1,33 +1,33 @@ -/** @file - Read-only DeviceStateLib for platforms that pin PcdDeviceStateBitmask as - FixedAtBuild. GetDeviceState returns the compile-time value; AddDeviceState - is unsupported (Fixed PCDs cannot be updated). - - Copyright (C) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - -#include -#include -#include -#include - -DEVICE_STATE -EFIAPI -GetDeviceState ( - VOID - ) -{ - return (DEVICE_STATE)FixedPcdGet32 (PcdDeviceStateBitmask); -} - -RETURN_STATUS -EFIAPI -AddDeviceState ( - DEVICE_STATE AdditionalState - ) -{ - (VOID)AdditionalState; - DEBUG ((DEBUG_WARN, "%a: AddDeviceState is unsupported when PcdDeviceStateBitmask is FixedAtBuild\n", __func__)); - return RETURN_UNSUPPORTED; -} +/** @file + Read-only DeviceStateLib for platforms that pin PcdDeviceStateBitmask as + FixedAtBuild. GetDeviceState returns the compile-time value; AddDeviceState + is unsupported (Fixed PCDs cannot be updated). + + Copyright (C) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +DEVICE_STATE +EFIAPI +GetDeviceState ( + VOID + ) +{ + return (DEVICE_STATE)FixedPcdGet32 (PcdDeviceStateBitmask); +} + +RETURN_STATUS +EFIAPI +AddDeviceState ( + DEVICE_STATE AdditionalState + ) +{ + (VOID)AdditionalState; + DEBUG ((DEBUG_WARN, "%a: AddDeviceState is unsupported when PcdDeviceStateBitmask is FixedAtBuild\n", __func__)); + return RETURN_UNSUPPORTED; +} diff --git a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf index cf60903d29b..b9441218190 100644 --- a/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf +++ b/MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf @@ -1,36 +1,36 @@ -## @file -# Read-only DeviceStateLib variant for platforms that resolve -# PcdDeviceStateBitmask as FixedAtBuild. -# -# Peiless SEC platforms (e.g. QemuArmVirtPkg) have no dynamic PCD store, -# so the PCD must be Fixed. PcdSet32S is not legal on a Fixed PCD, so this -# variant omits the write path from AddDeviceState. The read path is -# preserved so consumers such as Tpm2StartupLib continue to see the -# platform's build-time device state and emit the appropriate PCR -# measurements. -# -# Copyright (C) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -## - -[Defines] -INF_VERSION = 0x00010017 -BASE_NAME = DeviceStateLibFixed -FILE_GUID = 6c7b1d1a-9c8e-4c2f-8b3a-1e5f2a7d4c60 -VERSION_STRING = 1.0 -MODULE_TYPE = BASE -LIBRARY_CLASS = DeviceStateLib - -[LibraryClasses] -DebugLib -PcdLib - -[Packages] -MdePkg/MdePkg.dec -MdeModulePkg/MdeModulePkg.dec - -[Sources] -DeviceStateLibFixed.c - -[FixedPcd] -gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask +## @file +# Read-only DeviceStateLib variant for platforms that resolve +# PcdDeviceStateBitmask as FixedAtBuild. +# +# Peiless SEC platforms (e.g. QemuArmVirtPkg) have no dynamic PCD store, +# so the PCD must be Fixed. PcdSet32S is not legal on a Fixed PCD, so this +# variant omits the write path from AddDeviceState. The read path is +# preserved so consumers such as Tpm2StartupLib continue to see the +# platform's build-time device state and emit the appropriate PCR +# measurements. +# +# Copyright (C) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = DeviceStateLibFixed +FILE_GUID = 6c7b1d1a-9c8e-4c2f-8b3a-1e5f2a7d4c60 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = DeviceStateLib + +[LibraryClasses] +DebugLib +PcdLib + +[Packages] +MdePkg/MdePkg.dec +MdeModulePkg/MdeModulePkg.dec + +[Sources] +DeviceStateLibFixed.c + +[FixedPcd] +gEfiMdeModulePkgTokenSpaceGuid.PcdDeviceStateBitmask From f00ecdfa18fc0fc8ac9e40ecb2eaed6fa506e2eb Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 27 Jul 2026 23:55:00 +0000 Subject: [PATCH 05/11] Add missing DeviceStateLibFixed.inf to MdeModulePkg.dsc. --- MdeModulePkg/MdeModulePkg.dsc | 1 + 1 file changed, 1 insertion(+) diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 084179068c0..0a78a2b84cb 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -505,6 +505,7 @@ MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf # MU_CHANGE - Add DeviceStateLib to MdeModulePkg: MdeModulePkg/Library/DeviceStateLib/DeviceStateLib.inf + MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf # MU_CHANGE MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf MdeModulePkg/Library/PcdDatabaseLoaderLib/Pei/PcdDatabaseLoaderLibPei.inf # MU_CHANGE MdeModulePkg/Library/PcdDatabaseLoaderLib/Dxe/PcdDatabaseLoaderLibDxe.inf # MU_CHANGE From e2f683eea28d7a699a63b2b726cc14705e74699d Mon Sep 17 00:00:00 2001 From: rdiaz Date: Tue, 28 Jul 2026 00:05:27 +0000 Subject: [PATCH 06/11] Adding DeviceStateLibFixed.inf to the IgnoreInf section of MdeModukePkg CI. It is unable to be built alongside the dynamic version. --- MdeModulePkg/MdeModulePkg.ci.yaml | 9 ++++++++- MdeModulePkg/MdeModulePkg.dsc | 1 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml index 4a2acc23a55..f93c44b82a9 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -74,7 +74,14 @@ ## options defined .pytool/Plugin/DscCompleteCheck "DscCompleteCheck": { - "IgnoreInf": [], + "IgnoreInf": [ + # MU_CHANGE + # DeviceStateLibFixed.inf uses FixedPcd(PcdDeviceStateBitmask) and can + # only be built in a DSC that sets it as FixedAtBuild. MdeModulePkg.dsc + # declares it as DynamicEx to support the writeable DeviceStateLib.inf, so + # the Fixed variant cannot be built here. + "MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf" + ], "DscPath": "MdeModulePkg.dsc" }, ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 0a78a2b84cb..084179068c0 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -505,7 +505,6 @@ MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf # MU_CHANGE - Add DeviceStateLib to MdeModulePkg: MdeModulePkg/Library/DeviceStateLib/DeviceStateLib.inf - MdeModulePkg/Library/DeviceStateLib/DeviceStateLibFixed.inf # MU_CHANGE MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf MdeModulePkg/Library/PcdDatabaseLoaderLib/Pei/PcdDatabaseLoaderLibPei.inf # MU_CHANGE MdeModulePkg/Library/PcdDatabaseLoaderLib/Dxe/PcdDatabaseLoaderLibDxe.inf # MU_CHANGE From d8de0b27013c8dc0448818186dd7a35e4312d20e Mon Sep 17 00:00:00 2001 From: rdiaz Date: Tue, 28 Jul 2026 00:35:57 +0000 Subject: [PATCH 07/11] Ran Uncrustify. --- SecurityPkg/Include/Guid/PrehashedFvHob.h | 78 +++++++++---------- .../HashLibTpm2/HashLibTpm2PeilessSecLib.c | 1 + .../Library/Tpm2StartupLib/Tpm2StartupLib.c | 9 ++- SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c | 3 +- SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 65 +++++++++------- 5 files changed, 87 insertions(+), 69 deletions(-) diff --git a/SecurityPkg/Include/Guid/PrehashedFvHob.h b/SecurityPkg/Include/Guid/PrehashedFvHob.h index 18e5704e32f..753e3f3d879 100644 --- a/SecurityPkg/Include/Guid/PrehashedFvHob.h +++ b/SecurityPkg/Include/Guid/PrehashedFvHob.h @@ -1,39 +1,39 @@ -/** @file - HOB used to declare pre-hashed firmware volumes to Tpm2StartupLib - (or any consumer that needs to know a FV's digests without hashing it). - - This is the phase-agnostic equivalent of - gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid. Producers include: - - Tcg2Pei, which translates the PPI to this HOB early in its flow so - the consolidated Tpm2StartupLib can find pre-hashed FVs without - depending on PEI services. - - PEI-less platforms (SEC / early DXE), which can BuildGuidHob directly - when they have pre-computed FV digests (typically obtained from a - prior firmware stage such as TF-A). - - One HOB is produced per pre-hashed FV. The HOB payload begins with a - PREHASHED_FV_HOB header identifying the FV, immediately followed by - Count HASH_INFO records; each HASH_INFO is followed inline by its - digest bytes (HashSize bytes). This mirrors the PPI payload layout to - keep any PPI-to-HOB translator trivial. - - Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef PREHASHED_FV_HOB_H_ -#define PREHASHED_FV_HOB_H_ - -#include - -extern EFI_GUID gPrehashedFvHobGuid; - -typedef struct { - EFI_PHYSICAL_ADDRESS FvBase; - UINT64 FvLength; - UINT32 Count; - // HASH_INFO HashInfo[]; each followed inline by HashSize bytes of digest -} PREHASHED_FV_HOB; - -#endif +/** @file + HOB used to declare pre-hashed firmware volumes to Tpm2StartupLib + (or any consumer that needs to know a FV's digests without hashing it). + + This is the phase-agnostic equivalent of + gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid. Producers include: + - Tcg2Pei, which translates the PPI to this HOB early in its flow so + the consolidated Tpm2StartupLib can find pre-hashed FVs without + depending on PEI services. + - PEI-less platforms (SEC / early DXE), which can BuildGuidHob directly + when they have pre-computed FV digests (typically obtained from a + prior firmware stage such as TF-A). + + One HOB is produced per pre-hashed FV. The HOB payload begins with a + PREHASHED_FV_HOB header identifying the FV, immediately followed by + Count HASH_INFO records; each HASH_INFO is followed inline by its + digest bytes (HashSize bytes). This mirrors the PPI payload layout to + keep any PPI-to-HOB translator trivial. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PREHASHED_FV_HOB_H_ +#define PREHASHED_FV_HOB_H_ + +#include + +extern EFI_GUID gPrehashedFvHobGuid; + +typedef struct { + EFI_PHYSICAL_ADDRESS FvBase; + UINT64 FvLength; + UINT32 Count; + // HASH_INFO HashInfo[]; each followed inline by HashSize bytes of digest +} PREHASHED_FV_HOB; + +#endif diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c index 44a97cedd14..74ef0d7133d 100644 --- a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c +++ b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2PeilessSecLib.c @@ -88,6 +88,7 @@ GetTransferList ( return EFI_SUCCESS; } + #endif /** diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c index 2365c408593..476da15391d 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c @@ -118,7 +118,8 @@ Tpm2StartupCheckPrereqs ( EFI_STATUS Status; if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || - CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) { + CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) + { DEBUG ((DEBUG_INFO, "%a - No TPM2 instance required.\n", __func__)); return EFI_UNSUPPORTED; } @@ -163,7 +164,8 @@ IsFvMeasurementExcluded ( ExcludedHobData = GET_GUID_HOB_DATA (GuidHob); for (Index = 0; Index < ExcludedHobData->Num; Index++) { if ((ExcludedHobData->ExcludedFvs[Index].FvBase == FvBase) && - (ExcludedHobData->ExcludedFvs[Index].FvLength == FvLength)) { + (ExcludedHobData->ExcludedFvs[Index].FvLength == FvLength)) + { return TRUE; } } @@ -492,7 +494,8 @@ GetFvName ( if ((FvBase >= MAX_ADDRESS) || (FvLength >= MAX_ADDRESS - FvBase) || - (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER))) { + (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER))) + { return NULL; } diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index 019eac21fe3..ef15261d843 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -41,7 +41,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include // MU_CHANGE +#include // MU_CHANGE #include // MU_CHANGE #include // MU_CHANGE #include @@ -3353,6 +3353,7 @@ DriverEntry ( DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask Failed - %r\n", Status)); return Status; } + // MU_CHANGE - [END] // diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c index 15b7cad8511..64f3ab3967d 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c @@ -21,7 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include // #include // MU_CHANGE -#include // MU_CHANGE +#include // MU_CHANGE #include // MU_CHANGE #include // #include // MU_CHANGE @@ -131,7 +131,7 @@ EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo; UINT32 mMeasuredMaxChildFvIndex = 0; UINT32 mMeasuredChildFvIndex = 0; -#pragma pack (1) + #pragma pack (1) #define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)" typedef struct { @@ -141,7 +141,7 @@ typedef struct { UINT64 BlobLength; } FV_HANDOFF_TABLE_POINTERS2; -#pragma pack () + #pragma pack () #endif // MU_CHANGE - [END] /** @@ -223,7 +223,7 @@ EndofPeiSignalNotifyCallBack ( IN VOID *Ppi ) { -#if 0 // MU_CHANGE - [BEGIN] + #if 0 // MU_CHANGE - [BEGIN] MEASURED_HOB_DATA *MeasuredHobData; EXCLUDED_HOB_DATA *ExcludedHobData; // MU_CHANGE EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; // MU_CHANGE @@ -235,12 +235,12 @@ EndofPeiSignalNotifyCallBack ( MeasuredHobData = NULL; ExcludedHobData = NULL; // MU_CHANGE MeasurementExcludedFvPpi = NULL; // MU_CHANGE -#endif // MU_CHANGE - [END] + #endif // MU_CHANGE - [END] PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid); -// MU_CHANGE - [BEGIN] -#if 0 + // MU_CHANGE - [BEGIN] + #if 0 // // Create a Guid hob to save all measured Fv // @@ -265,11 +265,12 @@ EndofPeiSignalNotifyCallBack ( // CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex], mMeasuredChildFvInfo, sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex)); } -#endif + + #endif Tpm2StartupPublishMeasuredFvHob (); -#if 0 + #if 0 // // Create a guid hob to save all excluded FVs for DXE - MU_CHANGE - START // @@ -340,13 +341,14 @@ EndofPeiSignalNotifyCallBack ( } // Done with Excluded Fv Hob // MU_CHANGE - END -#endif // MU_CHANGE - [END] + #endif // MU_CHANGE - [END] PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid); return EFI_SUCCESS; } #if 0 // MU_CHANGE - [BEGIN] + /** Make sure that the current PCR allocations, the TPM supported PCRs, and the PcdTpm2HashMask are all in agreement. @@ -465,6 +467,7 @@ SyncPcrAllocationsAndPcrMask ( ResetCold (); } } + #endif // MU_CHANGE - [END] /** @@ -493,8 +496,8 @@ LogHashEvent ( TCG_PCR_EVENT2 *TcgPcrEvent2; UINT8 *DigestBuffer; // MU_CHANGE - [BEGIN] - UINT32 TpmHashAlgorithmBitmap; - UINT32 ActivePcrBanks; + UINT32 TpmHashAlgorithmBitmap; + UINT32 ActivePcrBanks; Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks); if (EFI_ERROR (Status)) { @@ -634,6 +637,7 @@ HashLogExtendEvent ( } #if 0 // MU_CHANGE - [BEGIN] + /** Measure CRTM version. @@ -1029,6 +1033,7 @@ MeasureMainBios ( return Status; } + #endif // MU_CHANGE - [END] /** @@ -1053,6 +1058,7 @@ FirmwareVolumeInfoPpiNotifyCallback ( EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv; EFI_STATUS Status; EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; + // UINTN Index; // MU_CHANGE Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi; @@ -1070,8 +1076,8 @@ FirmwareVolumeInfoPpiNotifyCallback ( return EFI_SUCCESS; } -// MU_CHANGE - [BEGIN] -#if 0 + // MU_CHANGE - [BEGIN] + #if 0 // // This is an FV from an FFS file, and the parent FV must have already been measured, // No need to measure twice, so just record the FV and return @@ -1103,7 +1109,7 @@ FirmwareVolumeInfoPpiNotifyCallback ( } return MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize); -#endif + #endif if ((Fv->ParentFvName != NULL) || (Fv->ParentFileName != NULL)) { Tpm2StartupRecordChildFv ((EFI_PHYSICAL_ADDRESS)(UINTN)Fv->FvInfo, Fv->FvInfoSize); @@ -1115,6 +1121,7 @@ FirmwareVolumeInfoPpiNotifyCallback ( } // MU_CHANGE - [BEGIN] + /** Walk every installed EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI instance and publish a single gExcludedFvHobGuid HOB containing the union @@ -1246,7 +1253,8 @@ BuildPrehashedFvHobFromPpi ( while (ExistingHob != NULL) { ExistingHdr = GET_GUID_HOB_DATA (ExistingHob); if ((ExistingHdr->FvBase == (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase) && - (ExistingHdr->FvLength == (UINT64)PrehashedFvPpi->FvLength)) { + (ExistingHdr->FvLength == (UINT64)PrehashedFvPpi->FvLength)) + { AlreadyPresent = TRUE; break; } @@ -1316,7 +1324,7 @@ PeimEntryMP ( { EFI_STATUS Status; EFI_PEI_FV_HANDLE VolumeHandle; // MU_CHANGE - EFI_FV_INFO VolumeInfo; // MU_CHANGE + EFI_FV_INFO VolumeInfo; // MU_CHANGE // DEVICE_STATE CurrentDeviceState; // MU_CHANGE @@ -1326,7 +1334,7 @@ PeimEntryMP ( Status = PeiServicesInstallPpi (&mTcgPpiList); ASSERT_EFI_ERROR (Status); -#if 0 // MU_CHANGE - [BEGIN] + #if 0 // MU_CHANGE - [BEGIN] // MU_CHANGE_103691 // MU_CHANGE [BEGIN] - Add support for measurements extended before Tcg2 stack is available. CreateTcg2PreUefiEventLogEntries (); @@ -1354,7 +1362,8 @@ PeimEntryMP ( if (EFI_ERROR (Status)) { return Status; } -#endif // MU_CHANGE - [END] + + #endif // MU_CHANGE - [END] // MU_CHANGE - [BEGIN] Status = PeiServicesFfsFindNextVolume (0, &VolumeHandle); @@ -1365,12 +1374,13 @@ PeimEntryMP ( ASSERT_EFI_ERROR (Status); Status = Tpm2StartupMeasureFvImage ( - (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart, - VolumeInfo.FvSize - ); + (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart, + VolumeInfo.FvSize + ); if (EFI_ERROR (Status)) { return Status; } + // MU_CHANGE - [END] // @@ -1385,6 +1395,7 @@ PeimEntryMP ( } #if 0 // MU_CHANGE - [BEGIN] + /** Measure and log Separator event with error, and extend the measurement result into a specific PCR. @@ -1411,6 +1422,7 @@ MeasureSeparatorEventWithError ( TcgEvent.EventSize = (UINT32)sizeof (EventData); return HashLogExtendEvent (&mEdkiiTcgPpi, 0, (UINT8 *)&EventData, TcgEvent.EventSize, &TcgEvent, (UINT8 *)&EventData); } + #endif // MU_CHANGE - [END] /** @@ -1432,6 +1444,7 @@ PeimEntryMA ( EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; + // TPM_PCRINDEX PcrIndex; // MU_CHANGE // BOOLEAN S3ErrorReport; // MU_CHANGE @@ -1464,7 +1477,7 @@ PeimEntryMA ( } if (!mImageInMemory) { -#if 0 // MU_CHANGE - [BEGIN] + #if 0 // MU_CHANGE - [BEGIN] // // Initialize TPM device // @@ -1565,7 +1578,7 @@ PeimEntryMA ( // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); -#endif // MU_CHANGE - [END] + #endif // MU_CHANGE - [END] // MU_CHANGE - [BEGIN] BuildExcludedFvHobFromPpi (); @@ -1587,7 +1600,7 @@ PeimEntryMA ( } if (mImageInMemory) { -#if 0 // MU_CHANGE - [BEGIN] + #if 0 // MU_CHANGE - [BEGIN] // MU_CHANGE_23086 // MU_CHANGE [BEGIN] - Call OEM init hook. Status = OemTpm2InitPeiPreMeasurements (); @@ -1597,7 +1610,7 @@ PeimEntryMA ( } // MU_CHANGE [END] -#endif // MU_CHANGE - [END] + #endif // MU_CHANGE - [END] Status = PeimEntryMP ((EFI_PEI_SERVICES **)PeiServices); return Status; From 25c82dac1ebe888480cd53913417e348089b0dee Mon Sep 17 00:00:00 2001 From: rdiaz Date: Tue, 28 Jul 2026 00:54:04 +0000 Subject: [PATCH 08/11] Correct line endings to Tpm2StartupLib.inf. --- .../Library/Tpm2StartupLib/Tpm2StartupLib.inf | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf index a5a11b17ad1..c7ba8d82631 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.inf @@ -1,67 +1,67 @@ -## @file -# Handles TPM 2.0 startup and initialization. -# -# A single library instance consolidates the TPM startup and pre-DXE -# measurement work that previously lived in PEI so it can be driven -# from either PEI or from SEC on PEI-less platforms. -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Tpm2StartupLib - FILE_GUID = 2066F14F-6CBB-44D2-A619-4100AADDD2E4 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = Tpm2StartupLib - -# -# VALID_ARCHITECTURES = IA32 X64 AARCH64 -# - -[Sources] - Tpm2StartupLib.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - SecurityPkg/SecurityPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DeviceStateLib - HashLib - HobLib - OemTpm2InitLib - PcdLib - PrintLib - ReportStatusCodeLib - Tcg2PreUefiEventLogLib - Tpm2CommandLib - Tpm2DeviceLib - Tpm2HelpLib - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy ## CONSUMES - gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES - -[Guids] - gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB - gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID - gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_CONSUMES ## GUID - gTcgEventEntryHobGuid ## SOMETIMES_PRODUCES ## HOB - gTcgEvent2EntryHobGuid ## SOMETIMES_PRODUCES ## HOB - gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB - gExcludedFvHobGuid ## SOMETIMES_CONSUMES ## HOB - gPrehashedFvHobGuid ## SOMETIMES_CONSUMES ## HOB - gMeasuredFvHobGuid ## SOMETIMES_PRODUCES ## HOB +## @file +# Handles TPM 2.0 startup and initialization. +# +# A single library instance consolidates the TPM startup and pre-DXE +# measurement work that previously lived in PEI so it can be driven +# from either PEI or from SEC on PEI-less platforms. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Tpm2StartupLib + FILE_GUID = 2066F14F-6CBB-44D2-A619-4100AADDD2E4 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = Tpm2StartupLib + +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + Tpm2StartupLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DeviceStateLib + HashLib + HobLib + OemTpm2InitLib + PcdLib + PrintLib + ReportStatusCodeLib + Tcg2PreUefiEventLogLib + Tpm2CommandLib + Tpm2DeviceLib + Tpm2HelpLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2SelfTestPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy ## CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdStatusCodeSubClassTpmDevice ## SOMETIMES_CONSUMES + +[Guids] + gTpmErrorHobGuid ## SOMETIMES_PRODUCES ## HOB + gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_PRODUCES ## GUID + gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_CONSUMES ## GUID + gTcgEventEntryHobGuid ## SOMETIMES_PRODUCES ## HOB + gTcgEvent2EntryHobGuid ## SOMETIMES_PRODUCES ## HOB + gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB + gExcludedFvHobGuid ## SOMETIMES_CONSUMES ## HOB + gPrehashedFvHobGuid ## SOMETIMES_CONSUMES ## HOB + gMeasuredFvHobGuid ## SOMETIMES_PRODUCES ## HOB From a44adcaba8d63c7168b633f848505f72d27863a4 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Wed, 29 Jul 2026 20:55:41 +0000 Subject: [PATCH 09/11] Addressed review feedback. --- .../Library/Tpm2StartupLib/Tpm2StartupLib.c | 62 +++++++++++++++---- SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c | 1 + SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 8 +-- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c index 476da15391d..4a26b6e800c 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c @@ -199,31 +199,69 @@ GetPrehashedFvDigests ( ) { EFI_HOB_GUID_TYPE *GuidHob; - PREHASHED_FV_HOB *Hdr; + PREHASHED_FV_HOB *FvHob; HASH_INFO *PreHashInfo; + UINT8 *HashInfoBuffer; + UINTN HashInfoBufferSize; + UINTN HobDataSize; UINT32 HashAlgoMask; + UINT32 RemainingMask; UINT32 Index; UINT32 DigestCount; + UINT16 HashAlgoId; + UINT16 HashSize; GuidHob = GetFirstGuidHob (&gPrehashedFvHobGuid); while (GuidHob != NULL) { - Hdr = GET_GUID_HOB_DATA (GuidHob); - if ((Hdr->FvBase == FvBase) && (Hdr->FvLength == FvLength)) { - PreHashInfo = (HASH_INFO *)(Hdr + 1); - DigestCount = 0; - for (Index = 0; Index < Hdr->Count; Index++) { - HashAlgoMask = GetHashMaskFromAlgo (PreHashInfo->HashAlgoId); - if ((*RemainingTpm2HashMask & HashAlgoMask) != 0) { - WriteUnaligned16 (&(DigestList->digests[DigestCount].hashAlg), PreHashInfo->HashAlgoId); - CopyMem (&DigestList->digests[DigestCount].digest, PreHashInfo + 1, PreHashInfo->HashSize); + FvHob = GET_GUID_HOB_DATA (GuidHob); + // Only continue if the current FV matches the FV being requested. + if ((FvHob->FvBase == FvBase) && (FvHob->FvLength == FvLength)) { + // Verify the HobDataSize matches what is expected. + HobDataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + if (HobDataSize < sizeof (PREHASHED_FV_HOB)) { + return EFI_NOT_FOUND; + } + + HashInfoBuffer = (UINT8 *)(FvHob + 1); + HashInfoBufferSize = HobDataSize - sizeof (PREHASHED_FV_HOB); + RemainingMask = *RemainingTpm2HashMask; + DigestCount = 0; + for (Index = 0; Index < FvHob->Count; Index++) { + // Verify that HashInfoBufferSize contains at least HASH_INFO. + if (HashInfoBufferSize < sizeof (HASH_INFO)) { + return EFI_NOT_FOUND; + } + + PreHashInfo = (HASH_INFO *)HashInfoBuffer; + HashAlgoId = ReadUnaligned16 (&PreHashInfo->HashAlgoId); + HashSize = ReadUnaligned16 (&PreHashInfo->HashSize); + // Validate HashSize fits within the digest and that HashInfoBufferSize + // is sufficiently large enough to contain HashSize. + if ((HashSize > sizeof (DigestList->digests[0].digest)) || + (HashInfoBufferSize - sizeof (HASH_INFO) < HashSize)) + { + return EFI_NOT_FOUND; + } + + // Only copy data from hash algorithms requested via RemainingTpm2HashMask. + HashAlgoMask = GetHashMaskFromAlgo (HashAlgoId); + if ((RemainingMask & HashAlgoMask) != 0) { + if (DigestCount >= HASH_COUNT) { + return EFI_NOT_FOUND; + } + + WriteUnaligned16 (&(DigestList->digests[DigestCount].hashAlg), HashAlgoId); + CopyMem (&DigestList->digests[DigestCount].digest, PreHashInfo + 1, HashSize); DigestCount++; - *RemainingTpm2HashMask &= ~HashAlgoMask; + RemainingMask &= ~HashAlgoMask; } - PreHashInfo = (HASH_INFO *)((UINT8 *)(PreHashInfo + 1) + PreHashInfo->HashSize); + HashInfoBuffer += sizeof (HASH_INFO) + HashSize; + HashInfoBufferSize -= sizeof (HASH_INFO) + HashSize; } WriteUnaligned32 (&DigestList->count, DigestCount); + *RemainingTpm2HashMask = RemainingMask; return EFI_SUCCESS; } diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index ef15261d843..80498c1791b 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -3289,6 +3289,7 @@ SyncPcrAllocationsAndPcrMask ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n", __func__)); ASSERT_EFI_ERROR (Status); + return Status; } ResetCold (); diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c index 64f3ab3967d..772f89ab88b 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c @@ -1172,7 +1172,7 @@ BuildExcludedFvHobFromPpi ( if (ExcludedHobData == NULL) { DEBUG (( DEBUG_ERROR, - "Failed to allocate 0x%x byte of memory for ExcludedFvHob", + "Failed to allocate 0x%x byte of memory for ExcludedFvHob\n", sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) )); return; @@ -1190,11 +1190,11 @@ BuildExcludedFvHobFromPpi ( (VOID **)&MeasurementExcludedFvPpi ); if (!EFI_ERROR (Status)) { - if (MeasurementExcludedFvPpi->Count <= 0) { - DEBUG ((DEBUG_ERROR, "ExcludedFvPpi has invalid count %d", MeasurementExcludedFvPpi->Count)); + if (MeasurementExcludedFvPpi->Count == 0) { + DEBUG ((DEBUG_ERROR, "ExcludedFvPpi has invalid count %d\n", MeasurementExcludedFvPpi->Count)); ASSERT (MeasurementExcludedFvPpi->Count > 0); } else if (HobIndex + MeasurementExcludedFvPpi->Count > Count) { - DEBUG ((DEBUG_ERROR, "Found more ExcludedFvPpi fvs than when calculated buffer size. BufferSizeCount (0x%x) NewCount (0x%x)", Count, (HobIndex + MeasurementExcludedFvPpi->Count))); + DEBUG ((DEBUG_ERROR, "Found more ExcludedFvPpi fvs than when calculated buffer size. BufferSizeCount (0x%x) NewCount (0x%x)\n", Count, (HobIndex + MeasurementExcludedFvPpi->Count))); ASSERT (HobIndex + MeasurementExcludedFvPpi->Count <= Count); } else { CopyMem ( From bcbe7653c193b782ffc9a6be9a35aa8f7ac82837 Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 31 Aug 2026 20:00:23 -0700 Subject: [PATCH 10/11] Addressed review feedback/comments --- ArmPlatformPkg/PeilessSec/PeilessSec.c | 4 +- ArmPlatformPkg/PeilessSec/PeilessSec.h | 2 +- .../Library/Tpm2StartupLib/Tpm2StartupLib.c | 12 +- SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 459 +++++------------- SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf | 4 +- 5 files changed, 130 insertions(+), 351 deletions(-) diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c index b7659d9c7e8..f2e9dc7b331 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.c +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c @@ -212,6 +212,8 @@ SecMain ( DecompressFvs (); // MU_CHANGE - [BEGIN] + // Status = MeasurePeilessSec (); + // ASSERT_EFI_ERROR (Status); Status = Tpm2StartupInitializeTpm (FALSE); if (!EFI_ERROR (Status)) { @@ -236,7 +238,7 @@ SecMain ( Tpm2StartupPublishMeasuredFvHob (); } else if (Status != EFI_UNSUPPORTED) { DEBUG ((DEBUG_ERROR, "%a: Tpm2StartupInitializeTpm failed: %r\n", __func__, Status)); - ASSERT_EFI_ERROR (FALSE); + ASSERT_EFI_ERROR (Status); } // MU_CHANGE - [END] diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.h b/ArmPlatformPkg/PeilessSec/PeilessSec.h index 9e289625c10..5389a15f388 100644 --- a/ArmPlatformPkg/PeilessSec/PeilessSec.h +++ b/ArmPlatformPkg/PeilessSec/PeilessSec.h @@ -19,7 +19,7 @@ #include #include #include -#include +// #include // MU_CHANGE #include #include #include diff --git a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c index 4a26b6e800c..cbbac82a68c 100644 --- a/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c +++ b/SecurityPkg/Library/Tpm2StartupLib/Tpm2StartupLib.c @@ -296,7 +296,6 @@ LogHashEvent ( EFI_STATUS Status; UINTN Index; EFI_STATUS RetStatus; - UINT32 SupportedEventLogs; TCG_PCR_EVENT2 *TcgPcrEvent2; UINT8 *DigestBuffer; UINT32 HashAlgorithmBitmap; @@ -307,14 +306,9 @@ LogHashEvent ( return EFI_DEVICE_ERROR; } - SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; - RetStatus = EFI_SUCCESS; - - for (Index = 0; Index < sizeof (mTcg2EventInfo) / sizeof (mTcg2EventInfo[0]); Index++) { - if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) == 0) { - continue; - } + RetStatus = EFI_SUCCESS; + for (Index = 0; Index < ARRAY_SIZE (mTcg2EventInfo); Index++) { switch (mTcg2EventInfo[Index].LogFormat) { case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest); @@ -960,7 +954,7 @@ Tpm2StartupPublishMeasuredFvHob ( MeasuredHobData = BuildGuidHob ( &gMeasuredFvHobGuid, - sizeof (UINTN) + sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * Count + OFFSET_OF (MEASURED_HOB_DATA, MeasuredFvBuf) + sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * Count ); if (MeasuredHobData == NULL) { DEBUG ((DEBUG_ERROR, "%a - Failed to allocate MeasuredFvHob\n", __func__)); diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c index 772f89ab88b..52a93284750 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c @@ -44,11 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // #include // MU_CHANGE // #include // MU_CHANGE -// #include // MU_CHANGE -// #include // MU_CHANGE #include // MU_CHANGE -// #include // MU_CHANGE -// #include // MU_CHANGE typedef struct { EFI_GUID *EventGuid; @@ -182,7 +178,44 @@ EndofPeiSignalNotifyCallBack ( IN VOID *Ppi ); +// MU_CHANGE - [BEGIN] + +/** + Publish a gExcludedFvHobGuid HOB for the + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI. +**/ +EFI_STATUS +EFIAPI +ExcludedFvPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** + Publish a gPrehashedFvHobGuid HOB for the + EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI. +**/ +EFI_STATUS +EFIAPI +PrehashedFvPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, + ExcludedFvPpiNotifyCallback + }, + { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid, + PrehashedFvPpiNotifyCallback + }, + // MU_CHANGE [END] { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, &gEfiPeiFirmwareVolumeInfoPpiGuid, @@ -269,79 +302,6 @@ EndofPeiSignalNotifyCallBack ( #endif Tpm2StartupPublishMeasuredFvHob (); - - #if 0 - // - // Create a guid hob to save all excluded FVs for DXE - MU_CHANGE - START - // - - // - // Get count - // - Instance = 0; - Count = 0; - do { - Status = PeiServicesLocatePpi ( - &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, - Instance, - NULL, - (VOID **)&MeasurementExcludedFvPpi - ); - if (!EFI_ERROR (Status)) { - Count += MeasurementExcludedFvPpi->Count; - Instance++; - } - } while (!EFI_ERROR (Status)); - - // Check if there are any excluded FVs - if (Count > 0) { - DEBUG ((DEBUG_INFO, "Found %d FVs excluded. Publishing hob\n", Count)); - ExcludedHobData = BuildGuidHob ( - &gExcludedFvHobGuid, - sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) - ); - - // Make sure allocation was successful - if (ExcludedHobData != NULL) { - ExcludedHobData->Num = Count; - // - // Copy FV info to hob data - // - Instance = 0; - HobIndex = 0; - do { - Status = PeiServicesLocatePpi ( - &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, - Instance, - NULL, - (VOID **)&MeasurementExcludedFvPpi - ); - if (!EFI_ERROR (Status)) { - if (MeasurementExcludedFvPpi->Count <= 0) { - DEBUG ((DEBUG_ERROR, "ExcludedFvPpi has invalid count %d", MeasurementExcludedFvPpi->Count)); - ASSERT (MeasurementExcludedFvPpi->Count > 0); - } else if ( HobIndex + MeasurementExcludedFvPpi->Count > Count) { - DEBUG ((DEBUG_ERROR, "Found more ExcludedFvPpi fvs than when calculated buffer size. BufferSizeCount (0x%x) NewCount (0x%x)", Count, (HobIndex + MeasurementExcludedFvPpi->Count))); - ASSERT (HobIndex + MeasurementExcludedFvPpi->Count <= Count); - } else { - CopyMem (&ExcludedHobData->ExcludedFvs[HobIndex], &MeasurementExcludedFvPpi->Fv[0], sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * MeasurementExcludedFvPpi->Count); - HobIndex += MeasurementExcludedFvPpi->Count; - } - - Instance++; - } - } while (!EFI_ERROR (Status)); - } else { - DEBUG (( - DEBUG_ERROR, - "Failed to allocate 0x%x byte of memory for ExcludedFvHob", - sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) - )); - } - } // Done with Excluded Fv Hob - - // MU_CHANGE - END - #endif // MU_CHANGE - [END] PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid); return EFI_SUCCESS; @@ -361,9 +321,8 @@ SyncPcrAllocationsAndPcrMask ( EFI_STATUS Status; EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; UINT32 TpmActivePcrBanks; - // UINT32 NewTpmActivePcrBanks; // MU_CHANGE - Update PCR order, add PCD, enable deallocate *and* allocate. - UINT32 Tpm2PcrMask; - UINT32 NewTpm2PcrMask; + UINT32 Tpm2PcrMask; + UINT32 NewTpm2PcrMask; DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n")); @@ -371,14 +330,6 @@ SyncPcrAllocationsAndPcrMask ( // Determine the current TPM support and the Platform PCR mask. // Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &TpmActivePcrBanks); - // MU_CHANGE [BEGIN] - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to determine TPM capabilities!\n", __func__)); - ASSERT_EFI_ERROR (Status); - return; - } - - // MU_CHANGE [END] Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask); if (Tpm2PcrMask == 0) { @@ -672,39 +623,6 @@ MeasureCRTMVersion ( ); } -// MU_CHANGE [BEGIN] - Measure Firmware Debugger Enabled - -/** - Measure and log firmware debugger enabled, and extend the measurement result into a specific PCR. - - @retval EFI_SUCCESS Operation completed successfully. - @retval EFI_OUT_OF_RESOURCES Out of memory. - @retval EFI_DEVICE_ERROR The operation was unsuccessful. -**/ -EFI_STATUS -MeasureFirmwareDebuggerEnabled ( - VOID - ) -{ - TCG_PCR_EVENT_HDR TcgEventHdr; - - TcgEventHdr.PCRIndex = 7; - TcgEventHdr.EventType = EV_EFI_ACTION; - TcgEventHdr.EventSize = sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1; - - DEBUG ((DEBUG_INFO, "Measuring Device State: Firmware Debugger Enabled\n")); - return HashLogExtendEvent ( - &mEdkiiTcgPpi, - 0, - (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING, - sizeof (FIRMWARE_DEBUGGER_EVENT_STRING) - 1, - &TcgEventHdr, - (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING - ); -} - -// MU_CHANGE [END] - /** Get the FvName from the FV header. @@ -1123,108 +1041,61 @@ FirmwareVolumeInfoPpiNotifyCallback ( // MU_CHANGE - [BEGIN] /** - Walk every installed EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI - instance and publish a single gExcludedFvHobGuid HOB containing the union - of their entries. Idempotent: does nothing if the HOB already exists. + Notify handler for gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid. + Publishes one gExcludedFvHobGuid HOB per PPI install; downstream + IsFvMeasurementExcluded walks every such HOB. **/ -STATIC -VOID -BuildExcludedFvHobFromPpi ( - VOID +EFI_STATUS +EFIAPI +ExcludedFvPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi ) { - EFI_STATUS Status; - UINT32 Instance; - UINT32 Count; - UINT32 HobIndex; - EXCLUDED_HOB_DATA *ExcludedHobData; - EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *MeasurementExcludedFvPpi; + EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *ExcludedPpi; + EXCLUDED_HOB_DATA *HobData; + UINTN HobSize; - if (GetFirstGuidHob (&gExcludedFvHobGuid) != NULL) { - return; + ExcludedPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *)Ppi; + if (ExcludedPpi->Count == 0) { + DEBUG ((DEBUG_WARN, "ExcludedFvPpi has Count=0; skipping\n")); + return EFI_SUCCESS; } - MeasurementExcludedFvPpi = NULL; - Instance = 0; - Count = 0; - do { - Status = PeiServicesLocatePpi ( - &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, - Instance, - NULL, - (VOID **)&MeasurementExcludedFvPpi - ); - if (!EFI_ERROR (Status)) { - Count += MeasurementExcludedFvPpi->Count; - Instance++; - } - } while (!EFI_ERROR (Status)); + HobSize = sizeof (EXCLUDED_HOB_DATA) + + sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * ExcludedPpi->Count; - if (Count == 0) { - return; - } - - DEBUG ((DEBUG_INFO, "Found %d FVs excluded. Publishing hob\n", Count)); - ExcludedHobData = BuildGuidHob ( - &gExcludedFvHobGuid, - sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) - ); - if (ExcludedHobData == NULL) { - DEBUG (( - DEBUG_ERROR, - "Failed to allocate 0x%x byte of memory for ExcludedFvHob\n", - sizeof (EXCLUDED_HOB_DATA) + (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * Count) - )); - return; + HobData = BuildGuidHob (&gExcludedFvHobGuid, HobSize); + if (HobData == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate ExcludedFvHob (size=0x%x)\n", (UINT32)HobSize)); + return EFI_OUT_OF_RESOURCES; } - ExcludedHobData->Num = Count; - - Instance = 0; - HobIndex = 0; - do { - Status = PeiServicesLocatePpi ( - &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, - Instance, - NULL, - (VOID **)&MeasurementExcludedFvPpi - ); - if (!EFI_ERROR (Status)) { - if (MeasurementExcludedFvPpi->Count == 0) { - DEBUG ((DEBUG_ERROR, "ExcludedFvPpi has invalid count %d\n", MeasurementExcludedFvPpi->Count)); - ASSERT (MeasurementExcludedFvPpi->Count > 0); - } else if (HobIndex + MeasurementExcludedFvPpi->Count > Count) { - DEBUG ((DEBUG_ERROR, "Found more ExcludedFvPpi fvs than when calculated buffer size. BufferSizeCount (0x%x) NewCount (0x%x)\n", Count, (HobIndex + MeasurementExcludedFvPpi->Count))); - ASSERT (HobIndex + MeasurementExcludedFvPpi->Count <= Count); - } else { - CopyMem ( - &ExcludedHobData->ExcludedFvs[HobIndex], - &MeasurementExcludedFvPpi->Fv[0], - sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * MeasurementExcludedFvPpi->Count - ); - HobIndex += MeasurementExcludedFvPpi->Count; - } + HobData->Num = ExcludedPpi->Count; + CopyMem ( + &HobData->ExcludedFvs[0], + &ExcludedPpi->Fv[0], + sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_FV) * ExcludedPpi->Count + ); - Instance++; - } - } while (!EFI_ERROR (Status)); + DEBUG ((DEBUG_INFO, "Published ExcludedFvHob for %u FV(s)\n", ExcludedPpi->Count)); + return EFI_SUCCESS; } /** - Walk every installed gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid - instance and publish one gPrehashedFvHobGuid HOB per FV. The trailing - HASH_INFO records + digest bytes from the PPI are copied verbatim into - the HOB payload (the two layouts are identical past the header). - Idempotent per FV: skips PPIs whose FvBase/FvLength already have a HOB. + Notify handler for gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid. + Publishes one gPrehashedFvHobGuid HOB per FV; skips FVs already recorded + so ReInstallPpi and retroactive notify fires do not duplicate entries. **/ -STATIC -VOID -BuildPrehashedFvHobFromPpi ( - VOID +EFI_STATUS +EFIAPI +PrehashedFvPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi ) { - EFI_STATUS Status; - UINT32 Instance; EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *PrehashedFvPpi; HASH_INFO *PpiHashInfo; UINT32 HashIndex; @@ -1232,77 +1103,56 @@ BuildPrehashedFvHobFromPpi ( PREHASHED_FV_HOB *HobHdr; EFI_HOB_GUID_TYPE *ExistingHob; PREHASHED_FV_HOB *ExistingHdr; - BOOLEAN AlreadyPresent; - Instance = 0; - do { - Status = PeiServicesLocatePpi ( - &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid, - Instance, - NULL, - (VOID **)&PrehashedFvPpi - ); - if (EFI_ERROR (Status)) { - break; - } + PrehashedFvPpi = (EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI *)Ppi; - Instance++; + ExistingHob = GetFirstGuidHob (&gPrehashedFvHobGuid); + while (ExistingHob != NULL) { + ExistingHdr = GET_GUID_HOB_DATA (ExistingHob); + if ((ExistingHdr->FvBase == (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase) && + (ExistingHdr->FvLength == (UINT64)PrehashedFvPpi->FvLength)) + { + return EFI_SUCCESS; + } - AlreadyPresent = FALSE; - ExistingHob = GetFirstGuidHob (&gPrehashedFvHobGuid); - while (ExistingHob != NULL) { - ExistingHdr = GET_GUID_HOB_DATA (ExistingHob); - if ((ExistingHdr->FvBase == (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase) && - (ExistingHdr->FvLength == (UINT64)PrehashedFvPpi->FvLength)) - { - AlreadyPresent = TRUE; - break; - } + ExistingHob = GetNextGuidHob (&gPrehashedFvHobGuid, GET_NEXT_HOB (ExistingHob)); + } - ExistingHob = GetNextGuidHob (&gPrehashedFvHobGuid, GET_NEXT_HOB (ExistingHob)); - } + if (PrehashedFvPpi->Count == 0) { + DEBUG ((DEBUG_WARN, "PrehashedFvPpi has Count=0; skipping\n")); + return EFI_SUCCESS; + } - if (AlreadyPresent) { - continue; - } + TrailingSize = 0; + PpiHashInfo = (HASH_INFO *)(PrehashedFvPpi + 1); + for (HashIndex = 0; HashIndex < PrehashedFvPpi->Count; HashIndex++) { + TrailingSize += sizeof (HASH_INFO) + PpiHashInfo->HashSize; + PpiHashInfo = (HASH_INFO *)((UINT8 *)(PpiHashInfo + 1) + PpiHashInfo->HashSize); + } - if (PrehashedFvPpi->Count == 0) { - DEBUG ((DEBUG_WARN, "PrehashedFvPpi[%u] has Count=0; skipping\n", Instance - 1)); - continue; - } + HobHdr = BuildGuidHob ( + &gPrehashedFvHobGuid, + sizeof (PREHASHED_FV_HOB) + TrailingSize + ); + if (HobHdr == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate PrehashedFvHob (trailing=0x%x)\n", (UINT32)TrailingSize)); + return EFI_OUT_OF_RESOURCES; + } - // - // Sum trailing HASH_INFO + digest bytes to size the HOB. - // - TrailingSize = 0; - PpiHashInfo = (HASH_INFO *)(PrehashedFvPpi + 1); - for (HashIndex = 0; HashIndex < PrehashedFvPpi->Count; HashIndex++) { - TrailingSize += sizeof (HASH_INFO) + PpiHashInfo->HashSize; - PpiHashInfo = (HASH_INFO *)((UINT8 *)(PpiHashInfo + 1) + PpiHashInfo->HashSize); - } + HobHdr->FvBase = (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase; + HobHdr->FvLength = (UINT64)PrehashedFvPpi->FvLength; + HobHdr->Count = PrehashedFvPpi->Count; + CopyMem (HobHdr + 1, PrehashedFvPpi + 1, TrailingSize); - HobHdr = BuildGuidHob ( - &gPrehashedFvHobGuid, - sizeof (PREHASHED_FV_HOB) + TrailingSize - ); - if (HobHdr == NULL) { - DEBUG ((DEBUG_ERROR, "Failed to allocate PrehashedFvHob (trailing=0x%x)\n", (UINT32)TrailingSize)); - return; - } + DEBUG (( + DEBUG_INFO, + "Published PrehashedFvHob: base=0x%lx len=0x%lx count=%u\n", + HobHdr->FvBase, + HobHdr->FvLength, + HobHdr->Count + )); - HobHdr->FvBase = (EFI_PHYSICAL_ADDRESS)PrehashedFvPpi->FvBase; - HobHdr->FvLength = (UINT64)PrehashedFvPpi->FvLength; - HobHdr->Count = PrehashedFvPpi->Count; - CopyMem (HobHdr + 1, PrehashedFvPpi + 1, TrailingSize); - - DEBUG (( - DEBUG_INFO, - "Published PrehashedFvHob: base=0x%lx len=0x%lx count=%u\n", - HobHdr->FvBase, - HobHdr->FvLength, - HobHdr->Count - )); - } while (TRUE); + return EFI_SUCCESS; } // MU_CHANGE [END] @@ -1326,8 +1176,6 @@ PeimEntryMP ( EFI_PEI_FV_HANDLE VolumeHandle; // MU_CHANGE EFI_FV_INFO VolumeInfo; // MU_CHANGE - // DEVICE_STATE CurrentDeviceState; // MU_CHANGE - // // install Tcg Services // @@ -1335,24 +1183,6 @@ PeimEntryMP ( ASSERT_EFI_ERROR (Status); #if 0 // MU_CHANGE - [BEGIN] - // MU_CHANGE_103691 - // MU_CHANGE [BEGIN] - Add support for measurements extended before Tcg2 stack is available. - CreateTcg2PreUefiEventLogEntries (); - // MU_CHANGE [END] - - // MU_CHANGE [BEGIN] - Measure Firmware Debugger Enabled - CurrentDeviceState = GetDeviceState (); - - if ((CurrentDeviceState & DEVICE_STATE_SOURCE_DEBUG_ENABLED) != 0) { - Status = MeasureFirmwareDebuggerEnabled (); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to measure Firmware Debugger Enabled!\n")); - PanicReport (__FILE__, __LINE__, "Failed to measure Firmware Debugger Enabled!\n"); - return Status; - } - } - - // MU_CHANGE [END] if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) { Status = MeasureCRTMVersion (); @@ -1366,6 +1196,8 @@ PeimEntryMP ( #endif // MU_CHANGE - [END] // MU_CHANGE - [BEGIN] + Status = PeiServicesNotifyPpi (&mNotifyList[0]); + ASSERT_EFI_ERROR (Status); Status = PeiServicesFfsFindNextVolume (0, &VolumeHandle); ASSERT_EFI_ERROR (Status); Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo); @@ -1383,14 +1215,6 @@ PeimEntryMP ( // MU_CHANGE - [END] - // - // Post callbacks: - // for the FvInfoPpi services to measure and record - // the additional Fvs to TPM - // - Status = PeiServicesNotifyPpi (&mNotifyList[0]); - ASSERT_EFI_ERROR (Status); - return Status; } @@ -1487,15 +1311,6 @@ PeimEntryMA ( goto Done; } - // MU_CHANGE_23086 - // MU_CHANGE [BEGIN] - Call OEM init hook. - Status = OemTpm2InitPeiPreStartup (BootMode); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPreStartup returned %r. Aborting PEI init!\n", Status)); - goto Done; - } - - // MU_CHANGE [END] S3ErrorReport = FALSE; if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) { if (BootMode == BOOT_ON_S3_RESUME) { @@ -1511,11 +1326,6 @@ PeimEntryMA ( } if (EFI_ERROR (Status)) { - // MU_CHANGE_58957 - // MU_CHANGE [BEGIN] - Make sure that TPM2_Startup() can report an error. - DEBUG ((DEBUG_ERROR, "Tcg2Pei::%a - TPM failed Startup!\n", __func__)); - ASSERT_EFI_ERROR (Status); - // MU_CHANGE [END] goto Done; } } @@ -1548,24 +1358,11 @@ PeimEntryMA ( if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) { Status = Tpm2SelfTest (NO); if (EFI_ERROR (Status)) { - // MU_CHANGE_58957 - // MU_CHANGE [BEGIN] - Make sure that TPM2_Startup() can report an error. - DEBUG ((DEBUG_ERROR, "Tcg2Pei::%a - TPM failed Startup!\n", __func__)); - // MU_CHANGE [END] goto Done; } } } - // MU_CHANGE_23086 - // MU_CHANGE [BEGIN] - Call OEM init hook. - Status = OemTpm2InitPeiPostSelfTest (BootMode); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPostSelfTest returned %r. Aborting PEI init!\n", Status)); - goto Done; - } - - // MU_CHANGE [END] DEBUG_CODE_BEGIN (); // // Peek into TPM PCR 00 before any BIOS measurement. @@ -1581,8 +1378,6 @@ PeimEntryMA ( #endif // MU_CHANGE - [END] // MU_CHANGE - [BEGIN] - BuildExcludedFvHobFromPpi (); - BuildPrehashedFvHobFromPpi (); Status = Tpm2StartupInitializeTpm (BootMode == BOOT_ON_S3_RESUME); if (EFI_ERROR (Status)) { @@ -1600,18 +1395,6 @@ PeimEntryMA ( } if (mImageInMemory) { - #if 0 // MU_CHANGE - [BEGIN] - // MU_CHANGE_23086 - // MU_CHANGE [BEGIN] - Call OEM init hook. - Status = OemTpm2InitPeiPreMeasurements (); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "OemTpm2InitPeiPreMeasurements returned %r. Aborting PEI init!\n", Status)); - return Status; - } - - // MU_CHANGE [END] - #endif // MU_CHANGE - [END] - Status = PeimEntryMP ((EFI_PEI_SERVICES **)PeiServices); return Status; } diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf index 4527f50aa9b..e023f96adbf 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf @@ -74,11 +74,11 @@ [Ppis] gEfiPeiFirmwareVolumeInfoPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY gEfiPeiFirmwareVolumeInfo2PpiGuid ## SOMETIMES_CONSUMES ## NOTIFY - gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid ## SOMETIMES_CONSUMES + gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY # MU_CHANGE gPeiTpmInitializedPpiGuid ## SOMETIMES_PRODUCES gPeiTpmInitializationDonePpiGuid ## PRODUCES gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY - gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid ## SOMETIMES_CONSUMES + gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid ## SOMETIMES_CONSUMES ## NOTIFY # MU_CHANGE gEdkiiTcgPpiGuid ## PRODUCES [Pcd] From 2d3c8e044fd816c68be26306f47f2a19e1bb74ca Mon Sep 17 00:00:00 2001 From: rdiaz Date: Mon, 31 Aug 2026 20:17:10 -0700 Subject: [PATCH 11/11] Ran Uncrustify --- SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c index 52a93284750..a8b6e6d5a65 100644 --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c @@ -1055,7 +1055,7 @@ ExcludedFvPpiNotifyCallback ( { EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *ExcludedPpi; EXCLUDED_HOB_DATA *HobData; - UINTN HobSize; + UINTN HobSize; ExcludedPpi = (EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *)Ppi; if (ExcludedPpi->Count == 0) {