]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
index fa4318dd5fba707466933ee8a60b7c89c31e5aad..94e93b26428fa35073b10699c63c21940511adfc 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Implement TPM2 Integrity related command.\r
 \r
-Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-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) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -22,62 +16,62 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #pragma pack(1)\r
 \r
 typedef struct {\r
-  TPM2_COMMAND_HEADER       Header;\r
-  TPMI_DH_PCR               PcrHandle;\r
-  UINT32                    AuthorizationSize;\r
-  TPMS_AUTH_COMMAND         AuthSessionPcr;\r
-  TPML_DIGEST_VALUES        DigestValues;\r
+  TPM2_COMMAND_HEADER    Header;\r
+  TPMI_DH_PCR            PcrHandle;\r
+  UINT32                 AuthorizationSize;\r
+  TPMS_AUTH_COMMAND      AuthSessionPcr;\r
+  TPML_DIGEST_VALUES     DigestValues;\r
 } TPM2_PCR_EXTEND_COMMAND;\r
 \r
 typedef struct {\r
-  TPM2_RESPONSE_HEADER       Header;\r
-  UINT32                     ParameterSize;\r
-  TPMS_AUTH_RESPONSE         AuthSessionPcr;\r
+  TPM2_RESPONSE_HEADER    Header;\r
+  UINT32                  ParameterSize;\r
+  TPMS_AUTH_RESPONSE      AuthSessionPcr;\r
 } TPM2_PCR_EXTEND_RESPONSE;\r
 \r
 typedef struct {\r
-  TPM2_COMMAND_HEADER       Header;\r
-  TPMI_DH_PCR               PcrHandle;\r
-  UINT32                    AuthorizationSize;\r
-  TPMS_AUTH_COMMAND         AuthSessionPcr;\r
-  TPM2B_EVENT               EventData;\r
+  TPM2_COMMAND_HEADER    Header;\r
+  TPMI_DH_PCR            PcrHandle;\r
+  UINT32                 AuthorizationSize;\r
+  TPMS_AUTH_COMMAND      AuthSessionPcr;\r
+  TPM2B_EVENT            EventData;\r
 } TPM2_PCR_EVENT_COMMAND;\r
 \r
 typedef struct {\r
-  TPM2_RESPONSE_HEADER       Header;\r
-  UINT32                     ParameterSize;\r
-  TPML_DIGEST_VALUES         Digests;\r
-  TPMS_AUTH_RESPONSE         AuthSessionPcr;\r
+  TPM2_RESPONSE_HEADER    Header;\r
+  UINT32                  ParameterSize;\r
+  TPML_DIGEST_VALUES      Digests;\r
+  TPMS_AUTH_RESPONSE      AuthSessionPcr;\r
 } TPM2_PCR_EVENT_RESPONSE;\r
 \r
 typedef struct {\r
-  TPM2_COMMAND_HEADER       Header;\r
-  TPML_PCR_SELECTION        PcrSelectionIn;\r
+  TPM2_COMMAND_HEADER    Header;\r
+  TPML_PCR_SELECTION     PcrSelectionIn;\r
 } TPM2_PCR_READ_COMMAND;\r
 \r
 typedef struct {\r
-  TPM2_RESPONSE_HEADER      Header;\r
-  UINT32                    PcrUpdateCounter;\r
-  TPML_PCR_SELECTION        PcrSelectionOut;\r
-  TPML_DIGEST               PcrValues;\r
+  TPM2_RESPONSE_HEADER    Header;\r
+  UINT32                  PcrUpdateCounter;\r
+  TPML_PCR_SELECTION      PcrSelectionOut;\r
+  TPML_DIGEST             PcrValues;\r
 } TPM2_PCR_READ_RESPONSE;\r
 \r
 typedef struct {\r
-  TPM2_COMMAND_HEADER       Header;\r
-  TPMI_RH_PLATFORM          AuthHandle;\r
-  UINT32                    AuthSessionSize;\r
-  TPMS_AUTH_COMMAND         AuthSession;\r
-  TPML_PCR_SELECTION        PcrAllocation;\r
+  TPM2_COMMAND_HEADER    Header;\r
+  TPMI_RH_PLATFORM       AuthHandle;\r
+  UINT32                 AuthSessionSize;\r
+  TPMS_AUTH_COMMAND      AuthSession;\r
+  TPML_PCR_SELECTION     PcrAllocation;\r
 } TPM2_PCR_ALLOCATE_COMMAND;\r
 \r
 typedef struct {\r
-  TPM2_RESPONSE_HEADER       Header;\r
-  UINT32                     AuthSessionSize;\r
-  TPMI_YES_NO                AllocationSuccess;\r
-  UINT32                     MaxPCR;\r
-  UINT32                     SizeNeeded;\r
-  UINT32                     SizeAvailable;\r
-  TPMS_AUTH_RESPONSE         AuthSession;\r
+  TPM2_RESPONSE_HEADER    Header;\r
+  UINT32                  AuthSessionSize;\r
+  TPMI_YES_NO             AllocationSuccess;\r
+  UINT32                  MaxPCR;\r
+  UINT32                  SizeNeeded;\r
+  UINT32                  SizeAvailable;\r
+  TPMS_AUTH_RESPONSE      AuthSession;\r
 } TPM2_PCR_ALLOCATE_RESPONSE;\r
 \r
 #pragma pack()\r
