Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] [PROTOTYPE] Stabilizing PCR4 Measurements #330

Draft
wants to merge 3 commits into
base: dev/202405
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 53 additions & 3 deletions SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ Tcg2MeasureGptTable (
PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
}

// MU_CHANGE [BEGIN]
DEBUG ((DEBUG_INFO, "PCR[%x] MeasureGptTable\n",Tcg2Event->Header.PCRIndex));
// MU_CHANGE [END]

//
// Only one of TCG2_PROTOCOL or CC_MEASUREMENT_PROTOCOL is exposed.
// So Measure the GPT data with one of the protocol.
Expand Down Expand Up @@ -475,6 +479,24 @@ Tcg2MeasurePeImage (
CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
}

// MU_CHANGE [END]
DEBUG_CODE_BEGIN ();

CHAR16 *ToText;
ToText = ConvertDevicePathToText (
ImageLoad->DevicePath,
FALSE,
TRUE
);
if (ToText != NULL) {
DEBUG ((DEBUG_INFO, "PCR[%x] MeasurePeImage (%s)\n",Tcg2Event->Header.PCRIndex, ToText));
FreePool (ToText);
} else {
DEBUG ((DEBUG_INFO, "PCR[%x] MeasurePeImage (N/A)\n",Tcg2Event->Header.PCRIndex));
}

DEBUG_CODE_END ();

//
// Log the PE data
//
Expand Down Expand Up @@ -772,12 +794,16 @@ DxeTpm2MeasureBootHandler (
return EFI_SUCCESS;
}

// MU_CHANGE [BEGIN]
//
// The PE image from unmeasured Firmware volume need be measured
// The PE image from measured Firmware volume will be measured according to policy below.
// If it is driver, do not measure
// If it is application, still measure.
// If it is application:
// From measured firmware volume: do not measure
// From unmeasured firmware volume: measure
//
// MU_CHANGE [END]
ApplicationRequired = TRUE;

