]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/TcgDxe/TcgDxe.c
Check in missing patch for TPM error handling.
[mirror_edk2.git] / SecurityPkg / Tcg / TcgDxe / TcgDxe.c
index 5ef34d0ba20418faa3ef6498f5cdfff2e1cf6e10..db7951cd9ad0f66ed26f207d31c2e41d2adef837 100644 (file)
@@ -8,7 +8,7 @@ buffer overflow, integer overflow.
 \r
 TcgDxePassThroughToTpm() will receive untrusted input and do basic validation.\r
 \r
-Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <IndustryStandard/Acpi.h>\r
 #include <IndustryStandard/PeImage.h>\r
 #include <IndustryStandard/SmBios.h>\r
+#include <IndustryStandard/TcpaAcpi.h>\r
 \r
 #include <Guid/GlobalVariable.h>\r
 #include <Guid/SmBios.h>\r
@@ -31,9 +32,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/TcgEventHob.h>\r
 #include <Guid/EventGroup.h>\r
 #include <Guid/EventExitBootServiceFailed.h>\r
+#include <Guid/TpmInstance.h>\r
+\r
 #include <Protocol/DevicePath.h>\r
 #include <Protocol/TcgService.h>\r
 #include <Protocol/AcpiTable.h>\r
+#include <Protocol/MpService.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -47,43 +51,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/TpmCommLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/UefiLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
 \r
 #include "TpmComm.h"\r
 \r
 #define  EFI_TCG_LOG_AREA_SIZE        0x10000\r
 \r
-#pragma pack (1)\r
-\r
-typedef struct _EFI_TCG_CLIENT_ACPI_TABLE {\r
-  EFI_ACPI_DESCRIPTION_HEADER       Header;\r
-  UINT16                            PlatformClass;\r
-  UINT32                            Laml;\r
-  EFI_PHYSICAL_ADDRESS              Lasa;\r
-} EFI_TCG_CLIENT_ACPI_TABLE;\r
-\r
-typedef struct _EFI_TCG_SERVER_ACPI_TABLE {\r
-  EFI_ACPI_DESCRIPTION_HEADER             Header;\r
-  UINT16                                  PlatformClass;\r
-  UINT16                                  Reserved0;\r
-  UINT64                                  Laml;\r
-  EFI_PHYSICAL_ADDRESS                    Lasa;\r
-  UINT16                                  SpecRev;\r
-  UINT8                                   DeviceFlags;\r
-  UINT8                                   InterruptFlags;\r
-  UINT8                                   Gpe;\r
-  UINT8                                   Reserved1[3];\r
-  UINT32                                  GlobalSysInt;\r
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  BaseAddress;\r
-  UINT32                                  Reserved2;\r
-  EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE  ConfigAddress;\r
-  UINT8                                   PciSegNum;\r
-  UINT8                                   PciBusNum;\r
-  UINT8                                   PciDevNum;\r
-  UINT8                                   PciFuncNum;\r
-} EFI_TCG_SERVER_ACPI_TABLE;\r
-\r
-#pragma pack ()\r
-\r
 #define TCG_DXE_DATA_FROM_THIS(this)  \\r
   BASE_CR (this, TCG_DXE_DATA, TcgProtocol)\r
 \r