@@ -96,88 +90,110 @@ typedef struct {
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrExtend (\r
-  IN      TPMI_DH_PCR               PcrHandle,\r
-  IN      TPML_DIGEST_VALUES        *Digests\r
+  IN      TPMI_DH_PCR         PcrHandle,\r
+  IN      TPML_DIGEST_VALUES  *Digests\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  TPM2_PCR_EXTEND_COMMAND           Cmd;\r
-  TPM2_PCR_EXTEND_RESPONSE          Res;\r
-  UINT32                            CmdSize;\r
-  UINT32                            RespSize;\r
-  UINT32                            ResultBufSize;\r
-  UINT8                             *Buffer;\r
-  UINTN                             Index;\r
-  UINT32                            SessionInfoSize;\r
-  UINT16                            DigestSize;\r
-\r
-  Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);\r
-  Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);\r
-  Cmd.PcrHandle          = SwapBytes32(PcrHandle);\r
-\r
+  EFI_STATUS                Status;\r
+  TPM2_PCR_EXTEND_COMMAND   Cmd;\r
+  TPM2_PCR_EXTEND_RESPONSE  Res;\r
+  UINT32                    CmdSize;\r
+  UINT32                    RespSize;\r
+  UINT32                    ResultBufSize;\r
+  UINT8                     *Buffer;\r
+  UINTN                     Index;\r
+  UINT32                    SessionInfoSize;\r
+  UINT16                    DigestSize;\r
+\r
+  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);\r
+  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);\r
+  Cmd.PcrHandle          = SwapBytes32 (PcrHandle);\r
 \r
   //\r
   // Add in Auth session\r
   //\r
   Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
-  \r
+\r
   // sessionInfoSize\r
-  SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
-  Buffer += SessionInfoSize;\r
-  Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
-  \r
-  //Digest Count\r
-  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));\r
-  Buffer += sizeof(UINT32);\r
-  \r
-  //Digest\r
+  SessionInfoSize       = CopyAuthSessionCommand (NULL, Buffer);\r
+  Buffer               += SessionInfoSize;\r
+  Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
+\r
+  // Digest Count\r
+  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));\r
+  Buffer += sizeof (UINT32);\r
+\r
+  // Digest\r
   for (Index = 0; Index < Digests->count; Index++) {\r
-    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));\r
-    Buffer += sizeof(UINT16);\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));\r
+    Buffer    += sizeof (UINT16);\r
     DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
     if (DigestSize == 0) {\r
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
+      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
       return EFI_DEVICE_ERROR;\r
     }\r
-    CopyMem(\r
+\r
+    CopyMem (\r
       Buffer,\r
       &Digests->digests[Index].digest,\r
       DigestSize\r
       );\r
+\r
+    DEBUG_CODE_BEGIN ();\r
+    UINTN  Index2;\r
+    DEBUG ((\r
+      DEBUG_VERBOSE,\r
+      "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",\r
+      Digests->digests[Index].hashAlg,\r
+      (UINT8)PcrHandle\r
+      ));\r
+\r
+    for (Index2 = 0; Index2 < DigestSize; Index2++) {\r
+      DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));\r
+    }\r
+\r
+    DEBUG ((DEBUG_VERBOSE, "\n"));\r
+    DEBUG_CODE_END ();\r
+\r
     Buffer += DigestSize;\r
   }\r
 \r
   CmdSize              = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
