]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/TcgDxe/TcgDxe.c
Add performance optimization for Tcg/TrEE.
[mirror_edk2.git] / SecurityPkg / Tcg / TcgDxe / TcgDxe.c
index 4b5380ba87fb5b4031ca2f4995d8f87d8b860669..f15e94353c686d622836e2f97238c5961df1bce9 100644 (file)
@@ -1,7 +1,14 @@
 /** @file  \r
   This module implements TCG EFI Protocol.\r
-  \r
-Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
\r
+Caution: This module requires additional review when modified.\r
+This driver will have external input - TcgDxePassThroughToTpm\r
+This external input must be validated carefully to avoid security issue like\r
+buffer overflow, integer overflow.\r
+\r
+TcgDxePassThroughToTpm() will receive untrusted input and do basic validation.\r
+\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
@@ -17,15 +24,20 @@ 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
 #include <Guid/HobList.h>\r
 #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
@@ -39,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
@@ -150,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
@@ -203,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
@@ -344,9 +406,13 @@ TcgDxeLogEvent (
 {\r
   TCG_DXE_DATA  *TcgData;\r
 \r
+  if (TCGLogData == NULL){\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\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
@@ -383,6 +449,13 @@ TcgDxePassThroughToTpm (
 {\r
   TCG_DXE_DATA                      *TcgData;\r
 \r
+  if (TpmInputParameterBlock == NULL || \r
+      TpmOutputParameterBlock == NULL || \r
+      TpmInputParameterBlockSize == 0 ||\r
+      TpmOutputParameterBlockSize == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
 \r
   return TisPcExecute (\r
@@ -423,13 +496,20 @@ TcgDxeHashLogExtendEventI (
 {\r
   EFI_STATUS                        Status;\r
 \r
-  if (HashDataLen > 0) {\r
+  if (!TcgData->BsCap.TPMPresentFlag) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if (HashDataLen > 0 || HashData != NULL) {\r
     Status = TpmCommHashAll (\r
                HashData,\r
                (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
@@ -442,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
@@ -482,24 +573,39 @@ TcgDxeHashLogExtendEvent (
   )\r
 {\r
   TCG_DXE_DATA  *TcgData;\r
+  EFI_STATUS    Status;\r
+\r
+  if (TCGLogData == NULL || EventLogLastEntry == NULL){\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \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
@@ -645,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
@@ -674,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
@@ -898,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
@@ -969,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
@@ -997,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
@@ -1028,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
@@ -1035,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
@@ -1050,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
@@ -1065,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
@@ -1092,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
@@ -1100,7 +1263,38 @@ 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
+  Exit Boot Services Failed Event notification handler.\r
+\r
+  Measure Failure of ExitBootServices.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+OnExitBootServicesFailed (\r
+  IN      EFI_EVENT                 Event,\r
+  IN      VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  //\r
+  // Measure Failure of ExitBootServices,\r
+  //\r
+  Status = TcgMeasureAction (\r
+             EFI_EXIT_BOOT_SERVICES_FAILED\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
@@ -1156,6 +1350,16 @@ 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
+  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
+    DEBUG ((EFI_D_ERROR, "TPM error!\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
   Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);\r
   if (EFI_ERROR (Status)) {\r
@@ -1180,7 +1384,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
@@ -1205,6 +1409,18 @@ DriverEntry (
                     &gEfiEventExitBootServicesGuid,\r
                     &Event\r
                     );\r
+\r
+    //\r
+    // Measure Exit Boot Service failed \r
+    //\r
+    Status = gBS->CreateEventEx (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_NOTIFY,\r
+                    OnExitBootServicesFailed,\r
+                    NULL,\r
+                    &gEventExitBootServicesFailedGuid,\r
+                    &Event\r
+                    );\r
   }\r
 \r
   //\r