OvmfPkg: Refactor MeaureFvImage

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4243

MeasureFvImage once was implemented in PeilessStartupLib and it does
measurement and logging for Configuration FV (Cfv) image in one go,
using TpmMeasureAndLogData(). But it doesn't work in SEC.

This patch splits MeasureFvImage into 2 functions and implement them in
SecTdxHelperLib.
 - TdxHelperMeasureCfvImage
 - TdxHelperBuildGuidHobForTdxMeasurement

TdxHelperMeasureCfvImage measures the Cfv image and stores the hash value
in WorkArea. TdxHelperBuildGuidHobForTdxMeasurement builds GuidHob for the
measurement based on the hash value in WorkArea.

After these 2 functions are introduced, PeilessStartupLib should also be
updated:
 - Call these 2 functions instead of the MeasureFvImage
 - Delete the duplicated codes in PeilessStartupLib

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Michael Roth <michael.roth@amd.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
Min M Xu
2023-02-03 11:31:41 +08:00
committed by mergify[bot]
parent f41acc651f
commit 852ae4cd80
6 changed files with 119 additions and 153 deletions

View File

@@ -1,121 +0,0 @@
/** @file
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <IndustryStandard/Tpm20.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/HobLib.h>
#include <Library/PrintLib.h>
#include <Library/TcgEventLogRecordLib.h>
#include <Library/TpmMeasurementLib.h>
#include "PeilessStartupInternal.h"
#define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
/**
Get the FvName from the FV header.
Causion: The FV is untrusted input.
@param[in] FvBase Base address of FV image.
@param[in] FvLength Length of FV image.
@return FvName pointer
@retval NULL FvName is NOT found
**/
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) {
return NULL;
}
if (FvLength >= MAX_ADDRESS - FvBase) {
return NULL;
}
if (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;
}
/**
Measure FV image.
@param[in] FvBase Base address of FV image.
@param[in] FvLength Length of FV image.
@param[in] PcrIndex Index of PCR
@retval EFI_SUCCESS Fv image is measured successfully
or it has been already measured.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureFvImage (
IN EFI_PHYSICAL_ADDRESS FvBase,
IN UINT64 FvLength,
IN UINT8 PcrIndex
)
{
EFI_STATUS Status;
CFV_HANDOFF_TABLE_POINTERS2 FvBlob2;
VOID *FvName;
//
// Init the log event for FV measurement
//
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 = FvBase;
FvBlob2.BlobLength = FvLength;
Status = TpmMeasureAndLogData (
1, // PCRIndex
EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType
(VOID *)&FvBlob2, // EventData
sizeof (FvBlob2), // EventSize
(UINT8 *)(UINTN)FvBase, // HashData
(UINTN)(FvLength) // HashDataLen
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));
ASSERT (FALSE);
}
return Status;
}

View File

@@ -140,13 +140,11 @@ PeilessStartup (
UINT32 DxeCodeSize;
TD_RETURN_DATA TdReturnData;
VOID *VmmHobList;
UINT8 *CfvBase;
Status = EFI_SUCCESS;
BootFv = NULL;
VmmHobList = NULL;
SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
CfvBase = (UINT8 *)(UINTN)FixedPcdGet32 (PcdCfvBase);
ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
@@ -187,18 +185,18 @@ PeilessStartup (
}
//
// Build GuidHob for tdx measurement
// Measure Tdx CFV
//
Status = TdxHelperBuildGuidHobForTdxMeasurement ();
Status = TdxHelperMeasureCfvImage ();
if (EFI_ERROR (Status)) {
ASSERT (FALSE);
CpuDeadLoop ();
}
//
// Measure Tdx CFV
// Build GuidHob for tdx measurement
//
Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, FixedPcdGet32 (PcdCfvRawDataSize), 1);
Status = TdxHelperBuildGuidHobForTdxMeasurement ();
if (EFI_ERROR (Status)) {
ASSERT (FALSE);
CpuDeadLoop ();

View File

@@ -58,25 +58,4 @@ EFIAPI
ConstructSecHobList (
);
/**
Measure FV image.
@param[in] FvBase Base address of FV image.
@param[in] FvLength Length of FV image.
@param[in] PcrIndex Index of PCR
@retval EFI_SUCCESS Fv image is measured successfully
or it has been already measured.
@retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
@retval EFI_DEVICE_ERROR The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureFvImage (
IN EFI_PHYSICAL_ADDRESS FvBase,
IN UINT64 FvLength,
IN UINT8 PcrIndex
);
#endif

View File

@@ -29,7 +29,6 @@
PeilessStartup.c
Hob.c
DxeLoad.c
IntelTdx.c
X64/VirtualMemory.c
[Packages]
@@ -70,9 +69,6 @@
gEfiNonCcFvGuid
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase
gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataOffset
gUefiOvmfPkgTokenSpaceGuid.PcdCfvRawDataSize
gUefiOvmfPkgTokenSpaceGuid.PcdBfvBase
gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataOffset
gUefiOvmfPkgTokenSpaceGuid.PcdBfvRawDataSize