-  Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+  Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
 \r
-  ResultBufSize = sizeof(Res);\r
-  Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
-  if (EFI_ERROR(Status)) {\r
+  ResultBufSize = sizeof (Res);\r
+  Status        = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  if (ResultBufSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+  if (ResultBufSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
   //\r
   // Validate response headers\r
   //\r
-  RespSize = SwapBytes32(Res.Header.paramSize);\r
-  if (RespSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
+  RespSize = SwapBytes32 (Res.Header.paramSize);\r
+  if (RespSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
   //\r
   // Fail if command failed\r
   //\r
-  if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  DEBUG_CODE_BEGIN ();\r
+  DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));\r
+  Tpm2PcrReadForActiveBank (PcrHandle, NULL);\r
+  DEBUG_CODE_END ();\r
+\r
   //\r
   // Unmarshal the response\r
   //\r
@@ -205,25 +221,25 @@ Tpm2PcrExtend (
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrEvent (\r
-  IN      TPMI_DH_PCR               PcrHandle,\r
-  IN      TPM2B_EVENT               *EventData,\r
-     OUT  TPML_DIGEST_VALUES        *Digests\r
+  IN      TPMI_DH_PCR      PcrHandle,\r
+  IN      TPM2B_EVENT      *EventData,\r
+  OUT  TPML_DIGEST_VALUES  *Digests\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  TPM2_PCR_EVENT_COMMAND            Cmd;\r
-  TPM2_PCR_EVENT_RESPONSE           Res;\r
-  UINT32                            CmdSize;\r
-  UINT32                            RespSize;\r
-  UINT32                            ResultBufSize;\r
-  UINT8                             *Buffer;\r
-  UINTN                             Index;\r
-  UINT32                            SessionInfoSize;\r
-  UINT16                            DigestSize;\r
-\r
-  Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);\r
-  Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);\r
-  Cmd.PcrHandle          = SwapBytes32(PcrHandle);\r
+  EFI_STATUS               Status;\r
+  TPM2_PCR_EVENT_COMMAND   Cmd;\r
+  TPM2_PCR_EVENT_RESPONSE  Res;\r
+  UINT32                   CmdSize;\r
+  UINT32                   RespSize;\r
+  UINT32                   ResultBufSize;\r
+  UINT8                    *Buffer;\r
+  UINTN                    Index;\r
+  UINT32                   SessionInfoSize;\r
+  UINT16                   DigestSize;\r
+\r
+  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);\r
+  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);\r
+  Cmd.PcrHandle          = SwapBytes32 (PcrHandle);\r
 \r
   //\r
   // Add in Auth session\r
@@ -231,45 +247,45 @@ Tpm2PcrEvent (
   Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
 \r
   // sessionInfoSize\r
-  SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
-  Buffer += SessionInfoSize;\r
-  Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
+  SessionInfoSize       = CopyAuthSessionCommand (NULL, Buffer);\r
+  Buffer               += SessionInfoSize;\r
+  Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
 \r
   // Event\r
-  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));\r
-  Buffer += sizeof(UINT16);\r
+  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));\r
+  Buffer += sizeof (UINT16);\r
 \r
   CopyMem (Buffer, EventData->buffer, EventData->size);\r
   Buffer += EventData->size;\r
-  \r
+\r
   CmdSize              = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
-  Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+  Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
 \r
