--- /dev/null
+/** @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