]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
OvmfPkg: Refactor MeasureHobList
[mirror_edk2.git] / OvmfPkg / IntelTdx / TdxHelperLib / TdxMeasurementHob.c
diff --git a/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c b/OvmfPkg/IntelTdx/TdxHelperLib/TdxMeasurementHob.c
new file mode 100644 (file)
index 0000000..6cbc760
--- /dev/null
@@ -0,0 +1,173 @@
+/** @file\r
+  Build GuidHob for tdx measurement.\r
+\r
+  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <IndustryStandard/UefiTcgPlatform.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <WorkArea.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
+#pragma pack()\r
+\r
+/**\r
+ * Build GuidHob for Tdx measurement.\r
+ *\r
+ * Tdx measurement includes the measurement of TdHob and CFV. They're measured\r
+ * and extended to RTMR registers in SEC phase. Because at that moment the Hob\r
+ * service are not available. So the values of the measurement are saved in\r
+ * workarea and will be built into GuidHob after the Hob service is ready.\r
+ *\r
+ * @param RtmrIndex     RTMR index\r
+ * @param EventType     Event type\r
+ * @param EventData     Event data\r
+ * @param EventSize     Size of event data\r
+ * @param HashValue     Hash value\r
+ * @param HashSize      Size of hash\r
+ *\r
+ * @retval EFI_SUCCESS  Successfully build the GuidHobs\r
+ * @retval Others       Other error as indicated\r
+ */\r
+STATIC\r
+EFI_STATUS\r
+BuildTdxMeasurementGuidHob (\r
+  UINT32  RtmrIndex,\r
+  UINT32  EventType,\r
+  UINT8   *EventData,\r
+  UINT32  EventSize,\r
+  UINT8   *HashValue,\r
+  UINT32  HashSize\r
+  )\r
+{\r
+  VOID                *EventHobData;\r
+  UINT8               *Ptr;\r
+  TPML_DIGEST_VALUES  *TdxDigest;\r
+\r
+  if (HashSize != SHA384_DIGEST_SIZE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  #define TDX_DIGEST_VALUE_LEN  (sizeof (UINT32) + sizeof (TPMI_ALG_HASH) + SHA384_DIGEST_SIZE)\r
+\r
+  EventHobData = BuildGuidHob (\r
+                   &gCcEventEntryHobGuid,\r
+                   sizeof (TCG_PCRINDEX) + sizeof (TCG_EVENTTYPE) +\r
+                   TDX_DIGEST_VALUE_LEN +\r
+                   sizeof (UINT32) + EventSize\r
+                   );\r
+\r
+  if (EventHobData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Ptr = (UINT8 *)EventHobData;\r
+\r
+  //\r
+  // There are 2 types of measurement registers in TDX: MRTD and RTMR[0-3].\r
+  // According to UEFI Spec 2.10 Section 38.4.1, RTMR[0-3] is mapped to MrIndex[1-4].\r
+  // So RtmrIndex must be increased by 1 before the event log is created.\r
+  //\r
+  RtmrIndex++;\r
+  CopyMem (Ptr, &RtmrIndex, sizeof (UINT32));\r
+  Ptr += sizeof (UINT32);\r
+\r
+  CopyMem (Ptr, &EventType, sizeof (TCG_EVENTTYPE));\r
+  Ptr += sizeof (TCG_EVENTTYPE);\r
+\r
+  TdxDigest                     = (TPML_DIGEST_VALUES *)Ptr;\r
+  TdxDigest->count              = 1;\r
+  TdxDigest->digests[0].hashAlg = TPM_ALG_SHA384;\r
+  CopyMem (\r
+    TdxDigest->digests[0].digest.sha384,\r
+    HashValue,\r
+    SHA384_DIGEST_SIZE\r
+    );\r
+  Ptr += TDX_DIGEST_VALUE_LEN;\r
+\r
+  CopyMem (Ptr, &EventSize, sizeof (UINT32));\r
+  Ptr += sizeof (UINT32);\r
+\r
+  CopyMem (Ptr, (VOID *)EventData, EventSize);\r
+  Ptr += EventSize;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Build the GuidHob for tdx measurements which were done in SEC phase.\r
+  The measurement values are stored in WorkArea.\r
+\r
+  @retval EFI_SUCCESS  The GuidHob is built successfully\r
+  @retval Others       Other errors as indicated\r
+**/\r
+EFI_STATUS\r
+InternalBuildGuidHobForTdxMeasurement (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  OVMF_WORK_AREA               *WorkArea;\r
+  VOID                         *TdHobList;\r
+  TDX_HANDOFF_TABLE_POINTERS2  HandoffTables;\r
+  UINT8                        *HashValue;\r
+\r
+  if (!TdIsEnabled ()) {\r
+    ASSERT (FALSE);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);\r
+  if (WorkArea == NULL) {\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Build the GuidHob for TdHob measurement\r
+  //\r
+  TdHobList = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
+  if (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap & TDX_MEASUREMENT_TDHOB_BITMASK) {\r
+    HashValue                          = WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.TdHobHashValue;\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 = TdHobList;\r
+\r
+    Status = BuildTdxMeasurementGuidHob (\r
+               0,                               // RtmrIndex\r
+               EV_EFI_HANDOFF_TABLES2,          // EventType\r
+               (UINT8 *)(UINTN)&HandoffTables,  // EventData\r
+               sizeof (HandoffTables),          // EventSize\r
+               HashValue,                       // HashValue\r
+               SHA384_DIGEST_SIZE               // HashSize\r
+               );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ASSERT (FALSE);\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r