-  ResultBufSize = sizeof(Res);\r
-  Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
-  if (EFI_ERROR(Status)) {\r
+  ResultBufSize = sizeof (Res);\r
+  Status        = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
-  if (ResultBufSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+  if (ResultBufSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
   //\r
   // Validate response headers\r
   //\r
-  RespSize = SwapBytes32(Res.Header.paramSize);\r
-  if (RespSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
+  RespSize = SwapBytes32 (Res.Header.paramSize);\r
+  if (RespSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
     return EFI_BUFFER_TOO_SMALL;\r
   }\r
 \r
   //\r
   // Fail if command failed\r
   //\r
-  if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
@@ -279,16 +295,22 @@ Tpm2PcrEvent (
   Buffer = (UINT8 *)&Res.Digests;\r
 \r
   Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\r
-  Buffer += sizeof(UINT32);\r
+  if (Digests->count > HASH_COUNT) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  Buffer += sizeof (UINT32);\r
   for (Index = 0; Index < Digests->count; Index++) {\r
     Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
-    Buffer += sizeof(UINT16);\r
-    DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
+    Buffer                         += sizeof (UINT16);\r
+    DigestSize                      = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
     if (DigestSize == 0) {\r
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
+      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
       return EFI_DEVICE_ERROR;\r
     }\r
-    CopyMem(\r
+\r
+    CopyMem (\r
       &Digests->digests[Index].digest,\r
       Buffer,\r
       DigestSize\r
@@ -306,59 +328,60 @@ Tpm2PcrEvent (
   @param[out] PcrUpdateCounter   The current value of the PCR update counter.\r
   @param[out] PcrSelectionOut    The PCR in the returned list.\r
   @param[out] PcrValues          The contents of the PCR indicated in pcrSelect.\r
-  \r
+\r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrRead (\r
-  IN      TPML_PCR_SELECTION        *PcrSelectionIn,\r
-     OUT  UINT32                    *PcrUpdateCounter,\r
-     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,\r
-     OUT  TPML_DIGEST               *PcrValues\r
+  IN      TPML_PCR_SELECTION  *PcrSelectionIn,\r
+  OUT  UINT32                 *PcrUpdateCounter,\r
+  OUT  TPML_PCR_SELECTION     *PcrSelectionOut,\r
+  OUT  TPML_DIGEST            *PcrValues\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  TPM2_PCR_READ_COMMAND             SendBuffer;\r
-  TPM2_PCR_READ_RESPONSE            RecvBuffer;\r
-  UINT32                            SendBufferSize;\r
-  UINT32                            RecvBufferSize;\r
-  UINTN                             Index;\r
-  TPML_DIGEST                       *PcrValuesOut;\r
-  TPM2B_DIGEST                      *Digests;\r
+  EFI_STATUS              Status;\r
+  TPM2_PCR_READ_COMMAND   SendBuffer;\r
+  TPM2_PCR_READ_RESPONSE  RecvBuffer;\r
+  UINT32                  SendBufferSize;\r
+  UINT32                  RecvBufferSize;\r
+  UINTN                   Index;\r
+  TPML_DIGEST             *PcrValuesOut;\r
+  TPM2B_DIGEST            *Digests;\r
 \r
   //\r
   // Construct command\r
   //\r
-  SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
-  SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);\r
\r
-  SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);\r
+  SendBuffer.Header.tag         = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
+  SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);\r
+\r
+  SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);\r
   for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
-    SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);\r
+    SendBuffer.PcrSelectionIn.pcrSelections[Index].hash         = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);\r
     SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;\r
     CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);\r
   }\r
 \r
-  SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
+  SendBufferSize              = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
   SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
 \r
   //\r
   // send Tpm command\r
   //\r
   RecvBufferSize = sizeof (RecvBuffer);\r
-  Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
+  Status         = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
+\r
+  if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -369,40 +392,65 @@ Tpm2PcrRead (
   //\r
   // PcrUpdateCounter\r
   //\r
-  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);\r
+\r
+  *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);\r
 \r
   //\r
   // PcrSelectionOut\r
   //\r
-  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);\r
-  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+\r
+  PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);\r
+  if (PcrSelectionOut->count > HASH_COUNT) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
-    PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
+    PcrSelectionOut->pcrSelections[Index].hash         = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
     PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
+    if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
     CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
   }\r
 \r
   //\r
   // PcrValues\r
   //\r
