/** @file
  Implement TPM2 Integrity related command.

Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <IndustryStandard/UefiTcgPlatform.h>
#include <Library/Tpm2CommandLib.h>
#include <Library/Tpm2HelpLib.h>
#include <Library/Tpm2DeviceLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>

#pragma pack(1)

typedef struct {
  TPM2_COMMAND_HEADER    Header;
  TPMI_DH_PCR            PcrHandle;
  UINT32                 AuthorizationSize;
  TPMS_AUTH_COMMAND      AuthSessionPcr;
  TPML_DIGEST_VALUES     DigestValues;
} TPM2_PCR_EXTEND_COMMAND;

typedef struct {
  TPM2_RESPONSE_HEADER    Header;
  UINT32                  ParameterSize;
  TPMS_AUTH_RESPONSE      AuthSessionPcr;
} TPM2_PCR_EXTEND_RESPONSE;

typedef struct {
  TPM2_COMMAND_HEADER    Header;
  TPMI_DH_PCR            PcrHandle;
  UINT32                 AuthorizationSize;
  TPMS_AUTH_COMMAND      AuthSessionPcr;
  TPM2B_EVENT            EventData;
} TPM2_PCR_EVENT_COMMAND;

typedef struct {
  TPM2_RESPONSE_HEADER    Header;
  UINT32                  ParameterSize;
  TPML_DIGEST_VALUES      Digests;
  TPMS_AUTH_RESPONSE      AuthSessionPcr;
} TPM2_PCR_EVENT_RESPONSE;

typedef struct {
  TPM2_COMMAND_HEADER    Header;
  TPML_PCR_SELECTION     PcrSelectionIn;
} TPM2_PCR_READ_COMMAND;

typedef struct {
  TPM2_RESPONSE_HEADER    Header;
  UINT32                  PcrUpdateCounter;
  TPML_PCR_SELECTION      PcrSelectionOut;
  TPML_DIGEST             PcrValues;
} TPM2_PCR_READ_RESPONSE;

typedef struct {
  TPM2_COMMAND_HEADER    Header;
  TPMI_RH_PLATFORM       AuthHandle;
  UINT32                 AuthSessionSize;
  TPMS_AUTH_COMMAND      AuthSession;
  TPML_PCR_SELECTION     PcrAllocation;
} TPM2_PCR_ALLOCATE_COMMAND;

typedef struct {
  TPM2_RESPONSE_HEADER    Header;
  UINT32                  AuthSessionSize;
  TPMI_YES_NO             AllocationSuccess;
  UINT32                  MaxPCR;
  UINT32                  SizeNeeded;
  UINT32                  SizeAvailable;
  TPMS_AUTH_RESPONSE      AuthSession;
} TPM2_PCR_ALLOCATE_RESPONSE;

#pragma pack()

/**
  This command is used to cause an update to the indicated PCR.
  The digests parameter contains one or more tagged digest value identified by an algorithm ID.
  For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).

  @param[in] PcrHandle   Handle of the PCR
  @param[in] Digests     List of tagged digest values to be extended

  @retval EFI_SUCCESS      Operation completed successfully.
  @retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
EFIAPI
Tpm2PcrExtend (
  IN      TPMI_DH_PCR         PcrHandle,
  IN      TPML_DIGEST_VALUES  *Digests
  )
{
  EFI_STATUS                Status;
  TPM2_PCR_EXTEND_COMMAND   Cmd;
  TPM2_PCR_EXTEND_RESPONSE  Res;
  UINT32                    CmdSize;
  UINT32                    RespSize;
  UINT32                    ResultBufSize;
  UINT8                     *Buffer;
  UINTN                     Index;
  UINT32                    SessionInfoSize;
  UINT16                    DigestSize;

  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);
  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);
  Cmd.PcrHandle          = SwapBytes32 (PcrHandle);

  //
  // Add in Auth session
  //
  Buffer = (UINT8 *)&Cmd.AuthSessionPcr;

  // sessionInfoSize
  SessionInfoSize       = Tpm2CopyAuthSessionCommand (NULL, Buffer);
  Buffer               += SessionInfoSize;
  Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);

  // Digest Count
  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));
  Buffer += sizeof (UINT32);

  // Digest
  for (Index = 0; Index < Digests->count; Index++) {
    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));
    Buffer    += sizeof (UINT16);
    DigestSize = Tpm2GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
    if (DigestSize == 0) {
      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
      return EFI_DEVICE_ERROR;
    }

    CopyMem (
      Buffer,
      &Digests->digests[Index].digest,
      DigestSize
      );

    DEBUG_CODE_BEGIN ();
    UINTN  Index2;
    DEBUG ((
      DEBUG_VERBOSE,
      "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",
      Digests->digests[Index].hashAlg,
      (UINT8)PcrHandle
      ));

    for (Index2 = 0; Index2 < DigestSize; Index2++) {
      DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));
    }

    DEBUG ((DEBUG_VERBOSE, "\n"));
    DEBUG_CODE_END ();

    Buffer += DigestSize;
  }

  CmdSize              = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
  Cmd.Header.paramSize = SwapBytes32 (CmdSize);

  ResultBufSize = sizeof (Res);
  Status        = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (ResultBufSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Validate response headers
  //
  RespSize = SwapBytes32 (Res.Header.paramSize);
  if (RespSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Fail if command failed
  //
  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
    return EFI_DEVICE_ERROR;
  }

  DEBUG_CODE_BEGIN ();
  DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));
  Tpm2PcrReadForActiveBank (PcrHandle, NULL);
  DEBUG_CODE_END ();

  //
  // Unmarshal the response
  //

  // None

  return EFI_SUCCESS;
}

/**
  This command is used to cause an update to the indicated PCR.
  The data in eventData is hashed using the hash algorithm associated with each bank in which the
  indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle
  references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in
  TPM2_PCR_Extend().
  A TPM shall support an Event.size of zero through 1,024 inclusive.

  @param[in]  PcrHandle   Handle of the PCR
  @param[in]  EventData   Event data in sized buffer
  @param[out] Digests     List of digest

  @retval EFI_SUCCESS      Operation completed successfully.
  @retval EFI_DEVICE_ERROR Unexpected device behavior.
**/
EFI_STATUS
EFIAPI
Tpm2PcrEvent (
  IN      TPMI_DH_PCR      PcrHandle,
  IN      TPM2B_EVENT      *EventData,
  OUT  TPML_DIGEST_VALUES  *Digests
  )
{
  EFI_STATUS               Status;
  TPM2_PCR_EVENT_COMMAND   Cmd;
  TPM2_PCR_EVENT_RESPONSE  Res;
  UINT32                   CmdSize;
  UINT32                   RespSize;
  UINT32                   ResultBufSize;
  UINT8                    *Buffer;
  UINTN                    Index;
  UINT32                   SessionInfoSize;
  UINT16                   DigestSize;

  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);
  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);
  Cmd.PcrHandle          = SwapBytes32 (PcrHandle);

  //
  // Add in Auth session
  //
  Buffer = (UINT8 *)&Cmd.AuthSessionPcr;

  // sessionInfoSize
  SessionInfoSize       = Tpm2CopyAuthSessionCommand (NULL, Buffer);
  Buffer               += SessionInfoSize;
  Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);

  // Event
  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));
  Buffer += sizeof (UINT16);

  CopyMem (Buffer, EventData->buffer, EventData->size);
  Buffer += EventData->size;

  CmdSize              = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);
  Cmd.Header.paramSize = SwapBytes32 (CmdSize);

  ResultBufSize = sizeof (Res);
  Status        = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (ResultBufSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Validate response headers
  //
  RespSize = SwapBytes32 (Res.Header.paramSize);
  if (RespSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Fail if command failed
  //
  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
    return EFI_DEVICE_ERROR;
  }

  //
  // Unmarshal the response
  //
  Buffer = (UINT8 *)&Res.Digests;

  Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
  if (Digests->count > HASH_COUNT) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));
    return EFI_DEVICE_ERROR;
  }

  Buffer += sizeof (UINT32);
  for (Index = 0; Index < Digests->count; Index++) {
    Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
    Buffer                         += sizeof (UINT16);
    DigestSize                      = Tpm2GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
    if (DigestSize == 0) {
      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
      return EFI_DEVICE_ERROR;
    }

    CopyMem (
      &Digests->digests[Index].digest,
      Buffer,
      DigestSize
      );
    Buffer += DigestSize;
  }

  return EFI_SUCCESS;
}

