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:
@@ -15,6 +15,7 @@
|
||||
#include <IndustryStandard/UefiTcgPlatform.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/TcgEventLogRecordLib.h>
|
||||
#include <WorkArea.h>
|
||||
|
||||
#pragma pack(1)
|
||||
@@ -29,6 +30,9 @@ typedef struct {
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#define FV_HANDOFF_TABLE_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
|
||||
typedef PLATFORM_FIRMWARE_BLOB2_STRUCT CFV_HANDOFF_TABLE_POINTERS2;
|
||||
|
||||
/**
|
||||
* Build GuidHob for Tdx measurement.
|
||||
*
|
||||
@@ -112,6 +116,52 @@ BuildTdxMeasurementGuidHob (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
Build the GuidHob for tdx measurements which were done in SEC phase.
|
||||
The measurement values are stored in WorkArea.
|
||||
@@ -128,6 +178,10 @@ InternalBuildGuidHobForTdxMeasurement (
|
||||
OVMF_WORK_AREA *WorkArea;
|
||||
VOID *TdHobList;
|
||||
TDX_HANDOFF_TABLE_POINTERS2 HandoffTables;
|
||||
VOID *FvName;
|
||||
CFV_HANDOFF_TABLE_POINTERS2 FvBlob2;
|
||||
EFI_PHYSICAL_ADDRESS FvBase;
|
||||
UINT64 FvLength;
|
||||
UINT8 *HashValue;
|
||||
|
||||
if (!TdIsEnabled ()) {
|
||||
@@ -169,5 +223,37 @@ InternalBuildGuidHobForTdxMeasurement (
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Build the GuidHob for Cfv measurement
|
||||
//
|
||||
if (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap & TDX_MEASUREMENT_CFVIMG_BITMASK) {
|
||||
HashValue = WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.CfvImgHashValue;
|
||||
FvBase = (UINT64)PcdGet32 (PcdOvmfFlashNvStorageVariableBase);
|
||||
FvLength = (UINT64)PcdGet32 (PcdCfvRawDataSize);
|
||||
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 = BuildTdxMeasurementGuidHob (
|
||||
0, // RtmrIndex
|
||||
EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType
|
||||
(VOID *)&FvBlob2, // EventData
|
||||
sizeof (FvBlob2), // EventSize
|
||||
HashValue, // HashValue
|
||||
SHA384_DIGEST_SIZE // HashSize
|
||||
);
|
||||
}
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user