if ((mTcg2CacheMeasuredHandle != Handle) && (mTcg2MeasuredHobData != NULL)) {
Expand Down Expand Up @@ -872,8 +898,10 @@ DxeTpm2MeasureBootHandler (
// Measure only application if Application flag is set
// Measure drivers and applications if Application flag is not set
//
if ((!ApplicationRequired) ||
(ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)))
// MU_CHANGE
//if ((!ApplicationRequired) ||
// (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)))
if (!ApplicationRequired)
{
//
// Print the image path to be measured.
Expand Down Expand Up @@ -905,6 +933,28 @@ DxeTpm2MeasureBootHandler (
);
}

// MU_CHANGE [END]
DEBUG_CODE_BEGIN ();
//
// Due to "TCG_SPEC_CHANGE: PCR4_SKIP_FV_APP" applications launched from measured firmware will be skipped
//

if (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {
CHAR16 *ToText;
ToText = ConvertDevicePathToText (
DevicePathNode,
FALSE,
TRUE
);
if (ToText != NULL) {
DEBUG ((DEBUG_INFO, "TCG_SPEC_CHANGE: PCR4_SKIP_FV_APP -- Skipping: %s.\n", ToText));
FreePool (ToText);
}
}

DEBUG_CODE_END ();
// MU_CHANGE [END]

//
// Done, free the allocated resource.
//
Expand Down
5 changes: 0 additions & 5 deletions SecurityPkg/SecurityPkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,6 @@
# TRUE - A random password will be used
# FALSE - The hierarchy will be disabled
gEfiSecurityPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy|TRUE|BOOLEAN|0x00010024
## MU_CHANGE - Support mode where Ready To Boot Strings/Events are not measured into
## PCR 4.
# TRUE - The Platform will measure
# FALSE -The Platform will not measure those events
gEfiSecurityPkgTokenSpaceGuid.TcgMeasureBootStringsInPcr4|TRUE|BOOLEAN|0x0000000B

[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## Indicates whether TPM physical presence is locked during platform initialization.
Expand Down
151 changes: 101 additions & 50 deletions SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

// #define PERF_ID_TCG2_DXE 0x3120 // MU_CHANGE

// MU_CHANGE [BEGIN]
//
// Event signals that this code adheres to the TCG PC Client Platform Firmware Profile Specification
// Version 1.05 Revision 23
//
#define TCG_SPEC_VERSION_EVENT_DATA "TCG PC Client Platform Firmware Profile Specification: Version 1.05, Revision 23"
// MU_CHANGE [END]

typedef struct {
CHAR16 *VariableName;
EFI_GUID *VendorGuid;
Expand Down Expand Up @@ -2005,6 +2013,9 @@ TcgMeasureAction (
TcgEvent.PCRIndex = PCRIndex;
TcgEvent.EventType = EV_EFI_ACTION;
TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
// MU_CHANGE [BEGIN]
DEBUG ((DEBUG_INFO, "PCR[%x] MeasureAction: %a\n", PCRIndex, String));
// MU_CHANGE [END]
return TcgDxeHashLogExtendEvent (
0,
(UINT8 *)String,
Expand Down Expand Up @@ -2050,7 +2061,9 @@ MeasureHandoffTables (
HandoffTables.NumberOfTables = 1;
HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;

// MU_CHANGE [BEGIN]
DEBUG ((DEBUG_INFO, "PCR[%x] MeasureHandoffTables\n", TcgEvent.PCRIndex));
// MU_CHANGE [END]
Status = TcgDxeHashLogExtendEvent (
0,
(UINT8 *)(UINTN)ProcessorLocBuf,
Expand Down Expand Up @@ -2083,8 +2096,9 @@ MeasureSeparatorEvent (
TCG_PCR_EVENT_HDR TcgEvent;
UINT32 EventData;

DEBUG ((DEBUG_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));

// MU_CHANGE [BEGIN]
DEBUG ((DEBUG_INFO, "PCR[%x] MeasureSeparatorEvent\n", PCRIndex));
// MU_CHANGE [END]
EventData = 0;
TcgEvent.PCRIndex = PCRIndex;
TcgEvent.EventType = EV_SEPARATOR;
Expand Down Expand Up @@ -2128,8 +2142,9 @@ MeasureVariable (
UINTN VarNameLength;
UEFI_VARIABLE_DATA *VarLog;

DEBUG ((DEBUG_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
// MU_CHANGE [BEGIN]
DEBUG ((DEBUG_INFO, "PCR[%x] MeasureVariable (EventType(%x), VariableName(%g), VendorGuid(%g))\n", PCRIndex, EventType, VarName, VendorGuid));
// MU_CHANGE [END]

VarNameLength = StrLen (VarName);
TcgEvent.PCRIndex = PCRIndex;
Expand Down Expand Up @@ -2595,22 +2610,6 @@ OnReadyToBoot (
DEBUG ((DEBUG_ERROR, "Boot Variables not Measured. Error!\n"));
}

if (PcdGetBool (TcgMeasureBootStringsInPcr4)) {
// MU_CHANGE for some platform uefi compat
//
// 1. This is the first boot attempt.
//
Status = TcgMeasureAction (
4,
EFI_CALLING_EFI_APPLICATION
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
}
} else {
DEBUG ((DEBUG_WARN, "Tcg2Dxe PCD set to skip Measure Boot String in PCR4\n"));
}

//
// 2. Draw a line between pre-boot env and entering post-boot env.
// PCR[7] is already done.
Expand All @@ -2633,35 +2632,6 @@ OnReadyToBoot (
//
// 5. Read & Measure variable. BootOrder already measured.
//
} else {
if (PcdGetBool (TcgMeasureBootStringsInPcr4)) {
// MU_CHANGE for platform uefi compat
//
// 6. Not first attempt, meaning a return from last attempt
//
Status = TcgMeasureAction (
4,
EFI_RETURNING_FROM_EFI_APPLICATION
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));
}

//
// 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again
// TCG PC Client PFP spec Section 2.4.4.5 Step 4
//
Status = TcgMeasureAction (
4,
EFI_CALLING_EFI_APPLICATION
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
}
} else {
// MU_CHANGE
DEBUG ((DEBUG_WARN, "Tcg2Dxe PCD set to skip Measure Boot String in PCR4\n"));
}
}

DEBUG ((DEBUG_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));
Expand Down Expand Up @@ -2817,6 +2787,74 @@ OnResetNotificationInstall (
}
}

// MU_CHANGE [BEGIN]

/**
Logs a non-measured event in the TCG event log.

This function is responsible for logging events that are not measured by the TPM. These events
do not affect the TPM's Platform Configuration Registers (PCRs) but are recorded for signaling to
an OS auditing the log. The function takes in the size of the event and the event data itself,
creates an EFI_TCG2_EVENT structure, and logs the event using the Tcg2LogEvent function.

@param[in] EventSize The size of the event data to be logged.
@param[in] EventData A pointer to the event data.

@retval EFI_SUCCESS The event was logged successfully.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed, or the event size is too large.
@retval Other An error returned by the Tcg2LogEvent function.
**/
EFI_STATUS
Tcg2LogNonMeasuredEvent (
IN UINTN EventSize,
IN VOID *EventData
)
{
EFI_TCG2_EVENT *Tcg2Event;
EFI_STATUS Status;

TPML_DIGEST_VALUES NoActionDigestList;

//
// Normally the digest list represents the hashes of the event data.
// In this case, there is no event data to hash, so the list is empty.
//
ZeroMem (&NoActionDigestList, sizeof (NoActionDigestList));
NoActionDigestList.count = 0;

// Handle the case where the event size is too large
if (EventSize > MAX_UINT32 - sizeof (EFI_TCG2_EVENT)) {
DEBUG ((DEBUG_ERROR, "Event size is too large\n"));
return EFI_OUT_OF_RESOURCES;
}

// Allocate memory for the event
Tcg2Event = AllocateZeroPool (sizeof (EFI_TCG2_EVENT) + EventSize);
if (Tcg2Event == NULL) {
DEBUG ((DEBUG_ERROR, "Failed to allocate memory for the non-measured event\n"));
return EFI_OUT_OF_RESOURCES;
}

Tcg2Event->Size = sizeof (EFI_TCG2_EVENT) + EventSize - sizeof (Tcg2Event->Event);
Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
Tcg2Event->Header.PCRIndex = 0; // For EV_NO_ACTION
Tcg2Event->Header.EventType = EV_NO_ACTION;
CopyMem (Tcg2Event->Event, EventData, EventSize); // Ensure EventData is not NULL

Status = Tcg2LogEvent (&mMuTcg2Protocol, &NoActionDigestList, Tcg2Event);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to log the non-measured event\n"));
}

// Free the allocated memory
FreePool (Tcg2Event);

return Status;
}

// MU_CHANGE [END]

/**
The function install Tcg2 protocol.

Expand All @@ -2832,6 +2870,19 @@ InstallTcg2 (
EFI_HANDLE Handle;

Handle = NULL;

// MU_CHANGE [BEGIN]
//
// Log the the version of the TCG specification that the platform implements.
//
Status = Tcg2LogNonMeasuredEvent (sizeof (TCG_SPEC_VERSION_EVENT_DATA), TCG_SPEC_VERSION_EVENT_DATA);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to log the non-measured signalling event\n"));
return Status;
}

// MU_CHANGE [END]

Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gEfiTcg2ProtocolGuid,
Expand Down
1 change: 0 additions & 1 deletion SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa ## PRODUCES
gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication ## CONSUMES
gEfiSecurityPkgTokenSpaceGuid.TcgMeasureBootStringsInPcr4 ## CONSUMES # MU_CHANGE

[Depex]
# According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec
Expand Down
Loading