]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg: Tcg2Dxe: Measure DBT into PCR[7]
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
index ae5e0841c256be22ffaf190e307e01b90678f65e..53de6668ad76b47ee1624cad3aa474d520f74ed0 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   This module implements Tcg2 Protocol.\r
   \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\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
@@ -56,9 +57,6 @@ typedef struct {
   EFI_GUID                               *VendorGuid;\r
 } VARIABLE_TYPE;\r
 \r
-#define  EFI_TCG_LOG_AREA_SIZE        0x10000\r
-#define  EFI_TCG_FINAL_LOG_AREA_SIZE  0x1000\r
-\r
 #define  TCG2_DEFAULT_MAX_COMMAND_SIZE        0x1000\r
 #define  TCG2_DEFAULT_MAX_RESPONSE_SIZE       0x1000\r
 \r
@@ -129,6 +127,8 @@ EFI_HANDLE mImageHandle;
   PE/COFF image is external input, so this function will validate its data structure\r
   within this image buffer before use.\r
 \r
+  Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().\r
+\r
   @param[in]  PCRIndex       TPM PCR index\r
   @param[in]  ImageAddress   Start address of image buffer.\r
   @param[in]  ImageSize      Image size\r
@@ -166,6 +166,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
@@ -201,33 +277,6 @@ InternalDumpHex (
   }\r
 }\r
 \r
