]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg: Removing ipf which is no longer supported from edk2.
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
index 6ea3631b025b2f360bb74ae5ece113300e973346..aa463b287e79819d1f20cdc9f0d27795b8cbd3c8 100644 (file)
@@ -1,14 +1,14 @@
 /** @file\r
   This module implements Tcg2 Protocol.\r
 /** @file\r
   This module implements Tcg2 Protocol.\r
-  \r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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
+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
 http://opensource.org/licenses/bsd-license.php\r
 \r
 http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
@@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/VariableWrite.h>\r
 #include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/TrEEProtocol.h>\r
 #include <Protocol/VariableWrite.h>\r
 #include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/ResetNotification.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -115,7 +116,6 @@ VARIABLE_TYPE  mVariableType[] = {
   {EFI_KEY_EXCHANGE_KEY_NAME,    &gEfiGlobalVariableGuid},\r
   {EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid},\r
   {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
   {EFI_KEY_EXCHANGE_KEY_NAME,    &gEfiGlobalVariableGuid},\r
   {EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid},\r
   {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
-  {EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid},\r
 };\r
 \r
 EFI_HANDLE mImageHandle;\r
 };\r
 \r
 EFI_HANDLE mImageHandle;\r
@@ -167,6 +167,82 @@ InternalDumpData (
   }\r
 }\r
 \r
   }\r
 }\r
 \r
+/**\r
+\r
+  This function initialize TCG_PCR_EVENT2_HDR for EV_NO_ACTION Event Type other than EFI Specification ID event\r
+  The behavior is defined by TCG PC Client PFP Spec. Section 9.3.4 EV_NO_ACTION Event Types\r
+\r
+  @param[in, out]   NoActionEvent  Event Header of EV_NO_ACTION Event\r
+  @param[in]        EventSize      Event Size of the EV_NO_ACTION Event\r
+\r
+**/\r
+VOID\r
+InitNoActionEvent (\r
+  IN OUT TCG_PCR_EVENT2_HDR  *NoActionEvent,\r
+  IN UINT32                  EventSize\r
+ )\r
+{\r
+  UINT32          DigestListCount;\r
+  TPMI_ALG_HASH   HashAlgId;\r
+  UINT8           *DigestBuffer;\r
+\r
+  DigestBuffer    = (UINT8 *)NoActionEvent->Digests.digests;\r
+  DigestListCount = 0;\r
+\r
+  NoActionEvent->PCRIndex  = 0;\r
+  NoActionEvent->EventType = EV_NO_ACTION;\r
+\r
+  //\r
+  // Set Hash count & hashAlg accordingly, while Digest.digests[n].digest to all 0\r
+  //\r
+  ZeroMem (&NoActionEvent->Digests, sizeof(NoActionEvent->Digests));\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
+     HashAlgId = TPM_ALG_SHA1;\r
+     CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+     DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+     DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
+     HashAlgId = TPM_ALG_SHA256;\r
+     CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+     DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+     DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
+    HashAlgId = TPM_ALG_SHA384;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
+    HashAlgId = TPM_ALG_SHA512;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
+    HashAlgId = TPM_ALG_SM3_256;\r
+    CopyMem (DigestBuffer, &HashAlgId, sizeof(TPMI_ALG_HASH));\r
+    DigestBuffer += sizeof(TPMI_ALG_HASH) + GetHashSizeFromAlgo (HashAlgId);\r
+    DigestListCount++;\r
+  }\r
+\r
+  //\r
+  // Set Digests Count\r
+  //\r
+  WriteUnaligned32 ((UINT32 *)&NoActionEvent->Digests.count, DigestListCount);\r
+\r
+  //\r
+  // Set Event Size\r
+  //\r
+  WriteUnaligned32((UINT32 *)DigestBuffer, EventSize);\r
+}\r
+\r
 /**\r
 \r
   This function dump raw data with colume format.\r
 /**\r
 \r
   This function dump raw data with colume format.\r
@@ -296,11 +372,11 @@ GetProcessorsCpuLocation (
 \r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
 \r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
-                                 The ProtocolCapability variable will not be populated. \r
+                                 The ProtocolCapability variable will not be populated.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
                                  The ProtocolCapability variable will not be populated.\r
   @retval EFI_BUFFER_TOO_SMALL   The ProtocolCapability variable is too small to hold the full response.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
                                  The ProtocolCapability variable will not be populated.\r
   @retval EFI_BUFFER_TOO_SMALL   The ProtocolCapability variable is too small to hold the full response.\r
-                                 It will be partially populated (required Size field will be set). \r
+                                 It will be partially populated (required Size field will be set).\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -314,7 +390,7 @@ Tcg2GetCapability (
   if ((This == NULL) || (ProtocolCapability == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if ((This == NULL) || (ProtocolCapability == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
   DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
 \r
   DEBUG ((DEBUG_VERBOSE, "Size - 0x%x\n", ProtocolCapability->Size));\r
   DEBUG ((DEBUG_VERBOSE, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\r
 \r
@@ -322,7 +398,7 @@ Tcg2GetCapability (
     //\r
     // Handle the case that firmware support 1.1 but OS only support 1.0.\r
     //\r
     //\r
     // Handle the case that firmware support 1.1 but OS only support 1.0.\r
     //\r
-    if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) || \r
+    if ((mTcgDxeData.BsCap.ProtocolVersion.Major > 0x01) ||\r
         ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
       if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
         CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
         ((mTcgDxeData.BsCap.ProtocolVersion.Major == 0x01) && ((mTcgDxeData.BsCap.ProtocolVersion.Minor > 0x00)))) {\r
       if (ProtocolCapability->Size >= sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)) {\r
         CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0));\r
@@ -487,7 +563,7 @@ DumpEvent2 (
 \r
 /**\r
   This function returns size of TCG PCR event 2.\r
 \r
 /**\r
   This function returns size of TCG PCR event 2.\r
-  \r
+\r
   @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
 \r
   @return size of TCG PCR event 2.\r
   @param[in]  TcgPcrEvent2     TCG PCR event 2 structure.\r
 \r
   @return size of TCG PCR event 2.\r
@@ -547,7 +623,7 @@ DumpEventLog (
   UINTN                     NumberOfEvents;\r
 \r
   DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
   UINTN                     NumberOfEvents;\r
 \r
   DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
-  \r
+\r
   switch (EventLogFormat) {\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
   switch (EventLogFormat) {\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
@@ -571,7 +647,7 @@ DumpEventLog (
     break;\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
     //\r
     break;\r
   case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
     //\r
-    // Dump first event        \r
+    // Dump first event\r
     //\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
     DumpEvent (EventHdr);\r
     //\r
     EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
     DumpEvent (EventHdr);\r
@@ -606,7 +682,7 @@ DumpEventLog (
 \r
 /**\r
   The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
 \r
 /**\r
   The EFI_TCG2_PROTOCOL Get Event Log function call allows a caller to\r
-  retrieve the address of a given event log and its last entry. \r
+  retrieve the address of a given event log and its last entry.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  EventLogFormat     The type of the event log for which the information is requested.\r
@@ -704,14 +780,14 @@ Tcg2GetEventLog (
 /**\r
   Add a new entry to the Event Log.\r
 \r
 /**\r
   Add a new entry to the Event Log.\r
 \r
-  @param[in, out] EventLogPtr     Pointer to the Event Log data.  \r
-  @param[in, out] LogSize         Size of the Event Log.  \r
+  @param[in, out] EventLogPtr     Pointer to the Event Log data.\r
+  @param[in, out] LogSize         Size of the Event Log.\r
   @param[in]      MaxSize         Maximum size of the Event Log.\r
   @param[in]      MaxSize         Maximum size of the Event Log.\r
-  @param[in]      NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.  \r
+  @param[in]      NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
   @param[in]      NewEventHdrSize New event header size.\r
   @param[in]      NewEventHdrSize New event header size.\r
-  @param[in]      NewEventData    Pointer to the new event data.  \r
+  @param[in]      NewEventData    Pointer to the new event data.\r
   @param[in]      NewEventSize    New event data size.\r
   @param[in]      NewEventSize    New event data size.\r
-  \r
+\r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
@@ -762,9 +838,9 @@ TcgCommLogEvent (
   Add a new entry to the Event Log.\r
 \r
   @param[in] EventLogFormat  The type of the event log for which the information is requested.\r
   Add a new entry to the Event Log.\r
 \r
   @param[in] EventLogFormat  The type of the event log for which the information is requested.\r
-  @param[in] NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.  \r
+  @param[in] NewEventHdr     Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.\r
   @param[in] NewEventHdrSize New event header size.\r
   @param[in] NewEventHdrSize New event header size.\r
-  @param[in] NewEventData    Pointer to the new event data.  \r
+  @param[in] NewEventData    Pointer to the new event data.\r
   @param[in] NewEventSize    New event data size.\r
 \r
   @retval EFI_SUCCESS           The new event log entry was added.\r
   @param[in] NewEventSize    New event data size.\r
 \r
   @retval EFI_SUCCESS           The new event log entry was added.\r
@@ -783,7 +859,7 @@ TcgDxeLogEvent (
   EFI_STATUS                Status;\r
   UINTN                     Index;\r
   TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
   EFI_STATUS                Status;\r
   UINTN                     Index;\r
   TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct;\r
-  \r
+\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
       break;\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if (EventLogFormat == mTcg2EventInfo[Index].LogFormat) {\r
       break;\r
@@ -813,7 +889,7 @@ TcgDxeLogEvent (
              NewEventData,\r
              NewEventSize\r
              );\r
              NewEventData,\r
              NewEventSize\r
              );\r
-  \r
+\r
   if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
   if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
@@ -1046,11 +1122,11 @@ TcgDxeLogHashEvent (
   and add an entry to the Event Log.\r
 \r
   @param[in]      Flags         Bitmap providing additional information.\r
   and add an entry to the Event Log.\r
 \r
   @param[in]      Flags         Bitmap providing additional information.\r
-  @param[in]      HashData      Physical address of the start of the data buffer \r
+  @param[in]      HashData      Physical address of the start of the data buffer\r
                                 to be hashed, extended, and logged.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData\r
                                 to be hashed, extended, and logged.\r
   @param[in]      HashDataLen   The length, in bytes, of the buffer referenced by HashData\r
-  @param[in, out] NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.  \r
-  @param[in]      NewEventData  Pointer to the new event data.  \r
+  @param[in, out] NewEventHdr   Pointer to a TCG_PCR_EVENT_HDR data structure.\r
+  @param[in]      NewEventData  Pointer to the new event data.\r
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
@@ -1100,13 +1176,13 @@ TcgDxeHashLogExtendEvent (
 /**\r
   The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
   an opportunity to extend and optionally log events without requiring\r
 /**\r
   The EFI_TCG2_PROTOCOL HashLogExtendEvent function call provides callers with\r
   an opportunity to extend and optionally log events without requiring\r
-  knowledge of actual TPM commands. \r
+  knowledge of actual TPM commands.\r
   The extend operation will occur even if this function cannot create an event\r
   The extend operation will occur even if this function cannot create an event\r
-  log entry (e.g. due to the event log being full). \r
+  log entry (e.g. due to the event log being full).\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  Flags              Bitmap providing additional information.\r
 \r
   @param[in]  This               Indicates the calling context\r
   @param[in]  Flags              Bitmap providing additional information.\r
-  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed. \r
+  @param[in]  DataToHash         Physical address of the start of the data buffer to be hashed.\r
   @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.\r
   @param[in]  Event              Pointer to data buffer containing information about the event.\r
 \r
   @param[in]  DataToHashLen      The length in bytes of the buffer referenced by DataToHash.\r
   @param[in]  Event              Pointer to data buffer containing information about the event.\r
 \r
@@ -1196,7 +1272,7 @@ Tcg2HashLogExtendEvent (
   @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.\r
   @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
   @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.\r
   @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.\r
   @retval EFI_INVALID_PARAMETER  One or more of the parameters are incorrect.\r
-  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small. \r
+  @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1246,7 +1322,7 @@ Tcg2SubmitCommand (
   @param[out] ActivePcrBanks  Pointer to the variable receiving the bitmap of currently active PCR banks.\r
 \r
   @retval EFI_SUCCESS           The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
   @param[out] ActivePcrBanks  Pointer to the variable receiving the bitmap of currently active PCR banks.\r
 \r
   @retval EFI_SUCCESS           The bitmap of active PCR banks was stored in the ActivePcrBanks parameter.\r
-  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect. \r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -1336,7 +1412,7 @@ Tcg2GetResultOfSetActivePcrBanks (
   if ((OperationPresent == NULL) || (Response == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   if ((OperationPresent == NULL) || (Response == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
   if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
     return EFI_SUCCESS;\r
   ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (OperationPresent, Response);\r
   if (ReturnCode == TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS) {\r
     return EFI_SUCCESS;\r
@@ -1381,7 +1457,8 @@ SetupEventLog (
   UINT32                          HashAlgorithmMaskCopied;\r
   TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
   UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
   UINT32                          HashAlgorithmMaskCopied;\r
   TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
   UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
-  TCG_PCR_EVENT_HDR               NoActionEvent;\r
+  TCG_PCR_EVENT_HDR               SpecIdEvent;\r
+  TCG_PCR_EVENT2_HDR              NoActionEvent;\r
   TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
   UINT8                           *VendorInfoSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
   UINT8                           *VendorInfoSize;\r
@@ -1408,7 +1485,7 @@ SetupEventLog (
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
       mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
       //\r
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
       mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
       //\r
-      // To initialize them as 0xFF is recommended \r
+      // To initialize them as 0xFF is recommended\r
       // because the OS can know the last entry for that.\r
       //\r
       SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
       // because the OS can know the last entry for that.\r
       //\r
       SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
@@ -1469,25 +1546,26 @@ SetupEventLog (
         VendorInfoSize = (UINT8 *)TempDigestSize;\r
         *VendorInfoSize = 0;\r
 \r
         VendorInfoSize = (UINT8 *)TempDigestSize;\r
         *VendorInfoSize = 0;\r
 \r
-        NoActionEvent.PCRIndex = 0;\r
-        NoActionEvent.EventType = EV_NO_ACTION;\r
-        ZeroMem (&NoActionEvent.Digest, sizeof(NoActionEvent.Digest));\r
-        NoActionEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
+        SpecIdEvent.PCRIndex = 0;\r
+        SpecIdEvent.EventType = EV_NO_ACTION;\r
+        ZeroMem (&SpecIdEvent.Digest, sizeof(SpecIdEvent.Digest));\r
+        SpecIdEvent.EventSize = (UINT32)GetTcgEfiSpecIdEventStructSize (TcgEfiSpecIdEventStruct);\r
 \r
         //\r
 \r
         //\r
-        // Log TcgEfiSpecIdEventStruct as the first Event\r
+        // Log TcgEfiSpecIdEventStruct as the first Event. Event format is TCG_PCR_EVENT.\r
+        //   TCG EFI Protocol Spec. Section 5.3 Event Log Header\r
         //   TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
         //\r
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
         //   TCG PC Client PFP spec. Section 9.2 Measurement Event Entries and Log\r
         //\r
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
-                   &NoActionEvent,\r
-                   sizeof(NoActionEvent),\r
+                   &SpecIdEvent,\r
+                   sizeof(SpecIdEvent),\r
                    (UINT8 *)TcgEfiSpecIdEventStruct,\r
                    (UINT8 *)TcgEfiSpecIdEventStruct,\r
-                   NoActionEvent.EventSize\r
+                   SpecIdEvent.EventSize\r
                    );\r
 \r
         //\r
                    );\r
 \r
         //\r
-        // EfiStartupLocalityEvent\r
+        // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
         //\r
         GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
         if (GuidHob.Guid != NULL) {\r
         //\r
         GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
         if (GuidHob.Guid != NULL) {\r
@@ -1496,14 +1574,13 @@ SetupEventLog (
           //\r
           StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
           CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
           //\r
           StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
           CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\r
-\r
-          NoActionEvent.PCRIndex = 0;\r
-          NoActionEvent.EventType = EV_NO_ACTION;\r
-          ZeroMem (&NoActionEvent.Digest, sizeof(NoActionEvent.Digest));\r
-          NoActionEvent.EventSize = sizeof(StartupLocalityEvent);\r
-\r
           DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
 \r
           DEBUG ((DEBUG_INFO, "SetupEventLog: Set Locality from HOB into StartupLocalityEvent 0x%02x\n", StartupLocalityEvent.StartupLocality));\r
 \r
+          //\r
+          // Initialize StartupLocalityEvent\r
+          //\r
+          InitNoActionEvent(&NoActionEvent, sizeof(StartupLocalityEvent));\r
+\r
           //\r
           // Log EfiStartupLocalityEvent as the second Event\r
           //   TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
           //\r
           // Log EfiStartupLocalityEvent as the second Event\r
           //   TCG PC Client PFP spec. Section 9.3.4.3 Startup Locality Event\r
@@ -1511,10 +1588,11 @@ SetupEventLog (
           Status = TcgDxeLogEvent (\r
                      mTcg2EventInfo[Index].LogFormat,\r
                      &NoActionEvent,\r
           Status = TcgDxeLogEvent (\r
                      mTcg2EventInfo[Index].LogFormat,\r
                      &NoActionEvent,\r
-                     sizeof(NoActionEvent),\r
+                     sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
                      (UINT8 *)&StartupLocalityEvent,\r
                      (UINT8 *)&StartupLocalityEvent,\r
-                     NoActionEvent.EventSize\r
+                     sizeof(StartupLocalityEvent)\r
                      );\r
                      );\r
+\r
         }\r
       }\r
     }\r
         }\r
       }\r
     }\r
@@ -1553,7 +1631,7 @@ SetupEventLog (
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
 \r
         //\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
 \r
         //\r
-        // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 \r
+        // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2\r
         //\r
         Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
         if (EFI_ERROR (Status)) {\r
         //\r
         Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
         if (EFI_ERROR (Status)) {\r
@@ -1574,7 +1652,7 @@ SetupEventLog (
       }\r
     }\r
   }\r
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // 3. Sync data from PEI to DXE\r
   //\r
   //\r
   // 3. Sync data from PEI to DXE\r
   //\r
@@ -1583,7 +1661,7 @@ SetupEventLog (
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       GuidHob.Raw = GetHobList ();\r
       Status = EFI_SUCCESS;\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       GuidHob.Raw = GetHobList ();\r
       Status = EFI_SUCCESS;\r
-      while (!EFI_ERROR (Status) && \r
+      while (!EFI_ERROR (Status) &&\r
              (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
         TcgEvent    = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
         ASSERT (TcgEvent != NULL);\r
              (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
         TcgEvent    = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
         ASSERT (TcgEvent != NULL);\r
@@ -1648,22 +1726,24 @@ SetupEventLog (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Measure and log an action string, and extend the measurement result into PCR[5].\r
+  Measure and log an action string, and extend the measurement result into PCR[PCRIndex].\r
+\r
+  @param[in] PCRIndex         PCRIndex to extend\r
+  @param[in] String           A specific string that indicates an Action event.\r
 \r
 \r
-  @param[in] String           A specific string that indicates an Action event.  \r
-  \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgMeasureAction (\r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgMeasureAction (\r
-  IN      CHAR8                     *String\r
+  IN      TPM_PCRINDEX       PCRIndex,\r
+  IN      CHAR8              *String\r
   )\r
 {\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
 \r
   )\r
 {\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
 \r
-  TcgEvent.PCRIndex  = 5;\r
+  TcgEvent.PCRIndex  = PCRIndex;\r
   TcgEvent.EventType = EV_EFI_ACTION;\r
   TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
   return TcgDxeHashLogExtendEvent (\r
   TcgEvent.EventType = EV_EFI_ACTION;\r
   TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
   return TcgDxeHashLogExtendEvent (\r
@@ -1698,7 +1778,7 @@ MeasureHandoffTables (
 \r
   if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
     //\r
 \r
   if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
     //\r
-    // Tcg Server spec. \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
     // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
     //\r
     Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
@@ -1730,7 +1810,7 @@ MeasureHandoffTables (
 /**\r
   Measure and log Separator event, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Measure and log Separator event, and extend the measurement result into a specific PCR.\r
 \r
-  @param[in] PCRIndex         PCR index.  \r
+  @param[in] PCRIndex         PCR index.\r
 \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
 \r
   @retval EFI_SUCCESS         Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR    The operation was unsuccessful.\r
@@ -1762,13 +1842,13 @@ MeasureSeparatorEvent (
 /**\r
   Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Measure and log an EFI variable, 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]  PCRIndex          PCR Index.\r
+  @param[in]  EventType         Event type.\r
   @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]  VendorGuid        A unique identifier for the vendor.\r
   @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]  VendorGuid        A unique identifier for the vendor.\r
-  @param[in]  VarData           The content of the variable data.  \r
-  @param[in]  VarSize           The size of the variable data.  \r
\r
+  @param[in]  VarData           The content of the variable data.\r
+  @param[in]  VarSize           The size of the variable data.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1787,7 +1867,7 @@ MeasureVariable (
   EFI_STATUS                        Status;\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
   UINTN                             VarNameLength;\r
   EFI_STATUS                        Status;\r
   TCG_PCR_EVENT_HDR                 TcgEvent;\r
   UINTN                             VarNameLength;\r
-  EFI_VARIABLE_DATA_TREE            *VarLog;\r
+  UEFI_VARIABLE_DATA                *VarLog;\r
 \r
   DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
   DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
 \r
   DEBUG ((EFI_D_INFO, "Tcg2Dxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
   DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
@@ -1799,7 +1879,7 @@ MeasureVariable (
   TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
                         - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
 \r
   TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
                         - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
 \r
-  VarLog = (EFI_VARIABLE_DATA_TREE *)AllocatePool (TcgEvent.EventSize);\r
+  VarLog = (UEFI_VARIABLE_DATA *)AllocatePool (TcgEvent.EventSize);\r
   if (VarLog == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   if (VarLog == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -1822,7 +1902,7 @@ MeasureVariable (
 \r
   if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
     //\r
 \r
   if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
     //\r
-    // Digest is the event data (EFI_VARIABLE_DATA)\r
+    // Digest is the event data (UEFI_VARIABLE_DATA)\r
     //\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
     //\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
@@ -1848,13 +1928,13 @@ MeasureVariable (
 /**\r
   Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
 \r
 /**\r
   Read then Measure and log an EFI variable, 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]  PCRIndex          PCR Index.\r
+  @param[in]  EventType         Event type.\r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1902,13 +1982,14 @@ ReadAndMeasureVariable (
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
+  Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[1].\r
+according to TCG PC Client PFP spec 0021 Section 2.4.4.2\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -1923,7 +2004,7 @@ ReadAndMeasureBootVariable (
   )\r
 {\r
   return ReadAndMeasureVariable (\r
   )\r
 {\r
   return ReadAndMeasureVariable (\r
-           5,\r
+           1,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
@@ -1937,9 +2018,9 @@ ReadAndMeasureBootVariable (
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
 \r
   @param[in]   VarName          A Null-terminated string that is the name of the vendor's variable.\r
   @param[in]   VendorGuid       A unique identifier for the vendor.\r
-  @param[out]  VarSize          The size of the variable data.  \r
-  @param[out]  VarData          Pointer to the content of the variable.  \r
\r
+  @param[out]  VarSize          The size of the variable data.\r
+  @param[out]  VarData          Pointer to the content of the variable.\r
+\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
   @retval EFI_SUCCESS           Operation completed successfully.\r
   @retval EFI_OUT_OF_RESOURCES  Out of memory.\r
   @retval EFI_DEVICE_ERROR      The operation was unsuccessful.\r
@@ -2056,6 +2137,24 @@ MeasureAllSecureVariables (
     }\r
   }\r
 \r
     }\r
   }\r
 \r
+  //\r
+  // Measure DBT if present and not empty\r
+  //\r
+  Status = GetVariable2 (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, &Data, &DataSize);\r
+  if (!EFI_ERROR(Status)) {\r
+    Status = MeasureVariable (\r
+               7,\r
+               EV_EFI_VARIABLE_DRIVER_CONFIG,\r
+               EFI_IMAGE_SECURITY_DATABASE2,\r
+               &gEfiImageSecurityDatabaseGuid,\r
+               Data,\r
+               DataSize\r
+               );\r
+    FreePool(Data);\r
+  } else {\r
+    DEBUG((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -2180,6 +2279,7 @@ OnReadyToBoot (
     // 1. This is the first boot attempt.\r
     //\r
     Status = TcgMeasureAction (\r
     // 1. This is the first boot attempt.\r
     //\r
     Status = TcgMeasureAction (\r
+               4,\r
                EFI_CALLING_EFI_APPLICATION\r
                );\r
     if (EFI_ERROR (Status)) {\r
                EFI_CALLING_EFI_APPLICATION\r
                );\r
     if (EFI_ERROR (Status)) {\r
@@ -2213,11 +2313,24 @@ OnReadyToBoot (
     // 6. Not first attempt, meaning a return from last attempt\r
     //\r
     Status = TcgMeasureAction (\r
     // 6. Not first attempt, meaning a return from last attempt\r
     //\r
     Status = TcgMeasureAction (\r
+               4,\r
                EFI_RETURNING_FROM_EFI_APPLICATOIN\r
                );\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
     }\r
                EFI_RETURNING_FROM_EFI_APPLICATOIN\r
                );\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
     }\r
+\r
+    //\r
+    // 7. Next boot attempt, measure "Calling EFI Application from Boot Option" again\r
+    // TCG PC Client PFP spec Section 2.4.4.5 Step 4\r
+    //\r
+    Status = TcgMeasureAction (\r
+               4,\r
+               EFI_CALLING_EFI_APPLICATION\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
+    }\r
   }\r
 \r
   DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
   }\r
 \r
   DEBUG ((EFI_D_INFO, "TPM2 Tcg2Dxe Measure Data when ReadyToBoot\n"));\r
@@ -2250,6 +2363,7 @@ OnExitBootServices (
   // Measure invocation of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure invocation of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2260,6 +2374,7 @@ OnExitBootServices (
   // Measure success of ExitBootServices\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure success of ExitBootServices\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2289,6 +2404,7 @@ OnExitBootServicesFailed (
   // Measure Failure of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
   // Measure Failure of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
   if (EFI_ERROR (Status)) {\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2297,9 +2413,71 @@ OnExitBootServicesFailed (
 \r
 }\r
 \r
 \r
 }\r
 \r
+/**\r
+  This routine is called to properly shutdown the TPM before system reset.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\r
+\r
+  @param[in]  ResetType         The type of reset to perform.\r
+  @param[in]  ResetStatus       The status code for the reset.\r
+  @param[in]  DataSize          The size, in bytes, of ResetData.\r
+  @param[in]  ResetData         For a ResetType of EfiResetCold, EfiResetWarm, or\r
+                                EfiResetShutdown the data buffer starts with a Null-terminated\r
+                                string, optionally followed by additional binary data.\r
+                                The string is a description that the caller may use to further\r
+                                indicate the reason for the system reset. ResetData is only\r
+                                valid if ResetStatus is something other than EFI_SUCCESS\r
+                                unless the ResetType is EfiResetPlatformSpecific\r
+                                where a minimum amount of ResetData is always required.\r
+                                For a ResetType of EfiResetPlatformSpecific the data buffer\r
+                                also starts with a Null-terminated string that is followed\r
+                                by an EFI_GUID that describes the specific type of reset to perform.\r
+**/\r
+VOID\r
+EFIAPI\r
+ShutdownTpmOnReset (\r
+  IN EFI_RESET_TYPE           ResetType,\r
+  IN EFI_STATUS               ResetStatus,\r
+  IN UINTN                    DataSize,\r
+  IN VOID                     *ResetData OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
+  DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
+}\r
+\r
+/**\r
+  Hook the system reset to properly shutdown TPM.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\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
+VOID\r
+EFIAPI\r
+OnResetNotificationInstall (\r
+  IN EFI_EVENT                      Event,\r
+  IN VOID                           *Context\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_RESET_NOTIFICATION_PROTOCOL   *ResetNotify;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
+    ASSERT_EFI_ERROR (Status);\r
+    DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
+\r
+    gBS->CloseEvent (Event);\r
+  }\r
+}\r
+\r
 /**\r
   The function install Tcg2 protocol.\r
 /**\r
   The function install Tcg2 protocol.\r
-  \r
+\r
   @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
   @retval other           Some error occurs.\r
 **/\r
   @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
   @retval other           Some error occurs.\r
 **/\r