-  PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
-  PcrValues->count = SwapBytes32(PcrValuesOut->count);\r
+  PcrValuesOut     = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
+  PcrValues->count = SwapBytes32 (PcrValuesOut->count);\r
+  //\r
+  // The number of digests in list is not greater than 8 per TPML_DIGEST definition\r
+  //\r
+  if (PcrValues->count > 8) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
   Digests = PcrValuesOut->digests;\r
   for (Index = 0; Index < PcrValues->count; Index++) {\r
-    PcrValues->digests[Index].size = SwapBytes16(Digests->size);\r
+    PcrValues->digests[Index].size = SwapBytes16 (Digests->size);\r
+    if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {\r
+      DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
     CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
-    Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);\r
+    Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -418,20 +466,20 @@ Tpm2PcrRead (
   @param[out] MaxPCR             maximum number of PCR that may be in a bank\r
   @param[out] SizeNeeded         number of octets required to satisfy the request\r
   @param[out] SizeAvailable      Number of octets available. Computed before the allocation\r
-  \r
+\r
   @retval EFI_SUCCESS            Operation completed successfully.\r
   @retval EFI_DEVICE_ERROR       The command was unsuccessful.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrAllocate (\r
-  IN  TPMI_RH_PLATFORM          AuthHandle,\r
-  IN  TPMS_AUTH_COMMAND         *AuthSession,\r
-  IN  TPML_PCR_SELECTION        *PcrAllocation,\r
-  OUT TPMI_YES_NO               *AllocationSuccess,\r
-  OUT UINT32                    *MaxPCR,\r
-  OUT UINT32                    *SizeNeeded,\r
-  OUT UINT32                    *SizeAvailable\r
+  IN  TPMI_RH_PLATFORM    AuthHandle,\r
+  IN  TPMS_AUTH_COMMAND   *AuthSession,\r
+  IN  TPML_PCR_SELECTION  *PcrAllocation,\r
+  OUT TPMI_YES_NO         *AllocationSuccess,\r
+  OUT UINT32              *MaxPCR,\r
+  OUT UINT32              *SizeNeeded,\r
+  OUT UINT32              *SizeAvailable\r
   )\r
 {\r
   EFI_STATUS                  Status;\r
@@ -448,10 +496,10 @@ Tpm2PcrAllocate (
   //\r
   // Construct command\r
   //\r
-  Cmd.Header.tag          = SwapBytes16(TPM_ST_SESSIONS);\r
-  Cmd.Header.paramSize    = SwapBytes32(sizeof(Cmd));\r
-  Cmd.Header.commandCode  = SwapBytes32(TPM_CC_PCR_Allocate);\r
-  Cmd.AuthHandle          = SwapBytes32(AuthHandle);\r
+  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);\r
+  Cmd.Header.paramSize   = SwapBytes32 (sizeof (Cmd));\r
+  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);\r
+  Cmd.AuthHandle         = SwapBytes32 (AuthHandle);\r
 \r
   //\r
   // Add in Auth session\r
@@ -459,43 +507,43 @@ Tpm2PcrAllocate (
   Buffer = (UINT8 *)&Cmd.AuthSession;\r
 \r
   // sessionInfoSize\r
-  SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
-  Buffer += SessionInfoSize;\r
-  Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
+  SessionInfoSize     = CopyAuthSessionCommand (AuthSession, Buffer);\r
+  Buffer             += SessionInfoSize;\r
+  Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);\r
 \r
   // Count\r
-  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));\r
-  Buffer += sizeof(UINT32);\r
+  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));\r
+  Buffer += sizeof (UINT32);\r
   for (Index = 0; Index < PcrAllocation->count; Index++) {\r
-    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));\r
-    Buffer += sizeof(UINT16);\r
+    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));\r
+    Buffer          += sizeof (UINT16);\r
     *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
     Buffer++;\r
     CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
     Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
   }\r
 \r
-  CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
-  Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
+  CmdSize              = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
+  Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
 \r
-  ResultBuf     = (UINT8 *) &Res;\r
-  ResultBufSize = sizeof(Res);\r
+  ResultBuf     = (UINT8 *)&Res;\r
+  ResultBufSize = sizeof (Res);\r
 \r
   //\r
   // Call the TPM\r
   //\r
   Status = Tpm2SubmitCommand (\r
-             CmdSize, \r
-             (UINT8 *)&Cmd, \r
+             CmdSize,\r
+             (UINT8 *)&Cmd,\r
              &ResultBufSize,\r
              ResultBuf\r
              );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto Done;\r
   }\r
 \r
