[edk2-devel] [PATCH 2/3] OvmfPkg: Implement MeasureHobList/MeasureFvImage

Min Xu posted 3 patches 3 years, 8 months ago
[edk2-devel] [PATCH 2/3] OvmfPkg: Implement MeasureHobList/MeasureFvImage
Posted by Min Xu 3 years, 8 months ago
From: Min M Xu <min.m.xu@intel.com>

MeasureHobList and MeasureFvImage once were implemented in
SecMeasurementTdxLib. The intention of this patch-set is to refactor
SecMeasurementTdxLib to be an instance of TpmMeasurementLib. So these
2 functions (MeasureHobList/MeasureFvImage) are moved to
PeilessStartupLib. This is because:
1. RTMR based trusted boot is implemented in Config-B (See below link)
2. PeilessStartupLib is designed for PEI-less boot and it is the right
   place to do the measurement for Hoblist and Config-FV.

Config-B: https://edk2.groups.io/g/devel/message/76367

Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
---
 OvmfPkg/IntelTdx/IntelTdxX64.dsc              |   2 +-
 OvmfPkg/Library/PeilessStartupLib/IntelTdx.c  | 186 ++++++++++++++++++
 .../PeilessStartupLib/PeilessStartup.c        |   1 -
 .../PeilessStartupInternal.h                  |  36 ++++
 .../PeilessStartupLib/PeilessStartupLib.inf   |   2 +-
 5 files changed, 224 insertions(+), 3 deletions(-)

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index 43ab8bd089d9..a40f7228b98e 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -527,7 +527,7 @@
   OvmfPkg/IntelTdx/Sec/SecMain.inf {
     <LibraryClasses>
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
-      SecMeasurementLib|OvmfPkg/Library/SecMeasurementLib/SecMeasurementLibTdx.inf
+      TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf
       BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
       HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
       NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
index d240d3b7719f..484fd21057c8 100644
--- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
+++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
@@ -9,8 +9,34 @@
 #include <Library/DebugLib.h>
 #include <Guid/VariableFormat.h>
 #include <Guid/SystemNvDataGuid.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TpmMeasurementLib.h>
+
 #include "PeilessStartupInternal.h"
 
+#pragma pack(1)
+
+#define HANDOFF_TABLE_DESC  "TdxTable"
+typedef struct {
+  UINT8                      TableDescriptionSize;
+  UINT8                      TableDescription[sizeof (HANDOFF_TABLE_DESC)];
+  UINT64                     NumberOfTables;
+  EFI_CONFIGURATION_TABLE    TableEntry[1];
+} TDX_HANDOFF_TABLE_POINTERS2;
+
+#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"
+typedef struct {
+  UINT8                   BlobDescriptionSize;
+  UINT8                   BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)];
+  EFI_PHYSICAL_ADDRESS    BlobBase;
+  UINT64                  BlobLength;
+} FV_HANDOFF_TABLE_POINTERS2;
+
+#pragma pack()
+
 /**
   Check padding data all bit should be 1.
 
@@ -161,3 +187,163 @@ TdxValidateCfv (
 
   return TRUE;
 }
+
+/**
+  Measure the Hoblist passed from the VMM.
+
+  @param[in] VmmHobList    The Hoblist pass the firmware
+
+  @retval EFI_SUCCESS           Fv image is measured successfully
+                                or it has been already measured.
+  @retval Others                Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+MeasureHobList (
+  IN CONST VOID  *VmmHobList
+  )
+{
+  EFI_PEI_HOB_POINTERS         Hob;
+  TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;
+  EFI_STATUS                   Status;
+
+  if (!TdIsEnabled ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Hob.Raw = (UINT8 *)VmmHobList;
+
+  //
+  // Parse the HOB list until end of list.
+  //
+  while (!END_OF_HOB_LIST (Hob)) {
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  //
+  // Init the log event for HOB measurement
+  //
+
+  HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription);
+  CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription));
+  HandoffTables.NumberOfTables = 1;
+  CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid);
+  HandoffTables.TableEntry[0].VendorTable = (VOID *)VmmHobList;
+
+  Status = TpmMeasureAndLogData (
+             1,                                              // PCRIndex
+             EV_EFI_HANDOFF_TABLES2,                         // EventType
+             (VOID *)&HandoffTables,                         // EventData
+             sizeof (HandoffTables),                         // EventSize
+             (UINT8 *)(UINTN)VmmHobList,                     // HashData
+             (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashDataLen
+             );
+
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+  }
+
+  return Status;
+}
+
+/**
+  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;
+  FV_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;
+}
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 54236b956c52..fdfefd00d732 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -20,7 +20,6 @@
 #include <ConfidentialComputingGuestAttr.h>
 #include <Guid/MemoryTypeInformation.h>
 #include <OvmfPlatforms.h>
-#include <Library/SecMeasurementLib.h>
 #include "PeilessStartupInternal.h"
 
 #define GET_GPAW_INIT_STATE(INFO)  ((UINT8) ((INFO) & 0x3f))
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
index dd79b8a06b44..74b5f46552c2 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
@@ -69,4 +69,40 @@ TdxValidateCfv (
   IN UINT32  TdxCfvSize
   );
 
+/**
+  Measure the Hoblist passed from the VMM.
+
+  @param[in] VmmHobList    The Hoblist pass the firmware
+
+  @retval EFI_SUCCESS           Fv image is measured successfully
+                                or it has been already measured.
+  @retval Others                Other errors as indicated
+**/
+EFI_STATUS
+EFIAPI
+MeasureHobList (
+  IN CONST VOID  *VmmHobList
+  );
+
+/**
+  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
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
index c5d291f02bcd..def50b4b019e 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
@@ -58,7 +58,7 @@
   QemuFwCfgLib
   PlatformInitLib
   HashLib
-  SecMeasurementLib
+  TpmMeasurementLib
 
 [Guids]
   gEfiHobMemoryAllocModuleGuid
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#90210): https://edk2.groups.io/g/devel/message/90210
Mute This Topic: https://groups.io/mt/91551452/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-