]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg/Tcg2Dxe: Add PcdTcgPfpMeasurementRevision in SpecId event.
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
index 3534fd13bf66f00a493153e514ad8e2651de0635..6d17616c1ce4236509dbf76f3a0d1a2bea60d1cb 100644 (file)
@@ -1,15 +1,9 @@
 /** @file\r
   This module implements Tcg2 Protocol.\r
-  \r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<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
-http://opensource.org/licenses/bsd-license.php\r
 \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
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -31,6 +25,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/ResetNotification.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -80,6 +75,7 @@ typedef struct {
   UINT8                             *LastEvent;\r
   BOOLEAN                           EventLogStarted;\r
   BOOLEAN                           EventLogTruncated;\r
+  UINTN                             Next800155EventOffset;\r
 } TCG_EVENT_LOG_AREA_STRUCT;\r
 \r
 typedef struct _TCG_DXE_DATA {\r
@@ -115,7 +111,6 @@ VARIABLE_TYPE  mVariableType[] = {
   {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
@@ -133,7 +128,7 @@ EFI_HANDLE mImageHandle;
   @param[in]  PCRIndex       TPM PCR index\r
   @param[in]  ImageAddress   Start address of image buffer.\r
   @param[in]  ImageSize      Image size\r
-  @param[out] DigestList     Digeest list of this image.\r
+  @param[out] DigestList     Digest list of this image.\r
 \r
   @retval EFI_SUCCESS            Successfully measure image.\r
   @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.\r
@@ -167,6 +162,82 @@ InternalDumpData (
   }\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
@@ -296,11 +367,11 @@ GetProcessorsCpuLocation (
 \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
-                                 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
@@ -314,7 +385,7 @@ Tcg2GetCapability (
   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
@@ -322,7 +393,7 @@ Tcg2GetCapability (
     //\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
@@ -487,7 +558,7 @@ DumpEvent2 (
 \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
@@ -547,7 +618,7 @@ DumpEventLog (
   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
@@ -571,7 +642,7 @@ DumpEventLog (
     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
@@ -606,7 +677,7 @@ DumpEventLog (
 \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
@@ -701,26 +772,51 @@ Tcg2GetEventLog (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Return if this is a Tcg800155PlatformIdEvent.\r
+\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]      NewEventData        Pointer to the new event data.\r
+  @param[in]      NewEventSize        New event data size.\r
+\r
+  @retval TRUE   This is a Tcg800155PlatformIdEvent.\r
+  @retval FALSE  This is NOT a Tcg800155PlatformIdEvent.\r
+\r
+**/\r
+BOOLEAN\r
+Is800155Event (\r
+  IN      VOID                      *NewEventHdr,\r
+  IN      UINT32                    NewEventHdrSize,\r
+  IN      UINT8                     *NewEventData,\r
+  IN      UINT32                    NewEventSize\r
+  )\r
+{\r
+  if ((((TCG_PCR_EVENT2_HDR *)NewEventHdr)->EventType == EV_NO_ACTION) &&\r
+      (NewEventSize >= sizeof(TCG_Sp800_155_PlatformId_Event2)) &&\r
+      (CompareMem (NewEventData, TCG_Sp800_155_PlatformId_Event2_SIGNATURE,\r
+        sizeof(TCG_Sp800_155_PlatformId_Event2_SIGNATURE) - 1) == 0)) {\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\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]      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]      NewEventHdrSize New event header size.\r
-  @param[in]      NewEventData    Pointer to the new event data.  \r
-  @param[in]      NewEventSize    New event data size.\r
-  \r
+  @param[in, out] EventLogAreaStruct  The event log area 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]      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
   @retval EFI_OUT_OF_RESOURCES  No enough memory to log the new event.\r
 \r
 **/\r
 EFI_STATUS\r
 TcgCommLogEvent (\r
-  IN OUT  UINT8                     **EventLogPtr,\r
-  IN OUT  UINTN                     *LogSize,\r
-  IN      UINTN                     MaxSize,\r
+  IN OUT  TCG_EVENT_LOG_AREA_STRUCT *EventLogAreaStruct,\r
   IN      VOID                      *NewEventHdr,\r
   IN      UINT32                    NewEventHdrSize,\r
   IN      UINT8                     *NewEventData,\r
@@ -728,6 +824,7 @@ TcgCommLogEvent (
   )\r
 {\r
   UINTN                            NewLogSize;\r
+  BOOLEAN                          Record800155Event;\r
 \r
   if (NewEventSize > MAX_ADDRESS -  NewEventHdrSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -735,23 +832,55 @@ TcgCommLogEvent (
 \r
   NewLogSize = NewEventHdrSize + NewEventSize;\r
 \r
-  if (NewLogSize > MAX_ADDRESS -  *LogSize) {\r
+  if (NewLogSize > MAX_ADDRESS -  EventLogAreaStruct->EventLogSize) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  if (NewLogSize + *LogSize > MaxSize) {\r
-    DEBUG ((EFI_D_INFO, "  MaxSize    - 0x%x\n", MaxSize));\r
-    DEBUG ((EFI_D_INFO, "  NewLogSize - 0x%x\n", NewLogSize));\r
-    DEBUG ((EFI_D_INFO, "  LogSize    - 0x%x\n", *LogSize));\r
-    DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
+  if (NewLogSize + EventLogAreaStruct->EventLogSize > EventLogAreaStruct->Laml) {\r
+    DEBUG ((DEBUG_INFO, "  Laml       - 0x%x\n", EventLogAreaStruct->Laml));\r
+    DEBUG ((DEBUG_INFO, "  NewLogSize - 0x%x\n", NewLogSize));\r
+    DEBUG ((DEBUG_INFO, "  LogSize    - 0x%x\n", EventLogAreaStruct->EventLogSize));\r
+    DEBUG ((DEBUG_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  *EventLogPtr += *LogSize;\r
-  *LogSize += NewLogSize;\r
-  CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);\r
+  //\r
+  // Check 800-155 event\r
+  // Record to 800-155 event offset only.\r
+  // If the offset is 0, no need to record.\r
+  //\r
+  Record800155Event = Is800155Event (NewEventHdr, NewEventHdrSize, NewEventData, NewEventSize);\r
+  if (Record800155Event) {\r
+    if (EventLogAreaStruct->Next800155EventOffset != 0) {\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewLogSize,\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
+        EventLogAreaStruct->EventLogSize - EventLogAreaStruct->Next800155EventOffset\r
+        );\r
+\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset,\r
+        NewEventHdr,\r
+        NewEventHdrSize\r
+        );\r
+      CopyMem (\r
+        (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->Next800155EventOffset + NewEventHdrSize,\r
+        NewEventData,\r
+        NewEventSize\r
+        );\r
+\r
+      EventLogAreaStruct->Next800155EventOffset += NewLogSize;\r
+      EventLogAreaStruct->LastEvent += NewLogSize;\r
+      EventLogAreaStruct->EventLogSize += NewLogSize;\r
+    }\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  EventLogAreaStruct->LastEvent = (UINT8 *)(UINTN)EventLogAreaStruct->Lasa + EventLogAreaStruct->EventLogSize;\r
+  EventLogAreaStruct->EventLogSize += NewLogSize;\r
+  CopyMem (EventLogAreaStruct->LastEvent, NewEventHdr, NewEventHdrSize);\r
   CopyMem (\r
-    *EventLogPtr + NewEventHdrSize,\r
+    EventLogAreaStruct->LastEvent + NewEventHdrSize,\r
     NewEventData,\r
     NewEventSize\r
     );\r
@@ -762,9 +891,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
-  @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] 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
@@ -783,7 +912,7 @@ TcgDxeLogEvent (
   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
@@ -803,17 +932,14 @@ TcgDxeLogEvent (
     return EFI_VOLUME_FULL;\r
   }\r
 \r
-  EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
   Status = TcgCommLogEvent (\r
-             &EventLogAreaStruct->LastEvent,\r
-             &EventLogAreaStruct->EventLogSize,\r
-             (UINTN)EventLogAreaStruct->Laml,\r
+             EventLogAreaStruct,\r
              NewEventHdr,\r
              NewEventHdrSize,\r
              NewEventData,\r
              NewEventSize\r
              );\r
-  \r
+\r
   if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
@@ -837,11 +963,8 @@ TcgDxeLogEvent (
       return EFI_VOLUME_FULL;\r
     }\r
 \r
-    EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
     Status = TcgCommLogEvent (\r
-               &EventLogAreaStruct->LastEvent,\r
-               &EventLogAreaStruct->EventLogSize,\r
-               (UINTN)EventLogAreaStruct->Laml,\r
+               EventLogAreaStruct,\r
                NewEventHdr,\r
                NewEventHdrSize,\r
                NewEventData,\r
@@ -1046,11 +1169,11 @@ TcgDxeLogHashEvent (
   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
-  @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
@@ -1068,11 +1191,25 @@ TcgDxeHashLogExtendEvent (
 {\r
   EFI_STATUS                        Status;\r
   TPML_DIGEST_VALUES                DigestList;\r
+  TCG_PCR_EVENT2_HDR                NoActionEvent;\r
 \r
   if (!mTcgDxeData.BsCap.TPMPresentFlag) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  if (NewEventHdr->EventType == EV_NO_ACTION) {\r
+    //\r
+    // Do not do TPM extend for EV_NO_ACTION\r
+    //\r
+    Status = EFI_SUCCESS;\r
+    InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);\r
+    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {\r
+      Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);\r
+    }\r
+\r
+    return Status;\r
+  }\r
+\r
   Status = HashAndExtend (\r
              NewEventHdr->PCRIndex,\r
              HashData,\r
@@ -1100,13 +1237,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
-  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
-  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
-  @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
@@ -1132,7 +1269,13 @@ Tcg2HashLogExtendEvent (
 \r
   DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
 \r
-  if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
+  if ((This == NULL) || (Event == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Do not check hash data size for EV_NO_ACTION event.\r
+  //\r
+  if ((Event->Header.EventType != EV_NO_ACTION) && (DataToHash == 0)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1196,7 +1339,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_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
@@ -1246,7 +1389,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
-  @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
@@ -1336,7 +1479,7 @@ Tcg2GetResultOfSetActivePcrBanks (
   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
@@ -1381,11 +1524,13 @@ SetupEventLog (
   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               FirstPcrEvent;\r
+  TCG_PCR_EVENT_HDR               SpecIdEvent;\r
+  TCG_PCR_EVENT2_HDR              NoActionEvent;\r
   TCG_EfiSpecIdEventAlgorithmSize *DigestSize;\r
   TCG_EfiSpecIdEventAlgorithmSize *TempDigestSize;\r
   UINT8                           *VendorInfoSize;\r
   UINT32                          NumberOfAlgorithms;\r
+  TCG_EfiStartupLocalityEvent     StartupLocalityEvent;\r
 \r
   DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
 \r
@@ -1395,19 +1540,40 @@ SetupEventLog (
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
       mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
-      Status = gBS->AllocatePages (\r
-                      AllocateAnyPages,\r
-                      EfiBootServicesData,\r
-                      EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
-                      &Lasa\r
-                      );\r
+      if (PcdGet8(PcdTpm2AcpiTableRev) >= 4) {\r
+        Status = gBS->AllocatePages (\r
+                        AllocateAnyPages,\r
+                        EfiACPIMemoryNVS,\r
+                        EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
+                        &Lasa\r
+                        );\r
+      } else {\r
+        Status = gBS->AllocatePages (\r
+                        AllocateAnyPages,\r
+                        EfiBootServicesData,\r
+                        EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
+                        &Lasa\r
+                        );\r
+      }\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
       mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
+      mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = 0;\r
+\r
+      if ((PcdGet8(PcdTpm2AcpiTableRev) >= 4) ||\r
+          (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)) {\r
+        //\r
+        // Report TCG2 event log address and length, so that they can be reported in TPM2 ACPI table.\r
+        // Ignore the return status, because those fields are optional.\r
+        //\r
+        PcdSet32S(PcdTpm2AcpiTableLaml, (UINT32)mTcgDxeData.EventLogAreaStruct[Index].Laml);\r
+        PcdSet64S(PcdTpm2AcpiTableLasa, mTcgDxeData.EventLogAreaStruct[Index].Lasa);\r
+      }\r
+\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
@@ -1423,7 +1589,7 @@ SetupEventLog (
         TcgEfiSpecIdEventStruct->platformClass = PcdGet8 (PcdTpmPlatformClass);\r
         TcgEfiSpecIdEventStruct->specVersionMajor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MAJOR_TPM2;\r
         TcgEfiSpecIdEventStruct->specVersionMinor = TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2;\r
-        TcgEfiSpecIdEventStruct->specErrata = TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2;\r
+        TcgEfiSpecIdEventStruct->specErrata = (UINT8)PcdGet32(PcdTcgPfpMeasurementRevision);\r
         TcgEfiSpecIdEventStruct->uintnSize = sizeof(UINTN)/sizeof(UINT32);\r
         NumberOfAlgorithms = 0;\r
         DigestSize = (TCG_EfiSpecIdEventAlgorithmSize *)((UINT8 *)TcgEfiSpecIdEventStruct + sizeof(*TcgEfiSpecIdEventStruct) + sizeof(NumberOfAlgorithms));\r
@@ -1468,24 +1634,79 @@ SetupEventLog (
         VendorInfoSize = (UINT8 *)TempDigestSize;\r
         *VendorInfoSize = 0;\r
 \r
-        //\r
-        // FirstPcrEvent\r
-        //\r
-        FirstPcrEvent.PCRIndex = 0;\r
-        FirstPcrEvent.EventType = EV_NO_ACTION;\r
-        ZeroMem (&FirstPcrEvent.Digest, sizeof(FirstPcrEvent.Digest));\r
-        FirstPcrEvent.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
-        // Record\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
-                   &FirstPcrEvent,\r
-                   sizeof(FirstPcrEvent),\r
+                   &SpecIdEvent,\r
+                   sizeof(SpecIdEvent),\r
                    (UINT8 *)TcgEfiSpecIdEventStruct,\r
-                   FirstPcrEvent.EventSize\r
+                   SpecIdEvent.EventSize\r
                    );\r
+        //\r
+        // record the offset at the end of 800-155 event.\r
+        // the future 800-155 event can be inserted here.\r
+        //\r
+        mTcgDxeData.EventLogAreaStruct[Index].Next800155EventOffset = \\r
+          mTcgDxeData.EventLogAreaStruct[Index].EventLogSize;\r
+\r
+        //\r
+        // Tcg800155PlatformIdEvent. Event format is TCG_PCR_EVENT2\r
+        //\r
+        GuidHob.Guid = GetFirstGuidHob (&gTcg800155PlatformIdEventHobGuid);\r
+        while (GuidHob.Guid != NULL) {\r
+          InitNoActionEvent(&NoActionEvent, GET_GUID_HOB_DATA_SIZE (GuidHob.Guid));\r
+\r
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     &NoActionEvent,\r
+                     sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
+                     GET_GUID_HOB_DATA (GuidHob.Guid),\r
+                     GET_GUID_HOB_DATA_SIZE (GuidHob.Guid)\r
+                     );\r
+\r
+          GuidHob.Guid = GET_NEXT_HOB (GuidHob);\r
+          GuidHob.Guid = GetNextGuidHob (&gTcg800155PlatformIdEventHobGuid, GuidHob.Guid);\r
+        }\r
+\r
+        //\r
+        // EfiStartupLocalityEvent. Event format is TCG_PCR_EVENT2\r
+        //\r
+        GuidHob.Guid = GetFirstGuidHob (&gTpm2StartupLocalityHobGuid);\r
+        if (GuidHob.Guid != NULL) {\r
+          //\r
+          // Get Locality Indicator from StartupLocality HOB\r
+          //\r
+          StartupLocalityEvent.StartupLocality = *(UINT8 *)(GET_GUID_HOB_DATA (GuidHob.Guid));\r
+          CopyMem (StartupLocalityEvent.Signature, TCG_EfiStartupLocalityEvent_SIGNATURE, sizeof(StartupLocalityEvent.Signature));\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
+          Status = TcgDxeLogEvent (\r
+                     mTcg2EventInfo[Index].LogFormat,\r
+                     &NoActionEvent,\r
+                     sizeof(NoActionEvent.PCRIndex) + sizeof(NoActionEvent.EventType) + GetDigestListBinSize (&NoActionEvent.Digests) + sizeof(NoActionEvent.EventSize),\r
+                     (UINT8 *)&StartupLocalityEvent,\r
+                     sizeof(StartupLocalityEvent)\r
+                     );\r
+\r
+        }\r
       }\r
     }\r
   }\r
@@ -1521,9 +1742,10 @@ SetupEventLog (
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\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
@@ -1541,10 +1763,11 @@ SetupEventLog (
         mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
         mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Next800155EventOffset = 0;\r
       }\r
     }\r
   }\r
-  \r
+\r
   //\r
   // 3. Sync data from PEI to DXE\r
   //\r
@@ -1553,7 +1776,7 @@ SetupEventLog (
     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
@@ -1618,22 +1841,24 @@ SetupEventLog (
 }\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
-  @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
-  IN      CHAR8                     *String\r
+  IN      TPM_PCRINDEX       PCRIndex,\r
+  IN      CHAR8              *String\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
@@ -1668,7 +1893,7 @@ MeasureHandoffTables (
 \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
@@ -1700,7 +1925,7 @@ MeasureHandoffTables (
 /**\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
@@ -1732,13 +1957,13 @@ MeasureSeparatorEvent (
 /**\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]  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
@@ -1757,7 +1982,7 @@ MeasureVariable (
   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
@@ -1769,7 +1994,7 @@ MeasureVariable (
   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
@@ -1792,7 +2017,7 @@ MeasureVariable (
 \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
@@ -1818,13 +2043,13 @@ MeasureVariable (
 /**\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[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
@@ -1872,13 +2097,14 @@ ReadAndMeasureVariable (
 }\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
-  @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
@@ -1893,7 +2119,7 @@ ReadAndMeasureBootVariable (
   )\r
 {\r
   return ReadAndMeasureVariable (\r
-           5,\r
+           1,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
@@ -1907,9 +2133,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
-  @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
@@ -2026,6 +2252,24 @@ MeasureAllSecureVariables (
     }\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
@@ -2150,6 +2394,7 @@ OnReadyToBoot (
     // 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
@@ -2183,10 +2428,23 @@ OnReadyToBoot (
     // 6. Not first attempt, meaning a return from last attempt\r
     //\r
     Status = TcgMeasureAction (\r
-               EFI_RETURNING_FROM_EFI_APPLICATOIN\r
+               4,\r
+               EFI_RETURNING_FROM_EFI_APPLICATION\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATION));\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_RETURNING_FROM_EFI_APPLICATOIN));\r
+      DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
     }\r
   }\r
 \r
@@ -2220,6 +2478,7 @@ OnExitBootServices (
   // Measure invocation of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_INVOCATION\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2230,6 +2489,7 @@ OnExitBootServices (
   // Measure success of ExitBootServices\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2259,6 +2519,7 @@ OnExitBootServicesFailed (
   // Measure Failure of ExitBootServices,\r
   //\r
   Status = TcgMeasureAction (\r
+             5,\r
              EFI_EXIT_BOOT_SERVICES_FAILED\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -2267,9 +2528,68 @@ OnExitBootServicesFailed (
 \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.\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
+\r
   @retval EFI_SUCCESS     Tcg2 protocol is installed.\r
   @retval other           Some error occurs.\r
 **/\r
@@ -2294,9 +2614,9 @@ InstallTcg2 (
 /**\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
-  \r
+\r
   @retval EFI_SUCCESS     The entry point is executed successfully.\r
   @retval other           Some error occurs when executing this entry point.\r
 **/\r
@@ -2321,7 +2641,7 @@ DriverEntry (
 \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
@@ -2329,18 +2649,18 @@ DriverEntry (
     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
-  \r
+\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
@@ -2447,7 +2767,7 @@ DriverEntry (
                     );\r
 \r
     //\r
-    // Measure Exit Boot Service failed \r
+    // Measure Exit Boot Service failed\r
     //\r
     Status = gBS->CreateEventEx (\r
                     EVT_NOTIFY_SIGNAL,\r
@@ -2464,6 +2784,11 @@ DriverEntry (
     // 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