-  if (ResultBufSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
+  if (ResultBufSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
     Status = EFI_BUFFER_TOO_SMALL;\r
     goto Done;\r
   }\r
@@ -503,9 +551,9 @@ Tpm2PcrAllocate (
   //\r
   // Validate response headers\r
   //\r
-  RespSize = SwapBytes32(Res.Header.paramSize);\r
-  if (RespSize > sizeof(Res)) {\r
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
+  RespSize = SwapBytes32 (Res.Header.paramSize);\r
+  if (RespSize > sizeof (Res)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
     Status = EFI_BUFFER_TOO_SMALL;\r
     goto Done;\r
   }\r
@@ -513,8 +561,8 @@ Tpm2PcrAllocate (
   //\r
   // Fail if command failed\r
   //\r
-  if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
-    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
+  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
     Status = EFI_DEVICE_ERROR;\r
     goto Done;\r
   }\r
@@ -523,15 +571,325 @@ Tpm2PcrAllocate (
   // Return the response\r
   //\r
   *AllocationSuccess = Res.AllocationSuccess;\r
-  *MaxPCR = SwapBytes32(Res.MaxPCR);\r
-  *SizeNeeded = SwapBytes32(Res.SizeNeeded);\r
-  *SizeAvailable = SwapBytes32(Res.SizeAvailable);\r
+  *MaxPCR            = SwapBytes32 (Res.MaxPCR);\r
+  *SizeNeeded        = SwapBytes32 (Res.SizeNeeded);\r
+  *SizeAvailable     = SwapBytes32 (Res.SizeAvailable);\r
 \r
 Done:\r
   //\r
   // Clear AuthSession Content\r
   //\r
-  ZeroMem (&Cmd, sizeof(Cmd));\r
-  ZeroMem (&Res, sizeof(Res));\r
+  ZeroMem (&Cmd, sizeof (Cmd));\r
+  ZeroMem (&Res, sizeof (Res));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Alloc PCR data.\r
+\r
+  @param[in]  PlatformAuth      platform auth value. NULL means no platform auth change.\r
+  @param[in]  SupportedPCRBanks Supported PCR banks\r
+  @param[in]  PCRBanks          PCR banks\r
+\r
+  @retval EFI_SUCCESS Operation completed successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrAllocateBanks (\r
+  IN TPM2B_AUTH  *PlatformAuth   OPTIONAL,\r
+  IN UINT32      SupportedPCRBanks,\r
+  IN UINT32      PCRBanks\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  TPMS_AUTH_COMMAND   *AuthSession;\r
+  TPMS_AUTH_COMMAND   LocalAuthSession;\r
+  TPML_PCR_SELECTION  PcrAllocation;\r
+  TPMI_YES_NO         AllocationSuccess;\r
+  UINT32              MaxPCR;\r
+  UINT32              SizeNeeded;\r
+  UINT32              SizeAvailable;\r
+\r
+  if (PlatformAuth == NULL) {\r
+    AuthSession = NULL;\r
+  } else {\r
+    AuthSession = &LocalAuthSession;\r
+    ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));\r
+    LocalAuthSession.sessionHandle = TPM_RS_PW;\r
+    LocalAuthSession.hmac.size     = PlatformAuth->size;\r
+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
+  }\r
+\r
+  //\r
+  // Fill input\r
+  //\r
+  ZeroMem (&PcrAllocation, sizeof (PcrAllocation));\r
+  if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA1;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((HASH_ALG_SHA1 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+\r
+    PcrAllocation.count++;\r
+  }\r
+\r
+  if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA256;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((HASH_ALG_SHA256 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+\r
+    PcrAllocation.count++;\r
+  }\r
+\r
+  if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA384;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((HASH_ALG_SHA384 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+\r
+    PcrAllocation.count++;\r
+  }\r
+\r
+  if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA512;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((HASH_ALG_SHA512 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+\r
+    PcrAllocation.count++;\r
+  }\r
+\r
+  if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SM3_256;\r
+    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
+    if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
+    } else {\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
+      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
+    }\r
+\r
+    PcrAllocation.count++;\r
+  }\r
+\r
+  Status = Tpm2PcrAllocate (\r
+             TPM_RH_PLATFORM,\r
+             AuthSession,\r
+             &PcrAllocation,\r
+             &AllocationSuccess,\r
+             &MaxPCR,\r
+             &SizeNeeded,\r
+             &SizeAvailable\r
+             );\r
+  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
+  DEBUG ((DEBUG_INFO, "MaxPCR            - %08x\n", MaxPCR));\r
+  DEBUG ((DEBUG_INFO, "SizeNeeded        - %08x\n", SizeNeeded));\r
+  DEBUG ((DEBUG_INFO, "SizeAvailable     - %08x\n", SizeAvailable));\r
+\r
+Done:\r
+  ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));\r
   return Status;\r
 }\r
+\r
+/**\r
+   This function will query the TPM to determine which hashing algorithms and\r
+   get the digests of all active and supported PCR banks of a specific PCR register.\r
+\r
+   @param[in]     PcrHandle     The index of the PCR register to be read.\r
+   @param[out]    HashList      List of digests from PCR register being read.\r
+\r
+   @retval EFI_SUCCESS           The Pcr was read successfully.\r
+   @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrReadForActiveBank (\r
+  IN      TPMI_DH_PCR  PcrHandle,\r
+  OUT     TPML_DIGEST  *HashList\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  TPML_PCR_SELECTION  Pcrs;\r
+  TPML_PCR_SELECTION  PcrSelectionIn;\r
+  TPML_PCR_SELECTION  PcrSelectionOut;\r
+  TPML_DIGEST         PcrValues;\r
+  UINT32              PcrUpdateCounter;\r
+  UINT8               PcrIndex;\r
+  UINT32              TpmHashAlgorithmBitmap;\r
+  TPMI_ALG_HASH       CurrentPcrBankHash;\r
+  UINT32              ActivePcrBanks;\r
+  UINT32              TcgRegistryHashAlg;\r
+  UINTN               Index;\r
+  UINTN               Index2;\r
+\r
+  PcrIndex = (UINT8)PcrHandle;\r
+\r
+  if ((PcrIndex < 0) ||\r
+      (PcrIndex >= IMPLEMENTATION_PCR))\r
+  {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));\r
+  ZeroMem (&PcrUpdateCounter, sizeof (UINT32));\r
+  ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));\r
+  ZeroMem (&PcrValues, sizeof (PcrValues));\r
+  ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));\r
+\r
+  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));\r
+\r
+  //\r
+  // Read TPM capabilities\r
+  //\r
+  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Get Active Pcrs\r
+  //\r
+  Status = Tpm2GetCapabilitySupportedAndActivePcrs (\r
+             &TpmHashAlgorithmBitmap,\r
+             &ActivePcrBanks\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Select from Active PCRs\r
+  //\r
+  for (Index = 0; Index < Pcrs.count; Index++) {\r
+    CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;\r
+\r
+    switch (CurrentPcrBankHash) {\r
+      case TPM_ALG_SHA1:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA1;\r
+        break;\r
+      case TPM_ALG_SHA256:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA256;\r
+        break;\r
+      case TPM_ALG_SHA384:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA384;\r
+        break;\r
+      case TPM_ALG_SHA512:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA512;\r
+        break;\r
+      case TPM_ALG_SM3_256:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SM3_256;\r
+        break;\r
+      default:\r
+        //\r
+        // Unsupported algorithm\r
+        //\r
+        DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));\r
+        TcgRegistryHashAlg = 0;\r
+        break;\r
+    }\r
+\r
+    //\r
+    // Skip unsupported and inactive PCR banks\r
+    //\r
+    if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {\r
+      DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Select PCR from current active bank\r
+    //\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash         = Pcrs.pcrSelections[Index].hash;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;\r
+    PcrSelectionIn.count++;\r
+  }\r
+\r
+  //\r
+  // Read PCRs\r
+  //\r
+  Status = Tpm2PcrRead (\r
+             &PcrSelectionIn,\r
+             &PcrUpdateCounter,\r
+             &PcrSelectionOut,\r
+             &PcrValues\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  for (Index = 0; Index < PcrValues.count; Index++) {\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",\r
+      PcrSelectionOut.pcrSelections[Index].hash,\r
+      PcrIndex\r
+      ));\r
+\r
+    for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {\r
+      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));\r
+    }\r
+\r
+    DEBUG ((DEBUG_INFO, "\n"));\r
+  }\r
+\r
+  if (HashList != NULL) {\r
+    CopyMem (\r
+      HashList,\r
+      &PcrValues,\r
+      sizeof (TPML_DIGEST)\r
+      );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r