]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg/TcgEventLogRecordLib: add new lib for firmware measurement
authorQi Zhang <qi1.zhang@intel.com>
Tue, 18 Aug 2020 06:26:11 +0000 (14:26 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 26 Aug 2020 15:56:11 +0000 (15:56 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2376

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
Message-Id: <20200818062618.3698-2-qi1.zhang@intel.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
SecurityPkg/Include/Library/TcgEventLogRecordLib.h [new file with mode: 0644]
SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.c [new file with mode: 0644]
SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf [new file with mode: 0644]
SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.uni [new file with mode: 0644]

diff --git a/SecurityPkg/Include/Library/TcgEventLogRecordLib.h b/SecurityPkg/Include/Library/TcgEventLogRecordLib.h
new file mode 100644 (file)
index 0000000..99d634c
--- /dev/null
@@ -0,0 +1,97 @@
+/** @file\r
+  This library is used by other modules to measure Firmware 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
+#ifndef _TCG_EVENTLOGRECORD_LIB_H_\r
+#define _TCG_EVENTLOGRECORD_LIB_H_\r
+\r
+#include <Uefi.h>\r
+\r
+#pragma pack (1)\r
+\r
+#define PLATFORM_FIRMWARE_BLOB_DESC "Fv(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)"\r
+typedef struct {\r
+  UINT8                             BlobDescriptionSize;\r
+  UINT8                             BlobDescription[sizeof(PLATFORM_FIRMWARE_BLOB_DESC)];\r
+  EFI_PHYSICAL_ADDRESS              BlobBase;\r
+  UINT64                            BlobLength;\r
+} PLATFORM_FIRMWARE_BLOB2_STRUCT;\r
+\r
+#define HANDOFF_TABLE_POINTER_DESC  "1234567890ABCDEF"\r
+typedef struct {\r
+  UINT8                             TableDescriptionSize;\r
+  UINT8                             TableDescription[sizeof(HANDOFF_TABLE_POINTER_DESC)];\r
+  UINT64                            NumberOfTables;\r
+  EFI_CONFIGURATION_TABLE           TableEntry[1];\r
+} HANDOFF_TABLE_POINTERS2_STRUCT;\r
+\r
+#pragma pack ()\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
+TpmMeasurementGetFvName (\r
+  IN EFI_PHYSICAL_ADDRESS           FvBase,\r
+  IN UINT64                         FvLength\r
+  );\r
+\r
+/**\r
+  Measure a FirmwareBlob.\r
+\r
+  @param[in]  PcrIndex                PCR Index.\r
+  @param[in]  Description             Description for this FirmwareBlob.\r
+  @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.\r
+  @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.\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
+MeasureFirmwareBlob (\r
+  IN UINT32                         PcrIndex,\r
+  IN CHAR8                          *Description OPTIONAL,\r
+  IN EFI_PHYSICAL_ADDRESS           FirmwareBlobBase,\r
+  IN UINT64                         FirmwareBlobLength\r
+  );\r
+\r
+/**\r
+  Measure a HandoffTable.\r
+\r
+  @param[in]  PcrIndex                PcrIndex of the measurement.\r
+  @param[in]  Description             Description for this HandoffTable.\r
+  @param[in]  TableGuid               GUID of this HandoffTable.\r
+  @param[in]  TableAddress            Base address of this HandoffTable.\r
+  @param[in]  TableLength             Size in bytes of this HandoffTable.\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
+MeasureHandoffTable (\r
+  IN UINT32                         PcrIndex,\r
+  IN CHAR8                          *Description OPTIONAL,\r
+  IN EFI_GUID                       *TableGuid,\r
+  IN VOID                           *TableAddress,\r
+  IN UINTN                          TableLength\r
+  );\r
+\r
+#endif\r
diff --git a/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.c b/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.c
new file mode 100644 (file)
index 0000000..e8a53fc
--- /dev/null
@@ -0,0 +1,197 @@
+/** @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 <Uefi/UefiBaseType.h>\r
+#include <Pi/PiFirmwareVolume.h>\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/TcgEventLogRecordLib.h>\r
+#include <Library/TpmMeasurementLib.h>\r
+\r
+#include <IndustryStandard/UefiTcgPlatform.h>\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
+TpmMeasurementGetFvName (\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
+  if (FvLength >= MAX_ADDRESS - FvBase) {\r
+    return NULL;\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->Signature != EFI_FVH_SIGNATURE) {\r
+    return NULL;\r
+  }\r
+  if (FvHeader->ExtHeaderOffset < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {\r
+    return NULL;\r
+  }\r
+  if (FvHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER) > FvLength) {\r
+    return NULL;\r
+  }\r
+  FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(UINTN)(FvBase + FvHeader->ExtHeaderOffset);\r
+\r
+  return &FvExtHeader->FvName;\r
+}\r
+\r
+/**\r
+  Measure a FirmwareBlob.\r
+\r
+  @param[in]  PcrIndex                PcrIndex of the measurement.\r
+  @param[in]  Description             Description for this FirmwareBlob.\r
+  @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.\r
+  @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.\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
+MeasureFirmwareBlob (\r
+  IN UINT32                         PcrIndex,\r
+  IN CHAR8                          *Description OPTIONAL,\r
+  IN EFI_PHYSICAL_ADDRESS           FirmwareBlobBase,\r
+  IN UINT64                         FirmwareBlobLength\r
+  )\r
+{\r
+  EFI_PLATFORM_FIRMWARE_BLOB        FvBlob;\r
+  PLATFORM_FIRMWARE_BLOB2_STRUCT    FvBlob2;\r
+  VOID                              *FvName;\r
+  UINT32                            EventType;\r
+  VOID                              *EventLog;\r
+  UINT32                            EventLogSize;\r
+  EFI_STATUS                        Status;\r
+\r
+  FvName = TpmMeasurementGetFvName (FirmwareBlobBase, FirmwareBlobLength);\r
+\r
+  if (((Description != NULL) || (FvName != NULL)) &&\r
+      (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {\r
+    if (Description != NULL) {\r
+      AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "%a", Description);\r
+    } else {\r
+      AsciiSPrint((CHAR8*)FvBlob2.BlobDescription, sizeof(FvBlob2.BlobDescription), "Fv(%g)", FvName);\r
+    }\r
+\r
+    FvBlob2.BlobDescriptionSize = sizeof(FvBlob2.BlobDescription);\r
+    FvBlob2.BlobBase = FirmwareBlobBase;\r
+    FvBlob2.BlobLength = FirmwareBlobLength;\r
+\r
+    EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB2;\r
+    EventLog = &FvBlob2;\r
+    EventLogSize = sizeof(FvBlob2);\r
+  } else {\r
+    FvBlob.BlobBase = FirmwareBlobBase;\r
+    FvBlob.BlobLength = FirmwareBlobLength;\r
+\r
+    EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
+    EventLog = &FvBlob;\r
+    EventLogSize = sizeof(FvBlob);\r
+  }\r
+\r
+  Status = TpmMeasureAndLogData (\r
+             PcrIndex,\r
+             EventType,\r
+             EventLog,\r
+             EventLogSize,\r
+             (VOID*)(UINTN)FirmwareBlobBase,\r
+             FirmwareBlobLength\r
+             );\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Measure a HandoffTable.\r
+\r
+  @param[in]  PcrIndex                PcrIndex of the measurement.\r
+  @param[in]  Description             Description for this HandoffTable.\r
+  @param[in]  TableGuid               GUID of this HandoffTable.\r
+  @param[in]  TableAddress            Base address of this HandoffTable.\r
+  @param[in]  TableLength             Size in bytes of this HandoffTable.\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
+MeasureHandoffTable (\r
+  IN UINT32                         PcrIndex,\r
+  IN CHAR8                          *Description OPTIONAL,\r
+  IN EFI_GUID                       *TableGuid,\r
+  IN VOID                           *TableAddress,\r
+  IN UINTN                          TableLength\r
+  )\r
+{\r
+  EFI_HANDOFF_TABLE_POINTERS        HandoffTables;\r
+  HANDOFF_TABLE_POINTERS2_STRUCT    HandoffTables2;\r
+  UINT32                            EventType;\r
+  VOID                              *EventLog;\r
+  UINT32                            EventLogSize;\r
+  EFI_STATUS                        Status;\r
+\r
+  if ((Description != NULL) &&\r
+      (PcdGet32(PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105)) {\r
+    AsciiSPrint((CHAR8*)HandoffTables2.TableDescription, sizeof(HandoffTables2.TableDescription), "%a", Description);\r
+\r
+    HandoffTables2.TableDescriptionSize = sizeof(HandoffTables2.TableDescription);\r
+    HandoffTables2.NumberOfTables = 1;\r
+    CopyGuid (&(HandoffTables2.TableEntry[0].VendorGuid), TableGuid);\r
+    HandoffTables2.TableEntry[0].VendorTable = TableAddress;\r
+\r
+    EventType = EV_EFI_HANDOFF_TABLES2;\r
+    EventLog = &HandoffTables2;\r
+    EventLogSize = sizeof(HandoffTables2);\r
+  } else {\r
+    HandoffTables.NumberOfTables = 1;\r
+    CopyGuid (&(HandoffTables.TableEntry[0].VendorGuid), TableGuid);\r
+    HandoffTables.TableEntry[0].VendorTable = TableAddress;\r
+\r
+    EventType = EV_EFI_HANDOFF_TABLES;\r
+    EventLog = &HandoffTables;\r
+    EventLogSize = sizeof(HandoffTables);\r
+  }\r
+\r
+  Status = TpmMeasureAndLogData (\r
+             PcrIndex,\r
+             EventType,\r
+             EventLog,\r
+             EventLogSize,\r
+             TableAddress,\r
+             TableLength\r
+             );\r
+  return Status;\r
+}\r
diff --git a/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf b/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.inf
new file mode 100644 (file)
index 0000000..71388f4
--- /dev/null
@@ -0,0 +1,40 @@
+## @file\r
+#  Provides interface for firmwware TPM measurement\r
+#\r
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = TcgEventLogRecordLib\r
+  MODULE_UNI_FILE                = TcgEventLogRecordLib.uni\r
+  FILE_GUID                      = F8125B2A-3922-4A22-A6F8-3B6159A25A3B\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources]\r
+  TcgEventLogRecordLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PcdLib\r
+  TpmMeasurementLib\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision          ## CONSUMES\r
diff --git a/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.uni b/SecurityPkg/Library/TcgEventLogRecordLib/TcgEventLogRecordLib.uni
new file mode 100644 (file)
index 0000000..b1ca410
--- /dev/null
@@ -0,0 +1,17 @@
+// /** @file\r
+// Provides interface for firmwware TPM measurement\r
+//\r
+// This library provides MeasureFirmwareBlob() and MeasureHandoffTable()\r
+// to measure and log data, and extend the measurement result into a specific PCR.\r
+//\r
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT             #language en-US "Provides Firmware TPM measurement functions for TPM1.2 and TPM 2.0"\r
+\r
+#string STR_MODULE_DESCRIPTION          #language en-US "This library provides MeasureFirmwareBlob() and MeasureHandoffTable() to measure and log data, and extend the measurement result into a specific PCR."\r
+\r