]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.c
Security: Add SecTpmMeasurementLibTdx
[mirror_edk2.git] / SecurityPkg / Library / SecTpmMeasurementLib / SecTpmMeasurementLibTdx.c
diff --git a/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.c b/SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.c
new file mode 100644 (file)
index 0000000..38887b1
--- /dev/null
@@ -0,0 +1,176 @@
+/** @file\r
+  This library is used by other modules to measure data to TPM.\r
+\r
+Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Guid/CcEventHob.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HashLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <Protocol/CcMeasurement.h>\r
+#include <Library/TpmMeasurementLib.h>\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  UINT32           Count;\r
+  TPMI_ALG_HASH    HashAlg;\r
+  BYTE             Sha384[SHA384_DIGEST_SIZE];\r
+} TDX_DIGEST_VALUE;\r
+\r
+#pragma pack()\r
+\r
+#define INVALID_PCR2MR_INDEX  0xFF\r
+\r
+/**\r
+  Get the mapped RTMR index based on the input PCRIndex.\r
+  RTMR[0]  => PCR[1,7]\r
+  RTMR[1]  => PCR[2,3,4,5]\r
+  RTMR[2]  => PCR[8~15]\r
+  RTMR[3]  => NA\r
+  Note:\r
+    PCR[0] is mapped to MRTD and should not appear here.\r
+    PCR[6] is reserved for OEM. It is not used.\r
+\r
+   @param[in] PCRIndex The input PCR index\r
+\r
+   @retval UINT8   The mapped RTMR index.\r
+**/\r
+UINT8\r
+GetMappedRtmrIndex (\r
+  IN UINT32  PCRIndex\r
+  )\r
+{\r
+  UINT8  RtmrIndex;\r
+\r
+  if ((PCRIndex == 6) || (PCRIndex == 0) || (PCRIndex > 15)) {\r
+    DEBUG ((DEBUG_ERROR, "Invalid PCRIndex(%d) map to MR Index.\n", PCRIndex));\r
+    ASSERT (FALSE);\r
+    return INVALID_PCR2MR_INDEX;\r
+  }\r
+\r
+  RtmrIndex = 0;\r
+  if ((PCRIndex == 1) || (PCRIndex == 7)) {\r
+    RtmrIndex = 0;\r
+  } else if ((PCRIndex >= 2) && (PCRIndex < 6)) {\r
+    RtmrIndex = 1;\r
+  } else if ((PCRIndex >= 8) && (PCRIndex <= 15)) {\r
+    RtmrIndex = 2;\r
+  }\r
+\r
+  return RtmrIndex;\r
+}\r
+\r
+/**\r
+  Tpm measure and log data, and extend the measurement result into a specific PCR.\r
+\r
+  @param[in]  PcrIndex         PCR Index.\r
+  @param[in]  EventType        Event type.\r
+  @param[in]  EventLog         Measurement event log.\r
+  @param[in]  LogLen           Event log length in bytes.\r
+  @param[in]  HashData         The start of the data buffer to be hashed, extended.\r
+  @param[in]  HashDataLen      The length, in bytes, of the buffer referenced by HashData\r
+\r
+  @retval EFI_SUCCESS           Operation completed successfully.\r
+  @retval EFI_UNSUPPORTED       TPM device not available.\r
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TpmMeasureAndLogData (\r
+  IN UINT32  PcrIndex,\r
+  IN UINT32  EventType,\r
+  IN VOID    *EventLog,\r
+  IN UINT32  LogLen,\r
+  IN VOID    *HashData,\r
+  IN UINT64  HashDataLen\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  UINT32              RtmrIndex;\r
+  VOID                *EventHobData;\r
+  TCG_PCR_EVENT2      *TcgPcrEvent2;\r
+  UINT8               *DigestBuffer;\r
+  TDX_DIGEST_VALUE    *TdxDigest;\r
+  TPML_DIGEST_VALUES  DigestList;\r
+  UINT8               *Ptr;\r
+\r
+  if (!TdIsEnabled ()) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  RtmrIndex = GetMappedRtmrIndex (PcrIndex);\r
+  if (RtmrIndex == INVALID_PCR2MR_INDEX) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "Creating TdTcg2PcrEvent PCR[%d]/RTMR[%d] EventType 0x%x\n", PcrIndex, RtmrIndex, EventType));\r
+\r
+  Status = HashAndExtend (\r
+             RtmrIndex,\r
+             (VOID *)HashData,\r
+             HashDataLen,\r
+             &DigestList\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "Failed to HashAndExtend. %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Use TDX_DIGEST_VALUE in the GUID HOB DataLength calculation\r
+  // to reserve enough buffer to hold TPML_DIGEST_VALUES compact binary\r
+  // which is limited to a SHA384 digest list\r
+  //\r
+  EventHobData = BuildGuidHob (\r
+                   &gCcEventEntryHobGuid,\r
+                   sizeof (TcgPcrEvent2->PCRIndex) + sizeof (TcgPcrEvent2->EventType) +\r
+                   sizeof (TDX_DIGEST_VALUE) +\r
+                   sizeof (TcgPcrEvent2->EventSize) + LogLen\r
+                   );\r
+\r
+  if (EventHobData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Ptr = (UINT8 *)EventHobData;\r
+  //\r
+  // Initialize PcrEvent data now\r
+  //\r
+  RtmrIndex++;\r
+  CopyMem (Ptr, &RtmrIndex, sizeof (UINT32));\r
+  Ptr += sizeof (UINT32);\r
+  CopyMem (Ptr, &EventType, sizeof (TCG_EVENTTYPE));\r
+  Ptr += sizeof (TCG_EVENTTYPE);\r
+\r
+  DigestBuffer = Ptr;\r
+\r
+  TdxDigest          = (TDX_DIGEST_VALUE *)DigestBuffer;\r
+  TdxDigest->Count   = 1;\r
+  TdxDigest->HashAlg = TPM_ALG_SHA384;\r
+  CopyMem (\r
+    TdxDigest->Sha384,\r
+    DigestList.digests[0].digest.sha384,\r
+    SHA384_DIGEST_SIZE\r
+    );\r
+\r
+  Ptr += sizeof (TDX_DIGEST_VALUE);\r
+\r
+  CopyMem (Ptr, &LogLen, sizeof (UINT32));\r
+  Ptr += sizeof (UINT32);\r
+  CopyMem (Ptr, EventLog, LogLen);\r
+  Ptr += LogLen;\r
+\r
+  Status = EFI_SUCCESS;\r
+  return Status;\r
+}\r