@@ -2324,9 +2502,9 @@ InstallTcg2 (
 /**\r
   The driver's entry point. It publishes EFI Tcg2 Protocol.\r
 \r
 /**\r
   The driver's entry point. It publishes EFI Tcg2 Protocol.\r
 \r
-  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  \r
+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.\r
   @param[in] SystemTable  A pointer to the EFI System Table.\r
   @param[in] SystemTable  A pointer to the EFI System Table.\r
-  \r
+\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval other           Some error occurs when executing this entry point.\r
 **/\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval other           Some error occurs when executing this entry point.\r
 **/\r
@@ -2351,7 +2529,7 @@ DriverEntry (
 \r
   if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
       CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
 \r
   if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
       CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
-    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));\r
+    DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -2359,18 +2537,18 @@ DriverEntry (
     DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
     DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  \r
+\r
   Status = Tpm2RequestUseTpm ();\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
     return Status;\r
   }\r
   Status = Tpm2RequestUseTpm ();\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Fill information\r
   //\r
   ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
   //\r
   // Fill information\r
   //\r
   ASSERT (TCG_EVENT_LOG_AREA_COUNT_MAX == sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]));\r
-  \r
+\r
   mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
   mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
   mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
   mTcgDxeData.BsCap.Size = sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);\r
   mTcgDxeData.BsCap.ProtocolVersion.Major = 1;\r
   mTcgDxeData.BsCap.ProtocolVersion.Minor = 1;\r
@@ -2477,7 +2655,7 @@ DriverEntry (
                     );\r
 \r
     //\r
                     );\r
 \r
     //\r
-    // Measure Exit Boot Service failed \r
+    // Measure Exit Boot Service failed\r
     //\r
     Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
     //\r
     Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
@@ -2494,6 +2672,11 @@ DriverEntry (
     // may update SecureBoot value based on last setting.\r
     //\r
     EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
     // may update SecureBoot value based on last setting.\r
     //\r
     EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+\r
+    //\r
+    // Hook the system reset to properly shutdown TPM.\r
+    //\r
+    EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r