]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: Implement MeasureHobList/MeasureFvImage
authorMin M Xu <min.m.xu@intel.com>
Sun, 5 Jun 2022 01:02:47 +0000 (09:02 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 7 Jun 2022 11:05:53 +0000 (11:05 +0000)
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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
OvmfPkg/IntelTdx/IntelTdxX64.dsc
OvmfPkg/Library/PeilessStartupLib/IntelTdx.c
OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h
OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf

index 43ab8bd089d9cc82e6eb4fa3ac40adcadd102d56..a40f7228b98e8d1f2b78ea14b2468142974f8f24 100644 (file)
   OvmfPkg/IntelTdx/Sec/SecMain.inf {\r
     <LibraryClasses>\r
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf\r
-      SecMeasurementLib|OvmfPkg/Library/SecMeasurementLib/SecMeasurementLibTdx.inf\r
+      TpmMeasurementLib|SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf\r
       BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf\r
       HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf\r
       NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf\r
index d240d3b7719fe046c9f2b6cd892b4ffa5e0f430f..484fd21057c8f4a67258c05a63297fc571a51e0b 100644 (file)
@@ -9,8 +9,34 @@
 #include <Library/DebugLib.h>\r
 #include <Guid/VariableFormat.h>\r
 #include <Guid/SystemNvDataGuid.h>\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/TpmMeasurementLib.h>\r
+\r
 #include "PeilessStartupInternal.h"\r
 \r
+#pragma pack(1)\r
+\r
+#define HANDOFF_TABLE_DESC  "TdxTable"\r
+typedef struct {\r
+  UINT8                      TableDescriptionSize;\r
+  UINT8                      TableDescription[sizeof (HANDOFF_TABLE_DESC)];\r
+  UINT64                     NumberOfTables;\r
+  EFI_CONFIGURATION_TABLE    TableEntry[1];\r
+} TDX_HANDOFF_TABLE_POINTERS2;\r
+\r
+#define FV_HANDOFF_TABLE_DESC  "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"\r
+typedef struct {\r
+  UINT8                   BlobDescriptionSize;\r
+  UINT8                   BlobDescription[sizeof (FV_HANDOFF_TABLE_DESC)];\r
+  EFI_PHYSICAL_ADDRESS    BlobBase;\r
+  UINT64                  BlobLength;\r
+} FV_HANDOFF_TABLE_POINTERS2;\r
+\r
+#pragma pack()\r
+\r
 /**\r
   Check padding data all bit should be 1.\r
 \r
@@ -161,3 +187,163 @@ TdxValidateCfv (
 \r
   return TRUE;\r
 }\r
+\r
+/**\r
+  Measure the Hoblist passed from the VMM.\r
+\r
+  @param[in] VmmHobList    The Hoblist pass the firmware\r
+\r
+  @retval EFI_SUCCESS           Fv image is measured successfully\r
+                                or it has been already measured.\r
+  @retval Others                Other errors as indicated\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MeasureHobList (\r
+  IN CONST VOID  *VmmHobList\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS         Hob;\r
+  TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;\r
+  EFI_STATUS                   Status;\r
+\r
+  if (!TdIsEnabled ()) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Hob.Raw = (UINT8 *)VmmHobList;\r
+\r
+  //\r
+  // Parse the HOB list until end of list.\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+\r
+  //\r
+  // Init the log event for HOB measurement\r
+  //\r
+\r
+  HandoffTables.TableDescriptionSize = sizeof (HandoffTables.TableDescription);\r
+  CopyMem (HandoffTables.TableDescription, HANDOFF_TABLE_DESC, sizeof (HandoffTables.TableDescription));\r
+  HandoffTables.NumberOfTables = 1;\r
+  CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), &gUefiOvmfPkgTokenSpaceGuid);\r
+  HandoffTables.TableEntry[0].VendorTable = (VOID *)VmmHobList;\r
+\r
+  Status = TpmMeasureAndLogData (\r
+             1,                                              // PCRIndex\r
+             EV_EFI_HANDOFF_TABLES2,                         // EventType\r
+             (VOID *)&HandoffTables,                         // EventData\r
+             sizeof (HandoffTables),                         // EventSize\r
+             (UINT8 *)(UINTN)VmmHobList,                     // HashData\r
+             (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)VmmHobList) // HashDataLen\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get the FvName from the FV header.\r
+\r
+  Causion: The FV is untrusted input.\r
+\r
+  @param[in]  FvBase            Base address of FV image.\r
+  @param[in]  FvLength          Length of FV image.\r
+\r
+  @return FvName pointer\r
+  @retval NULL   FvName is NOT found\r
+**/\r
+VOID *\r
+GetFvName (\r
+  IN EFI_PHYSICAL_ADDRESS  FvBase,\r
+  IN UINT64                FvLength\r
+  )\r
+{\r
+  EFI_FIRMWARE_VOLUME_HEADER      *FvHeader;\r
+  EFI_FIRMWARE_VOLUME_EXT_HEADER  *FvExtHeader;\r
+\r
+  if (FvBase >= MAX_ADDRESS) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvLength >= MAX_ADDRESS - FvBase) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvLength < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {\r
+    return NULL;\r
+  }\r
+\r
+  FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvBase;\r
+  if (FvHeader->ExtHeaderOffset < sizeof (EFI_FIRMWARE_VOLUME_HEADER)) {\r
+    return NULL;\r
+  }\r
+\r
+  if (FvHeader->ExtHeaderOffset + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {\r
+    return NULL;\r
+  }\r
+\r
+  FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);\r
+\r
+  return &FvExtHeader->FvName;\r
+}\r
+\r
+/**\r
+  Measure FV image.\r
+\r
+  @param[in]  FvBase            Base address of FV image.\r
+  @param[in]  FvLength          Length of FV image.\r
+  @param[in]  PcrIndex          Index of PCR\r
+\r
+  @retval EFI_SUCCESS           Fv image is measured successfully\r
+                                or it has been already measured.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MeasureFvImage (\r
+  IN EFI_PHYSICAL_ADDRESS  FvBase,\r
+  IN UINT64                FvLength,\r
+  IN UINT8                 PcrIndex\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  FV_HANDOFF_TABLE_POINTERS2  FvBlob2;\r
+  VOID                        *FvName;\r
+\r
+  //\r
+  // Init the log event for FV measurement\r
+  //\r
+  FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);\r
+  CopyMem (FvBlob2.BlobDescription, FV_HANDOFF_TABLE_DESC, sizeof (FvBlob2.BlobDescription));\r
+  FvName = GetFvName (FvBase, FvLength);\r
+  if (FvName != NULL) {\r
+    AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof (FvBlob2.BlobDescription), "Fv(%g)", FvName);\r
+  }\r
+\r
+  FvBlob2.BlobBase   = FvBase;\r
+  FvBlob2.BlobLength = FvLength;\r
+\r
+  Status = TpmMeasureAndLogData (\r
+             1,                              // PCRIndex\r
+             EV_EFI_PLATFORM_FIRMWARE_BLOB2, // EventType\r
+             (VOID *)&FvBlob2,               // EventData\r
+             sizeof (FvBlob2),               // EventSize\r
+             (UINT8 *)(UINTN)FvBase,         // HashData\r
+             (UINTN)(FvLength)               // HashDataLen\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "The FV which failed to be measured starts at: 0x%x\n", FvBase));\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  return Status;\r
+}\r
index 54236b956c52547092f121da4e165482ac85f374..fdfefd00d7329fd822abb0abfe13a496934b2fec 100644 (file)
@@ -20,7 +20,6 @@
 #include <ConfidentialComputingGuestAttr.h>\r
 #include <Guid/MemoryTypeInformation.h>\r
 #include <OvmfPlatforms.h>\r
-#include <Library/SecMeasurementLib.h>\r
 #include "PeilessStartupInternal.h"\r
 \r
 #define GET_GPAW_INIT_STATE(INFO)  ((UINT8) ((INFO) & 0x3f))\r
index dd79b8a06b44fa250bb4d525a6acb35ea79b9223..74b5f46552c2ff0878d66af47d1284792ebf4f6f 100644 (file)
@@ -69,4 +69,40 @@ TdxValidateCfv (
   IN UINT32  TdxCfvSize\r
   );\r
 \r
+/**\r
+  Measure the Hoblist passed from the VMM.\r
+\r
+  @param[in] VmmHobList    The Hoblist pass the firmware\r
+\r
+  @retval EFI_SUCCESS           Fv image is measured successfully\r
+                                or it has been already measured.\r
+  @retval Others                Other errors as indicated\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MeasureHobList (\r
+  IN CONST VOID  *VmmHobList\r
+  );\r
+\r
+/**\r
+  Measure FV image.\r
+\r
+  @param[in]  FvBase            Base address of FV image.\r
+  @param[in]  FvLength          Length of FV image.\r
+  @param[in]  PcrIndex          Index of PCR\r
+\r
+  @retval EFI_SUCCESS           Fv image is measured successfully\r
+                                or it has been already measured.\r
+  @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
+  @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MeasureFvImage (\r
+  IN EFI_PHYSICAL_ADDRESS  FvBase,\r
+  IN UINT64                FvLength,\r
+  IN UINT8                 PcrIndex\r
+  );\r
+\r
 #endif\r
index c5d291f02bcd9808d6ba9097ebe1717ba946a592..def50b4b019e2ef8595fb21382dd0c9425cdb3f3 100644 (file)
@@ -58,7 +58,7 @@
   QemuFwCfgLib\r
   PlatformInitLib\r
   HashLib\r
-  SecMeasurementLib\r
+  TpmMeasurementLib\r
 \r
 [Guids]\r
   gEfiHobMemoryAllocModuleGuid\r