-/**\r
-  Check if buffer is all zero.\r
-\r
-  @param[in] Buffer      Buffer to be checked.\r
-  @param[in] BufferSize  Size of buffer to be checked.\r
-\r
-  @retval TRUE  Buffer is all zero.\r
-  @retval FALSE Buffer is not all zero.\r
-**/\r
-BOOLEAN\r
-IsZeroBuffer (\r
-  IN VOID  *Buffer,\r
-  IN UINTN BufferSize\r
-  )\r
-{\r
-  UINT8 *BufferData;\r
-  UINTN Index;\r
-\r
-  BufferData = Buffer;\r
-  for (Index = 0; Index < BufferSize; Index++) {\r
-    if (BufferData[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-  return TRUE;\r
-}\r
-\r
 /**\r
   Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
   Caller is responsible to free LocationBuf.\r
@@ -335,14 +384,14 @@ Tcg2GetCapability (
   IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability\r
   )\r
 {\r
-  DEBUG ((EFI_D_INFO, "Tcg2GetCapability ...\n"));\r
+  DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability ...\n"));\r
 \r
   if ((This == NULL) || (ProtocolCapability == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
-  DEBUG ((EFI_D_INFO, "Size - 0x%x\n", ProtocolCapability->Size));\r
-  DEBUG ((EFI_D_INFO, " 1.1 - 0x%x, 1.0 - 0x%x\n", sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY), sizeof(TREE_BOOT_SERVICE_CAPABILITY_1_0)));\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
   if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {\r
     //\r
@@ -366,7 +415,7 @@ Tcg2GetCapability (
   }\r
 \r
   CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);\r
-  DEBUG ((EFI_D_INFO, "Tcg2GetCapability - %r\n", EFI_SUCCESS));\r
+  DEBUG ((DEBUG_VERBOSE, "Tcg2GetCapability - %r\n", EFI_SUCCESS));\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -820,11 +869,10 @@ TcgDxeLogEvent (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!mTcgDxeData.GetEventLogCalled[Index]) {\r
-    EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];\r
-  } else {\r
-    EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];\r
-  }\r
+  //\r
+  // Record to normal event log\r
+  //\r
+  EventLogAreaStruct = &mTcgDxeData.EventLogAreaStruct[Index];\r
 \r
   if (EventLogAreaStruct->EventLogTruncated) {\r
     return EFI_VOLUME_FULL;\r
@@ -841,79 +889,54 @@ TcgDxeLogEvent (
              NewEventSize\r
              );\r
   \r
-  if (Status == EFI_DEVICE_ERROR) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else if (Status == EFI_OUT_OF_RESOURCES) {\r
+  if (Status == EFI_OUT_OF_RESOURCES) {\r
     EventLogAreaStruct->EventLogTruncated = TRUE;\r
     return EFI_VOLUME_FULL;\r
   } else if (Status == EFI_SUCCESS) {\r
     EventLogAreaStruct->EventLogStarted = TRUE;\r
-    if (mTcgDxeData.GetEventLogCalled[Index]) {\r
-      (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
-    }\r
   }\r
 \r
-  return Status;\r
-}\r
-\r
-/**\r
-  This function get digest from digest list.\r
-\r
-  @param HashAlg    digest algorithm\r
-  @param DigestList digest list\r
-  @param Digest     digest\r
-\r
-  @retval EFI_SUCCESS   Sha1Digest is found and returned.\r
-  @retval EFI_NOT_FOUND Sha1Digest is not found.\r
-**/\r
-EFI_STATUS\r
-Tpm2GetDigestFromDigestList (\r
-  IN TPMI_ALG_HASH      HashAlg,\r
-  IN TPML_DIGEST_VALUES *DigestList,\r
-  IN VOID               *Digest\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  DigestSize = GetHashSizeFromAlgo (HashAlg);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (DigestList->digests[Index].hashAlg == HashAlg) {\r
-      CopyMem (\r
-        Digest,\r
-        &DigestList->digests[Index].digest,\r
-        DigestSize\r
-        );\r
+  //\r
+  // If GetEventLog is called, record to FinalEventsTable, too.\r
+  //\r
+  if (mTcgDxeData.GetEventLogCalled[Index]) {\r
+    if (mTcgDxeData.FinalEventsTable[Index] == NULL) {\r
+      //\r
+      // no need for FinalEventsTable\r
+      //\r
       return EFI_SUCCESS;\r
     }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
-  Get TPML_DIGEST_VALUES data size.\r
-\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES data.\r
+    EventLogAreaStruct = &mTcgDxeData.FinalEventLogAreaStruct[Index];\r
 \r
-  @return TPML_DIGEST_VALUES data size.\r
-**/\r
-UINT32\r
-GetDigestListSize (\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-  UINT32 TotalSize;\r
+    if (EventLogAreaStruct->EventLogTruncated) {\r
+      return EFI_VOLUME_FULL;\r
+    }\r
 \r
-  TotalSize = sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    TotalSize += sizeof(DigestList->digests[Index].hashAlg) + DigestSize;\r
+    EventLogAreaStruct->LastEvent = (UINT8*)(UINTN)EventLogAreaStruct->Lasa;\r
+    Status = TcgCommLogEvent (\r
+               &EventLogAreaStruct->LastEvent,\r
+               &EventLogAreaStruct->EventLogSize,\r
+               (UINTN)EventLogAreaStruct->Laml,\r
+               NewEventHdr,\r
+               NewEventHdrSize,\r
+               NewEventData,\r
+               NewEventSize\r
+               );\r
+    if (Status == EFI_OUT_OF_RESOURCES) {\r
+      EventLogAreaStruct->EventLogTruncated = TRUE;\r
+      return EFI_VOLUME_FULL;\r
+    } else if (Status == EFI_SUCCESS) {\r
+      EventLogAreaStruct->EventLogStarted = TRUE;\r
+      //\r
+      // Increase the NumberOfEvents in FinalEventsTable\r
+      //\r
+      (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents ++;\r
+      DEBUG ((EFI_D_INFO, "FinalEventsTable->NumberOfEvents - 0x%x\n", (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents));\r
+      DEBUG ((EFI_D_INFO, "  Size - 0x%x\n", (UINTN)EventLogAreaStruct->EventLogSize));\r
+    }\r
   }\r
 \r
-  return TotalSize;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -951,79 +974,55 @@ GetDigestListBinSize (
 }\r
 \r
 /**\r
-  Return if hash alg is supported in TPM PCR bank.\r
+  Copy TPML_DIGEST_VALUES compact binary into a buffer\r
 \r
-  @param HashAlg  Hash algorithm to be checked.\r
+  @param[in,out]    Buffer                  Buffer to hold copied TPML_DIGEST_VALUES compact binary.\r
+  @param[in]        DigestListBin           TPML_DIGEST_VALUES compact binary buffer.\r
+  @param[in]        HashAlgorithmMask       HASH bits corresponding to the desired digests to copy.\r
+  @param[out]       HashAlgorithmMaskCopied Pointer to HASH bits corresponding to the digests copied.\r
 \r
-  @retval TRUE  Hash algorithm is supported.\r
-  @retval FALSE Hash algorithm is not supported.\r
+  @return The end of buffer to hold TPML_DIGEST_VALUES compact binary.\r
 **/\r
-BOOLEAN\r
-IsHashAlgSupportedInPcrBank (\r
-  IN TPMI_ALG_HASH  HashAlg\r
+VOID *\r
+CopyDigestListBinToBuffer (\r
+  IN OUT VOID                       *Buffer,\r
+  IN VOID                           *DigestListBin,\r
+  IN UINT32                         HashAlgorithmMask,\r
+  OUT UINT32                        *HashAlgorithmMaskCopied\r
   )\r
 {\r
-  switch (HashAlg) {\r
-  case TPM_ALG_SHA1:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA256:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA384:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SHA512:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  case TPM_ALG_SM3_256:\r
-    if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {\r
-      return TRUE;\r
-    }\r
-    break;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
+  UINTN         Index;\r
+  UINT16        DigestSize;\r
+  UINT32        Count;\r
+  TPMI_ALG_HASH HashAlg;\r
+  UINT32        DigestListCount;\r
+  UINT32        *DigestListCountPtr;\r
 \r
-/**\r
-  Copy TPML_DIGEST_VALUES into a buffer\r
+  DigestListCountPtr = (UINT32 *) Buffer;\r
+  DigestListCount = 0;\r
+  (*HashAlgorithmMaskCopied) = 0;\r
 \r
-  @param[in,out] Buffer        Buffer to hold TPML_DIGEST_VALUES.\r
-  @param[in]     DigestList    TPML_DIGEST_VALUES to be copied.\r
+  Count = ReadUnaligned32 (DigestListBin);\r
+  Buffer = (UINT8 *)Buffer + sizeof(Count);\r
+  DigestListBin = (UINT8 *)DigestListBin + sizeof(Count);\r
+  for (Index = 0; Index < Count; Index++) {\r
+    HashAlg = ReadUnaligned16 (DigestListBin);\r
+    DigestListBin = (UINT8 *)DigestListBin + sizeof(HashAlg);\r
+    DigestSize = GetHashSizeFromAlgo (HashAlg);\r
 \r
-  @return The end of buffer to hold TPML_DIGEST_VALUES.\r
-**/\r
-VOID *\r
-CopyDigestListToBuffer (\r
-  IN OUT VOID                       *Buffer,\r
-  IN TPML_DIGEST_VALUES             *DigestList\r
-  )\r
-{\r
-  UINTN  Index;\r
-  UINT16 DigestSize;\r
-\r
-  CopyMem (Buffer, &DigestList->count, sizeof(DigestList->count));\r
-  Buffer = (UINT8 *)Buffer + sizeof(DigestList->count);\r
-  for (Index = 0; Index < DigestList->count; Index++) {\r
-    if (!IsHashAlgSupportedInPcrBank (DigestList->digests[Index].hashAlg)) {\r
-      DEBUG ((EFI_D_ERROR, "WARNING: TPM2 Event log has HashAlg unsupported by PCR bank (0x%x)\n", DigestList->digests[Index].hashAlg));\r
-      continue;\r
+    if (IsHashAlgSupportedInHashAlgorithmMask(HashAlg, HashAlgorithmMask)) {\r
+      CopyMem (Buffer, &HashAlg, sizeof(HashAlg));\r
+      Buffer = (UINT8 *)Buffer + sizeof(HashAlg);\r
+      CopyMem (Buffer, DigestListBin, DigestSize);\r
+      Buffer = (UINT8 *)Buffer + DigestSize;\r
+      DigestListCount++;\r
+      (*HashAlgorithmMaskCopied) |= GetHashMaskFromAlgo (HashAlg);\r
+    } else {\r
+      DEBUG ((DEBUG_ERROR, "WARNING: CopyDigestListBinToBuffer Event log has HashAlg unsupported by PCR bank (0x%x)\n", HashAlg));\r
     }\r
-    CopyMem (Buffer, &DigestList->digests[Index].hashAlg, sizeof(DigestList->digests[Index].hashAlg));\r
-    Buffer = (UINT8 *)Buffer + sizeof(DigestList->digests[Index].hashAlg);\r
-    DigestSize = GetHashSizeFromAlgo (DigestList->digests[Index].hashAlg);\r
-    CopyMem (Buffer, &DigestList->digests[Index].digest, DigestSize);\r
-    Buffer = (UINT8 *)Buffer + DigestSize;\r
+    DigestListBin = (UINT8 *)DigestListBin + DigestSize;\r
   }\r
+  WriteUnaligned32 (DigestListCountPtr, DigestListCount);\r
 \r
   return Buffer;\r
 }\r
@@ -1051,6 +1050,7 @@ TcgDxeLogHashEvent (
   EFI_STATUS                        RetStatus;\r
   TCG_PCR_EVENT2                    TcgPcrEvent2;\r
   UINT8                             *DigestBuffer;\r
+  UINT32                            *EventSizePtr;\r
 \r
   DEBUG ((EFI_D_INFO, "SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
 \r
@@ -1060,7 +1060,7 @@ TcgDxeLogHashEvent (
       DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));\r
       switch (mTcg2EventInfo[Index].LogFormat) {\r
       case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
-        Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
+        Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
         if (!EFI_ERROR (Status)) {\r
           //\r
           // Enter critical region\r
@@ -1087,9 +1087,8 @@ TcgDxeLogHashEvent (
         TcgPcrEvent2.PCRIndex = NewEventHdr->PCRIndex;\r
         TcgPcrEvent2.EventType = NewEventHdr->EventType;\r
         DigestBuffer = (UINT8 *)&TcgPcrEvent2.Digest;\r
-        DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList);\r
-        CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
-        DigestBuffer = DigestBuffer + sizeof(NewEventHdr->EventSize);\r
+        EventSizePtr = CopyDigestListToBuffer (DigestBuffer, DigestList, mTcgDxeData.BsCap.ActivePcrBanks);\r
+        CopyMem (EventSizePtr, &NewEventHdr->EventSize, sizeof(NewEventHdr->EventSize));\r
 \r
         //\r
         // Enter critical region\r
@@ -1098,7 +1097,7 @@ TcgDxeLogHashEvent (
         Status = TcgDxeLogEvent (\r
                    mTcg2EventInfo[Index].LogFormat,\r
                    &TcgPcrEvent2,\r
-                   sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2.EventSize),\r
+                   sizeof(TcgPcrEvent2.PCRIndex) + sizeof(TcgPcrEvent2.EventType) + GetDigestListBinSize (DigestBuffer) + sizeof(TcgPcrEvent2.EventSize),\r
                    NewEventData,\r
                    NewEventHdr->EventSize\r
                    );\r
@@ -1206,7 +1205,7 @@ Tcg2HashLogExtendEvent (
   TCG_PCR_EVENT_HDR  NewEventHdr;\r
   TPML_DIGEST_VALUES DigestList;\r
 \r
-  DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent ...\n"));\r
+  DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent ...\n"));\r
 \r
   if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1256,7 +1255,7 @@ Tcg2HashLogExtendEvent (
                Event->Event\r
                );\r
   }\r
-  DEBUG ((EFI_D_INFO, "Tcg2HashLogExtendEvent - %r\n", Status));\r
+  DEBUG ((DEBUG_VERBOSE, "Tcg2HashLogExtendEvent - %r\n", Status));\r
   return Status;\r
 }\r
 \r
@@ -1298,10 +1297,10 @@ Tcg2SubmitCommand (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) {\r
+  if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) {\r
+  if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1448,15 +1447,22 @@ SetupEventLog (
   EFI_PEI_HOB_POINTERS            GuidHob;\r
   EFI_PHYSICAL_ADDRESS            Lasa;\r
   UINTN                           Index;\r
+  VOID                            *DigestListBin;\r
+  TPML_DIGEST_VALUES              TempDigestListBin;\r
   UINT32                          DigestListBinSize;\r
+  UINT8                           *Event;\r
   UINT32                          EventSize;\r
+  UINT32                          *EventSizePtr;\r
+  UINT32                          HashAlgorithmMaskCopied;\r
   TCG_EfiSpecIDEventStruct        *TcgEfiSpecIdEventStruct;\r
-  UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\r
-  TCG_PCR_EVENT_HDR               FirstPcrEvent;\r
+  UINT8                           TempBuf[sizeof(TCG_EfiSpecIDEventStruct) + sizeof(UINT32) + (HASH_COUNT * sizeof(TCG_EfiSpecIdEventAlgorithmSize)) + sizeof(UINT8)];\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
@@ -1466,23 +1472,22 @@ 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
-      Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
       Status = gBS->AllocatePages (\r
-                      AllocateMaxAddress,\r
-                      EfiACPIMemoryNVS,\r
-                      EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
+                      AllocateAnyPages,\r
+                      EfiBootServicesData,\r
+                      EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
                       &Lasa\r
                       );\r
       if (EFI_ERROR (Status)) {\r
         return Status;\r
       }\r
       mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
-      mTcgDxeData.EventLogAreaStruct[Index].Laml = EFI_TCG_LOG_AREA_SIZE;\r
+      mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
       //\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, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
+      SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
       //\r
       // Create first entry for Log Header Entry Data\r
       //\r
@@ -1540,24 +1545,54 @@ 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
+        //\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
@@ -1567,41 +1602,52 @@ SetupEventLog (
   //\r
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {\r
     if ((mTcgDxeData.BsCap.SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {\r
-      Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
-      Status = gBS->AllocatePages (\r
-                      AllocateMaxAddress,\r
-                      EfiACPIMemoryNVS,\r
-                      EFI_SIZE_TO_PAGES (EFI_TCG_FINAL_LOG_AREA_SIZE),\r
-                      &Lasa\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_FINAL_LOG_AREA_SIZE, 0xFF);\r
+      if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
+        Status = gBS->AllocatePages (\r
+                        AllocateAnyPages,\r
+                        EfiACPIMemoryNVS,\r
+                        EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcg2FinalLogAreaLen)),\r
+                        &Lasa\r
+                        );\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
+        }\r
+        SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcg2FinalLogAreaLen), 0xFF);\r
 \r
-      //\r
-      // Initialize\r
-      //\r
-      mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
-      (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
-      (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
-\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = EFI_TCG_FINAL_LOG_AREA_SIZE - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
-      mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
+        //\r
+        // Initialize\r
+        //\r
+        mTcgDxeData.FinalEventsTable[Index] = (VOID *)(UINTN)Lasa;\r
+        (mTcgDxeData.FinalEventsTable[Index])->Version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;\r
+        (mTcgDxeData.FinalEventsTable[Index])->NumberOfEvents = 0;\r
+\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = Lasa + sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcg2FinalLogAreaLen) - sizeof(EFI_TCG2_FINAL_EVENTS_TABLE);\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = (VOID *)(UINTN)mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
 \r
-      if (mTcg2EventInfo[Index].LogFormat == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {\r
         //\r
-        // Install to configuration table\r
+        // Install to configuration table for EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 \r
         //\r
-        Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[1]);\r
+        Status = gBS->InstallConfigurationTable (&gEfiTcg2FinalEventsTableGuid, (VOID *)mTcgDxeData.FinalEventsTable[Index]);\r
         if (EFI_ERROR (Status)) {\r
           return Status;\r
         }\r
+      } else {\r
+        //\r
+        // No need to handle EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2\r
+        //\r
+        mTcgDxeData.FinalEventsTable[Index] = NULL;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogFormat = mTcg2EventInfo[Index].LogFormat;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Lasa = 0;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].Laml = 0;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogSize = 0;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].LastEvent = 0;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogStarted = FALSE;\r
+        mTcgDxeData.FinalEventLogAreaStruct[Index].EventLogTruncated = FALSE;\r
       }\r
     }\r
   }\r
@@ -1616,7 +1662,8 @@ SetupEventLog (
       Status = EFI_SUCCESS;\r
       while (!EFI_ERROR (Status) && \r
              (GuidHob.Raw = GetNextGuidHob (mTcg2EventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
-        TcgEvent    = GET_GUID_HOB_DATA (GuidHob.Guid);\r
+        TcgEvent    = AllocateCopyPool (GET_GUID_HOB_DATA_SIZE (GuidHob.Guid), GET_GUID_HOB_DATA (GuidHob.Guid));\r
+        ASSERT (TcgEvent != NULL);\r
         GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
         switch (mTcg2EventInfo[Index].LogFormat) {\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:\r
@@ -1629,17 +1676,47 @@ SetupEventLog (
                      );\r
           break;\r
         case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2:\r
-          DigestListBinSize = GetDigestListBinSize ((UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE));\r
-          CopyMem (&EventSize, (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize, sizeof(UINT32));\r
+          DigestListBin = (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE);\r
+          DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
+          //\r
+          // Save event size.\r
+          //\r
+          CopyMem (&EventSize, (UINT8 *)DigestListBin + DigestListBinSize, sizeof(UINT32));\r
+          Event = (UINT8 *)DigestListBin + DigestListBinSize + sizeof(UINT32);\r
+          //\r
+          // Filter inactive digest in the event2 log from PEI HOB.\r
+          //\r
+          CopyMem (&TempDigestListBin, DigestListBin, GetDigestListBinSize (DigestListBin));\r
+          EventSizePtr = CopyDigestListBinToBuffer (\r
+                           DigestListBin,\r
+                           &TempDigestListBin,\r
+                           mTcgDxeData.BsCap.ActivePcrBanks,\r
+                           &HashAlgorithmMaskCopied\r
+                           );\r
+          if (HashAlgorithmMaskCopied != mTcgDxeData.BsCap.ActivePcrBanks) {\r
+            DEBUG ((\r
+              DEBUG_ERROR,\r
+              "ERROR: The event2 log includes digest hash mask 0x%x, but required digest hash mask is 0x%x\n",\r
+              HashAlgorithmMaskCopied,\r
+              mTcgDxeData.BsCap.ActivePcrBanks\r
+              ));\r
+          }\r
+          //\r
+          // Restore event size.\r
+          //\r
+          CopyMem (EventSizePtr, &EventSize, sizeof(UINT32));\r
+          DigestListBinSize = GetDigestListBinSize (DigestListBin);\r
+\r
           Status = TcgDxeLogEvent (\r
                      mTcg2EventInfo[Index].LogFormat,\r
                      TcgEvent,\r
                      sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
-                     (UINT8 *)TcgEvent + sizeof(TCG_PCRINDEX) + sizeof(TCG_EVENTTYPE) + DigestListBinSize + sizeof(UINT32),\r
+                     Event,\r
                      EventSize\r
                      );\r
           break;\r
         }\r
+        FreePool (TcgEvent);\r
       }\r
     }\r
   }\r
@@ -1648,8 +1725,9 @@ 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
   @retval EFI_SUCCESS         Operation completed successfully.\r
@@ -1658,12 +1736,13 @@ SetupEventLog (
 **/\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
@@ -1787,7 +1866,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
@@ -1799,7 +1878,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
@@ -1822,7 +1901,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
@@ -1832,6 +1911,7 @@ MeasureVariable (
                (UINT8*)VarLog\r
                );\r
   } else {\r
+    ASSERT (VarData != NULL);\r
     Status = TcgDxeHashLogExtendEvent (\r
                0,\r
                (UINT8*)VarData,\r
@@ -1901,7 +1981,8 @@ 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
@@ -1922,7 +2003,7 @@ ReadAndMeasureBootVariable (
   )\r
 {\r
   return ReadAndMeasureVariable (\r
-           5,\r
+           1,\r
            EV_EFI_VARIABLE_BOOT,\r
            VarName,\r
            VendorGuid,\r
@@ -2055,6 +2136,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
@@ -2179,6 +2278,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
@@ -2192,7 +2292,7 @@ OnReadyToBoot (
     for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
       Status = MeasureSeparatorEvent (PcrIndex);\r
       if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
+        DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));\r
       }\r
     }\r
 \r
@@ -2212,11 +2312,24 @@ OnReadyToBoot (
     // 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
+\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
@@ -2249,6 +2362,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
@@ -2259,6 +2373,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
@@ -2288,6 +2403,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
@@ -2341,7 +2457,6 @@ DriverEntry (
   VOID                              *Registration;\r
   UINT32                            MaxCommandSize;\r
   UINT32                            MaxResponseSize;\r
-  TPML_PCR_SELECTION                Pcrs;\r
   UINTN                             Index;\r
   EFI_TCG2_EVENT_ALGORITHM_BITMAP   TpmHashAlgorithmBitmap;\r
   UINT32                            ActivePCRBanks;\r
@@ -2411,61 +2526,22 @@ DriverEntry (
   //\r
   // Get supported PCR and current Active PCRs\r
   //\r
-  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
-    TpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-    NumberOfPCRBanks = 1;\r
-    ActivePCRBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-  } else {\r
-    DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
-    NumberOfPCRBanks = 0;\r
-    TpmHashAlgorithmBitmap = 0;\r
-    ActivePCRBanks = 0;\r
-    for (Index = 0; Index < Pcrs.count; Index++) {\r
-      DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
-      switch (Pcrs.pcrSelections[Index].hash) {\r
-      case TPM_ALG_SHA1:\r
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-        NumberOfPCRBanks ++;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1;\r
-        }        \r
-        break;\r
-      case TPM_ALG_SHA256:\r
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
-        NumberOfPCRBanks ++;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256;\r
-        }\r
-        break;\r
-      case TPM_ALG_SHA384:\r
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
-        NumberOfPCRBanks ++;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384;\r
-        }\r
-        break;\r
-      case TPM_ALG_SHA512:\r
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
-        NumberOfPCRBanks ++;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512;\r
-        }\r
-        break;\r
-      case TPM_ALG_SM3_256:\r
-        TpmHashAlgorithmBitmap |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
-        NumberOfPCRBanks ++;\r
-        if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
-          ActivePCRBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256;\r
-        }\r
-        break;\r
-      }\r
-    }\r
-  }\r
+  Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePCRBanks);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
   mTcgDxeData.BsCap.ActivePcrBanks = ActivePCRBanks & PcdGet32 (PcdTcg2HashAlgorithmBitmap);\r
 \r
+  //\r
+  // Need calculate NumberOfPCRBanks here, because HashAlgorithmBitmap might be removed by PCD.\r
+  //\r
+  NumberOfPCRBanks = 0;\r
+  for (Index = 0; Index < 32; Index++) {\r
+    if ((mTcgDxeData.BsCap.HashAlgorithmBitmap & (1u << Index)) != 0) {\r
+      NumberOfPCRBanks++;\r
+    }\r
+  }\r
+\r
   if (PcdGet32 (PcdTcg2NumberOfPCRBanks) == 0) {\r
     mTcgDxeData.BsCap.NumberOfPCRBanks = NumberOfPCRBanks;\r
   } else {\r
@@ -2477,11 +2553,11 @@ DriverEntry (
   }\r
 \r
   mTcgDxeData.BsCap.SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;\r
-  if ((mTcgDxeData.BsCap.ActivePcrBanks & TREE_BOOT_HASH_ALG_SHA1) == 0) {\r
+  if ((mTcgDxeData.BsCap.ActivePcrBanks & EFI_TCG2_BOOT_HASH_ALG_SHA1) == 0) {\r
     //\r
     // No need to expose TCG1.2 event log if SHA1 bank does not exist.\r
     //\r
-    mTcgDxeData.BsCap.SupportedEventLogs &= ~TREE_EVENT_LOG_FORMAT_TCG_1_2;\r
+    mTcgDxeData.BsCap.SupportedEventLogs &= ~EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;\r
   }\r
 \r
   DEBUG ((EFI_D_INFO, "Tcg2.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r