@@ -158,6 +131,87 @@ EFI_TCG_SERVER_ACPI_TABLE           mTcgServerAcpiTemplate = {
 UINTN  mBootAttempts  = 0;\r
 CHAR16 mBootVarName[] = L"BootOrder";\r
 \r
+/**\r
+  Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
+  Caller is responsible to free LocationBuf.\r
+\r
+  @param[out] LocationBuf          Returns Processor Location Buffer.\r
+  @param[out] Num                  Returns processor number.\r
+\r
+  @retval EFI_SUCCESS              Operation completed successfully.\r
+  @retval EFI_UNSUPPORTED       MpService protocol not found.\r
+\r
+**/\r
+EFI_STATUS\r
+GetProcessorsCpuLocation (\r
+    OUT  EFI_CPU_PHYSICAL_LOCATION   **LocationBuf,\r
+    OUT  UINTN                       *Num\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_MP_SERVICES_PROTOCOL          *MpProtocol;\r
+  UINTN                             ProcessorNum;\r
+  UINTN                             EnabledProcessorNum;\r
+  EFI_PROCESSOR_INFORMATION         ProcessorInfo;\r
+  EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;\r
+  UINTN                             Index;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // MP protocol is not installed\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = MpProtocol->GetNumberOfProcessors(\r
+                         MpProtocol,\r
+                         &ProcessorNum,\r
+                         &EnabledProcessorNum\r
+                         );\r
+  if (EFI_ERROR(Status)){\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->AllocatePool(\r
+                  EfiBootServicesData,\r
+                  sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
+                  (VOID **) &ProcessorLocBuf\r
+                  );\r
+  if (EFI_ERROR(Status)){\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get each processor Location info\r
+  //\r
+  for (Index = 0; Index < ProcessorNum; Index++) {\r
+    Status = MpProtocol->GetProcessorInfo(\r
+                           MpProtocol,\r
+                           Index,\r
+                           &ProcessorInfo\r
+                           );\r
+    if (EFI_ERROR(Status)){\r
+      FreePool(ProcessorLocBuf);\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Get all Processor Location info & measure\r
+    //\r
+    CopyMem(\r
+      &ProcessorLocBuf[Index],\r
+      &ProcessorInfo.Location,\r
+      sizeof(EFI_CPU_PHYSICAL_LOCATION)\r
+      );\r
+  }\r
+\r
+  *LocationBuf = ProcessorLocBuf;\r
+  *Num = ProcessorNum;\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   This service provides EFI protocol capability information, state information \r
   about the TPM, and Event Log state information.\r
@@ -211,7 +265,7 @@ TcgDxeStatusCheck (
   }\r
 \r
   if (EventLogLastEntry != NULL) {\r
-    if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+    if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
       *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
     } else {\r
       *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)TcgData->LastEvent;\r
@@ -358,7 +412,7 @@ TcgDxeLogEvent (
 \r
   TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
   \r
-  if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+  if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
   return TcgDxeLogEventI (\r
@@ -442,8 +496,8 @@ TcgDxeHashLogExtendEventI (
 {\r
   EFI_STATUS                        Status;\r
 \r
-  if (HashData == NULL && HashDataLen > 0) {\r
-    return EFI_INVALID_PARAMETER;\r
+  if (!TcgData->BsCap.TPMPresentFlag) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   if (HashDataLen > 0 || HashData != NULL) {\r
@@ -452,7 +506,10 @@ TcgDxeHashLogExtendEventI (
                (UINTN) HashDataLen,\r
                &NewEventHdr->Digest\r
                );\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG ((DEBUG_ERROR, "TpmCommHashAll Failed. %x\n", Status));\r
+      goto Done;\r
+    }\r
   }\r
 \r
   Status = TpmCommExtend (\r
@@ -465,6 +522,17 @@ TcgDxeHashLogExtendEventI (
     Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData);\r
   }\r
 \r
+Done:\r
+  if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) {\r
+    DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEventI - %r. Disable TPM.\n", Status));\r
+    TcgData->BsCap.TPMPresentFlag = FALSE;\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
+      );\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -505,6 +573,7 @@ TcgDxeHashLogExtendEvent (
   )\r
 {\r
   TCG_DXE_DATA  *TcgData;\r
+  EFI_STATUS    Status;\r
 \r
   if (TCGLogData == NULL || EventLogLastEntry == NULL){\r
     return EFI_INVALID_PARAMETER;\r
@@ -512,21 +581,31 @@ TcgDxeHashLogExtendEvent (
 \r
   TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
   \r
-  if (TcgData->BsCap.TPMDeactivatedFlag) {\r
+  if (TcgData->BsCap.TPMDeactivatedFlag || (!TcgData->BsCap.TPMPresentFlag)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
     \r
   if (AlgorithmId != TPM_ALG_SHA) {\r
     return EFI_UNSUPPORTED;\r
   }\r
+  \r
+  if (HashData == 0 && HashDataLen > 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
-  return TcgDxeHashLogExtendEventI (\r
-           TcgData,\r
-           (UINT8 *) (UINTN) HashData,\r
-           HashDataLen,\r
-           (TCG_PCR_EVENT_HDR*)TCGLogData,\r
-           TCGLogData->Event\r
-           );\r
+  Status = TcgDxeHashLogExtendEventI (\r
+             TcgData,\r
+             (UINT8 *) (UINTN) HashData,\r
+             HashDataLen,\r
+             (TCG_PCR_EVENT_HDR*)TCGLogData,\r
+             TCGLogData->Event\r
+             );\r
+\r
+  if (!EFI_ERROR(Status)){\r
+    *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN) TcgData->LastEvent;\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 TCG_DXE_DATA                 mTcgDxeData = {\r
@@ -672,15 +751,20 @@ MeasureHandoffTables (
   SMBIOS_TABLE_ENTRY_POINT          *SmbiosTable;\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
   EFI_HANDOFF_TABLE_POINTERS        HandoffTables;\r
+  UINTN                             ProcessorNum;\r
+  EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;\r
+\r
+  ProcessorLocBuf = NULL;\r
 \r
+  //\r
+  // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]\r
+  //\r
   Status = EfiGetSystemConfigurationTable (\r
              &gEfiSmbiosTableGuid,\r
              (VOID **) &SmbiosTable\r
              );\r
 \r
-  if (!EFI_ERROR (Status)) {\r
-    ASSERT (SmbiosTable != NULL);\r
-\r
+  if (!EFI_ERROR (Status) && SmbiosTable != NULL) {\r
     TcgEvent.PCRIndex  = 1;\r
     TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;\r
     TcgEvent.EventSize = sizeof (HandoffTables);\r
@@ -701,6 +785,34 @@ MeasureHandoffTables (
                );\r
   }\r
 \r
+  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
+    //\r
+    // Tcg Server spec. \r
+    // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
+    //\r
+    Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
+\r
+    if (!EFI_ERROR(Status)){\r
+      TcgEvent.PCRIndex  = 1;\r
+      TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
+      TcgEvent.EventSize = sizeof (HandoffTables);\r
+\r
+      HandoffTables.NumberOfTables = 1;\r
+      HandoffTables.TableEntry[0].VendorGuid  = gEfiMpServiceProtocolGuid;\r
+      HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
+\r
+      Status = TcgDxeHashLogExtendEventI (\r
+                 &mTcgDxeData,\r
+                 (UINT8*)(UINTN)ProcessorLocBuf,\r
+                 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
+                 &TcgEvent,\r
+                 (UINT8*)&HandoffTables\r
+                 );\r
+\r
+      FreePool(ProcessorLocBuf);\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -925,12 +1037,14 @@ MeasureAllBootVariables (
              &BootCount,\r
              (VOID **) &BootOrder\r
              );\r
-  if (Status == EFI_NOT_FOUND) {\r
+  if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
     return EFI_SUCCESS;\r
   }\r
-  ASSERT (BootOrder != NULL);\r
 \r
   if (EFI_ERROR (Status)) {\r
+    //\r
+    // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
+    //\r
     FreePool (BootOrder);\r
     return Status;\r
   }\r
@@ -996,14 +1110,18 @@ OnReadyToBoot (
     Status = TcgMeasureAction (\r
                EFI_CALLING_EFI_APPLICATION\r
                );\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
+    }\r
 \r
     //\r
     // 2. Draw a line between pre-boot env and entering post-boot env.\r
     //\r
     for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {\r
       Status = MeasureSeparatorEvent (PcrIndex);\r
-      ASSERT_EFI_ERROR (Status);\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
+      }\r
     }\r
 \r
     //\r
@@ -1024,7 +1142,9 @@ OnReadyToBoot (
     Status = TcgMeasureAction (\r
                EFI_RETURNING_FROM_EFI_APPLICATOIN\r
                );\r
-    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
+    }\r
   }\r
 \r
   DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n"));\r
@@ -1055,6 +1175,7 @@ InstallAcpiTable (
   EFI_STATUS                        Status;\r
   EFI_ACPI_TABLE_PROTOCOL           *AcpiTable;\r
   UINT8                             Checksum;\r
+  UINT64                            OemTableId;\r
 \r
   Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);\r
   if (EFI_ERROR (Status)) {\r
@@ -1062,7 +1183,12 @@ InstallAcpiTable (
   }\r
 \r
   if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
\r
+    CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));\r
+    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+    CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
+    mTcgClientAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+    mTcgClientAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+    mTcgClientAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
     //\r
     // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
     // service of the ACPI table protocol to install it.\r
@@ -1077,7 +1203,12 @@ InstallAcpiTable (
                             &TableKey\r
                             );\r
   } else {\r
-\r
+    CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));\r
+    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
+    CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
+    mTcgServerAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);\r
+    mTcgServerAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);\r
+    mTcgServerAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
     //\r
     // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
     // service of the ACPI table protocol to install it.\r
@@ -1092,7 +1223,10 @@ InstallAcpiTable (
                             &TableKey\r
                             );\r
   }\r
-  ASSERT_EFI_ERROR (Status);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));\r
+  }\r
 }\r
 \r
 /**\r
@@ -1119,7 +1253,9 @@ OnExitBootServices (
   Status = TcgMeasureAction (\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
+  }\r
 \r
   //\r
   // Measure success of ExitBootServices\r
@@ -1127,7 +1263,9 @@ OnExitBootServices (
   Status = TcgMeasureAction (\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
-  ASSERT_EFI_ERROR (Status);\r
+  if (EFI_ERROR (Status)){\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
+  }\r
 }\r
 \r
 /**\r
@@ -1154,8 +1292,9 @@ OnExitBootServicesFailed (
   Status = TcgMeasureAction (\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
+  if (EFI_ERROR (Status)){\r
+    DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
+  }\r
 }\r
 \r
 /**\r
@@ -1211,6 +1350,11 @@ DriverEntry (
   EFI_EVENT                         Event;\r
   VOID                              *Registration;\r
 \r
+  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
+    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
   Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);\r
   if (EFI_ERROR (Status)) {\r
@@ -1218,6 +1362,10 @@ DriverEntry (
     return Status;\r
   }\r
 \r
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    mTcgDxeData.BsCap.TPMPresentFlag = FALSE;\r
+  }\r
+\r
   Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((\r
@@ -1235,7 +1383,7 @@ DriverEntry (
                   EFI_NATIVE_INTERFACE,\r
                   &mTcgDxeData.TcgProtocol\r
                   );\r
-  if (!EFI_ERROR (Status) && !mTcgDxeData.BsCap.TPMDeactivatedFlag) {\r
+  if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) {\r
     //\r
     // Setup the log area and copy event log from hob list to it\r
     //\r