/**
  This command returns the values of all PCR specified in pcrSelect.

  @param[in]  PcrSelectionIn     The selection of PCR to read.
  @param[out] PcrUpdateCounter   The current value of the PCR update counter.
  @param[out] PcrSelectionOut    The PCR in the returned list.
  @param[out] PcrValues          The contents of the PCR indicated in pcrSelect.

  @retval EFI_SUCCESS            Operation completed successfully.
  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
Tpm2PcrRead (
  IN      TPML_PCR_SELECTION  *PcrSelectionIn,
  OUT  UINT32                 *PcrUpdateCounter,
  OUT  TPML_PCR_SELECTION     *PcrSelectionOut,
  OUT  TPML_DIGEST            *PcrValues
  )
{
  EFI_STATUS              Status;
  TPM2_PCR_READ_COMMAND   SendBuffer;
  TPM2_PCR_READ_RESPONSE  RecvBuffer;
  UINT32                  SendBufferSize;
  UINT32                  RecvBufferSize;
  UINTN                   Index;
  TPML_DIGEST             *PcrValuesOut;
  TPM2B_DIGEST            *Digests;

  //
  // Construct command
  //
  SendBuffer.Header.tag         = SwapBytes16 (TPM_ST_NO_SESSIONS);
  SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);

  SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);
  for (Index = 0; Index < PcrSelectionIn->count; Index++) {
    SendBuffer.PcrSelectionIn.pcrSelections[Index].hash         = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);
    SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;
    CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);
  }

  SendBufferSize              = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;
  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);

  //
  // send Tpm command
  //
  RecvBufferSize = sizeof (RecvBuffer);
  Status         = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
    return EFI_DEVICE_ERROR;
  }

  if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
    return EFI_NOT_FOUND;
  }

  //
  // Return the response
  //

  //
  // PcrUpdateCounter
  //
  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
    return EFI_DEVICE_ERROR;
  }

  *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);

  //
  // PcrSelectionOut
  //
  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
    return EFI_DEVICE_ERROR;
  }

  PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);
  if (PcrSelectionOut->count > HASH_COUNT) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));
    return EFI_DEVICE_ERROR;
  }

  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
    return EFI_DEVICE_ERROR;
  }

  for (Index = 0; Index < PcrSelectionOut->count; Index++) {
    PcrSelectionOut->pcrSelections[Index].hash         = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);
    PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;
    if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {
      return EFI_DEVICE_ERROR;
    }

    CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);
  }

  //
  // PcrValues
  //
  PcrValuesOut     = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);
  PcrValues->count = SwapBytes32 (PcrValuesOut->count);
  //
  // The number of digests in list is not greater than 8 per TPML_DIGEST definition
  //
  if (PcrValues->count > 8) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));
    return EFI_DEVICE_ERROR;
  }

  Digests = PcrValuesOut->digests;
  for (Index = 0; Index < PcrValues->count; Index++) {
    PcrValues->digests[Index].size = SwapBytes16 (Digests->size);
    if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {
      DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));
      return EFI_DEVICE_ERROR;
    }

    CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);
    Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);
  }

  return EFI_SUCCESS;
}

/**
  This command is used to set the desired PCR allocation of PCR and algorithms.

  @param[in]  AuthHandle         TPM_RH_PLATFORM+{PP}
  @param[in]  AuthSession        Auth Session context
  @param[in]  PcrAllocation      The requested allocation
  @param[out] AllocationSuccess  YES if the allocation succeeded
  @param[out] MaxPCR             maximum number of PCR that may be in a bank
  @param[out] SizeNeeded         number of octets required to satisfy the request
  @param[out] SizeAvailable      Number of octets available. Computed before the allocation

  @retval EFI_SUCCESS            Operation completed successfully.
  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
Tpm2PcrAllocate (
  IN  TPMI_RH_PLATFORM    AuthHandle,
  IN  TPMS_AUTH_COMMAND   *AuthSession,
  IN  TPML_PCR_SELECTION  *PcrAllocation,
  OUT TPMI_YES_NO         *AllocationSuccess,
  OUT UINT32              *MaxPCR,
  OUT UINT32              *SizeNeeded,
  OUT UINT32              *SizeAvailable
  )
{
  EFI_STATUS                  Status;
  TPM2_PCR_ALLOCATE_COMMAND   Cmd;
  TPM2_PCR_ALLOCATE_RESPONSE  Res;
  UINT32                      CmdSize;
  UINT32                      RespSize;
  UINT8                       *Buffer;
  UINT32                      SessionInfoSize;
  UINT8                       *ResultBuf;
  UINT32                      ResultBufSize;
  UINTN                       Index;

  //
  // Construct command
  //
  Cmd.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);
  Cmd.Header.paramSize   = SwapBytes32 (sizeof (Cmd));
  Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);
  Cmd.AuthHandle         = SwapBytes32 (AuthHandle);

  //
  // Add in Auth session
  //
  Buffer = (UINT8 *)&Cmd.AuthSession;

  // sessionInfoSize
  SessionInfoSize     = Tpm2CopyAuthSessionCommand (AuthSession, Buffer);
  Buffer             += SessionInfoSize;
  Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);

  // Count
  WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));
  Buffer += sizeof (UINT32);
  for (Index = 0; Index < PcrAllocation->count; Index++) {
    WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));
    Buffer          += sizeof (UINT16);
    *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;
    Buffer++;
    CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);
    Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;
  }

  CmdSize              = (UINT32)(Buffer - (UINT8 *)&Cmd);
  Cmd.Header.paramSize = SwapBytes32 (CmdSize);

  ResultBuf     = (UINT8 *)&Res;
  ResultBufSize = sizeof (Res);

  //
  // Call the TPM
  //
  Status = Tpm2SubmitCommand (
             CmdSize,
             (UINT8 *)&Cmd,
             &ResultBufSize,
             ResultBuf
             );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  if (ResultBufSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
    Status = EFI_BUFFER_TOO_SMALL;
    goto Done;
  }

  //
  // Validate response headers
  //
  RespSize = SwapBytes32 (Res.Header.paramSize);
  if (RespSize > sizeof (Res)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
    Status = EFI_BUFFER_TOO_SMALL;
    goto Done;
  }

  //
  // Fail if command failed
  //
  if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  //
  // Return the response
  //
  *AllocationSuccess = Res.AllocationSuccess;
  *MaxPCR            = SwapBytes32 (Res.MaxPCR);
  *SizeNeeded        = SwapBytes32 (Res.SizeNeeded);
  *SizeAvailable     = SwapBytes32 (Res.SizeAvailable);

Done:
  //
  // Clear AuthSession Content
  //
  ZeroMem (&Cmd, sizeof (Cmd));
  ZeroMem (&Res, sizeof (Res));
  return Status;
}

/**
  Alloc PCR data.

  @param[in]  PlatformAuth      platform auth value. NULL means no platform auth change.
  @param[in]  SupportedPCRBanks Supported PCR banks
  @param[in]  PCRBanks          PCR banks

  @retval EFI_SUCCESS Operation completed successfully.
**/
EFI_STATUS
EFIAPI
Tpm2PcrAllocateBanks (
  IN TPM2B_AUTH  *PlatformAuth   OPTIONAL,
  IN UINT32      SupportedPCRBanks,
  IN UINT32      PCRBanks
  )
{
  EFI_STATUS          Status;
  TPMS_AUTH_COMMAND   *AuthSession;
  TPMS_AUTH_COMMAND   LocalAuthSession;
  TPML_PCR_SELECTION  PcrAllocation;
  TPMI_YES_NO         AllocationSuccess;
  UINT32              MaxPCR;
  UINT32              SizeNeeded;
  UINT32              SizeAvailable;

  if (PlatformAuth == NULL) {
    AuthSession = NULL;
  } else {
    AuthSession = &LocalAuthSession;
    ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
    LocalAuthSession.sessionHandle = TPM_RS_PW;
    LocalAuthSession.hmac.size     = PlatformAuth->size;
    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
  }

  //
  // Fill input
  //
  ZeroMem (&PcrAllocation, sizeof (PcrAllocation));
  if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {
    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA1;
    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
    if ((HASH_ALG_SHA1 & PCRBanks) != 0) {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
    } else {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
    }

    PcrAllocation.count++;
  }

  if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {
    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA256;
    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
    if ((HASH_ALG_SHA256 & PCRBanks) != 0) {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
    } else {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
    }

    PcrAllocation.count++;
  }

  if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {
    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA384;
    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
    if ((HASH_ALG_SHA384 & PCRBanks) != 0) {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
    } else {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
    }

    PcrAllocation.count++;
  }

  if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {
    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SHA512;
    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
    if ((HASH_ALG_SHA512 & PCRBanks) != 0) {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
    } else {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
    }

    PcrAllocation.count++;
  }

  if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {
    PcrAllocation.pcrSelections[PcrAllocation.count].hash         = TPM_ALG_SM3_256;
    PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;
    if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;
    } else {
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;
      PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;
    }

    PcrAllocation.count++;
  }

  Status = Tpm2PcrAllocate (
             TPM_RH_PLATFORM,
             AuthSession,
             &PcrAllocation,
             &AllocationSuccess,
             &MaxPCR,
             &SizeNeeded,
             &SizeAvailable
             );
  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
  DEBUG ((DEBUG_INFO, "MaxPCR            - %08x\n", MaxPCR));
  DEBUG ((DEBUG_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
  DEBUG ((DEBUG_INFO, "SizeAvailable     - %08x\n", SizeAvailable));

Done:
  ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
  return Status;
}

/**
   This function will query the TPM to determine which hashing algorithms and
   get the digests of all active and supported PCR banks of a specific PCR register.

   @param[in]     PcrHandle     The index of the PCR register to be read.
   @param[out]    HashList      List of digests from PCR register being read.

   @retval EFI_SUCCESS           The Pcr was read successfully.
   @retval EFI_DEVICE_ERROR      The command was unsuccessful.
**/
EFI_STATUS
EFIAPI
Tpm2PcrReadForActiveBank (
  IN      TPMI_DH_PCR  PcrHandle,
  OUT     TPML_DIGEST  *HashList
  )
{
  EFI_STATUS          Status;
  TPML_PCR_SELECTION  Pcrs;
  TPML_PCR_SELECTION  PcrSelectionIn;
  TPML_PCR_SELECTION  PcrSelectionOut;
  TPML_DIGEST         PcrValues;
  UINT32              PcrUpdateCounter;
  UINT8               PcrIndex;
  UINT32              TpmHashAlgorithmBitmap;
  TPMI_ALG_HASH       CurrentPcrBankHash;
  UINT32              ActivePcrBanks;
  UINT32              TcgRegistryHashAlg;
  UINTN               Index;
  UINTN               Index2;

  PcrIndex = (UINT8)PcrHandle;

  if ((PcrIndex < 0) ||
      (PcrIndex >= IMPLEMENTATION_PCR))
  {
    return EFI_INVALID_PARAMETER;
  }

  ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));
  ZeroMem (&PcrUpdateCounter, sizeof (UINT32));
  ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));
  ZeroMem (&PcrValues, sizeof (PcrValues));
  ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));

  //
  // Read TPM capabilities
  //
  Status = Tpm2GetCapabilityPcrs (&Pcrs);

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));
    return EFI_DEVICE_ERROR;
  }

  //
  // Get Active Pcrs
  //
  Status = Tpm2GetCapabilitySupportedAndActivePcrs (
             &TpmHashAlgorithmBitmap,
             &ActivePcrBanks
             );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));
    return EFI_DEVICE_ERROR;
  }

  //
  // Select from Active PCRs
  //
  for (Index = 0; Index < Pcrs.count; Index++) {
    CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;

    switch (CurrentPcrBankHash) {
      case TPM_ALG_SHA1:
        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));
        TcgRegistryHashAlg = HASH_ALG_SHA1;
        break;
      case TPM_ALG_SHA256:
        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));
        TcgRegistryHashAlg = HASH_ALG_SHA256;
        break;
      case TPM_ALG_SHA384:
        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));
        TcgRegistryHashAlg = HASH_ALG_SHA384;
        break;
      case TPM_ALG_SHA512:
        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));
        TcgRegistryHashAlg = HASH_ALG_SHA512;
        break;
      case TPM_ALG_SM3_256:
        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));
        TcgRegistryHashAlg = HASH_ALG_SM3_256;
        break;
      default:
        //
        // Unsupported algorithm
        //
        DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));
        TcgRegistryHashAlg = 0;
        break;
    }

    //
    // Skip unsupported and inactive PCR banks
    //
    if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {
      DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));
      continue;
    }

    //
    // Select PCR from current active bank
    //
    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash         = Pcrs.pcrSelections[Index].hash;
    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;
    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;
    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;
    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;
    PcrSelectionIn.count++;
  }

  //
  // Read PCRs
  //
  Status = Tpm2PcrRead (
             &PcrSelectionIn,
             &PcrUpdateCounter,
             &PcrSelectionOut,
             &PcrValues
             );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));
    return EFI_DEVICE_ERROR;
  }

  if (DebugPrintLevelEnabled (DEBUG_SECURITY)) {
    for (Index = 0; Index < PcrValues.count; Index++) {
      DEBUG ((
        DEBUG_SECURITY,
        "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
        PcrSelectionOut.pcrSelections[Index].hash,
        PcrIndex
        ));

      for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
        DEBUG ((DEBUG_SECURITY, "%02x ", PcrValues.digests[Index].buffer[Index2]));
      }

      DEBUG ((DEBUG_SECURITY, "\n"));
    }
  }

  if (HashList != NULL) {
    CopyMem (
      HashList,
      &PcrValues,
      sizeof (TPML_DIGEST)
      );
  }

  return EFI_SUCCESS;
}
