public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
@ 2020-07-20 22:28 Rodrigo Gonzalez del Cueto
  2020-07-23  2:06 ` Yao, Jiewen
  0 siblings, 1 reply; 8+ messages in thread
From: Rodrigo Gonzalez del Cueto @ 2020-07-20 22:28 UTC (permalink / raw)
  To: devel; +Cc: Rodrigo Gonzalez del Cueto, Jiewen Yao, Jian J Wang, Qi Zhang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858

Add debug functionality to examine TPM extend operations
performed by BIOS and inspect the PCR 00 value prior to
any BIOS measurements.

Replaced usage of EFI_D_* for DEBUG_* definitions in debug
messages.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Qi Zhang <qi1.zhang@intel.com>
Signed-off-by: Rodrigo Gonzalez del Cueto <rodrigo.gonzalez.del.cueto@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h  |  25 +-
 .../Library/Tpm2CommandLib/Tpm2Integrity.c    | 468 ++++++++++++------
 SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c             |  32 +-
 3 files changed, 364 insertions(+), 161 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index ce381e786b..bfa5bd82f4 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -505,7 +505,7 @@ EFIAPI
 Tpm2PcrEvent (
   IN      TPMI_DH_PCR               PcrHandle,
   IN      TPM2B_EVENT               *EventData,
-     OUT  TPML_DIGEST_VALUES        *Digests
+  OUT  TPML_DIGEST_VALUES        *Digests
   );
 
 /**
@@ -523,9 +523,26 @@ EFI_STATUS
 EFIAPI
 Tpm2PcrRead (
   IN      TPML_PCR_SELECTION        *PcrSelectionIn,
-     OUT  UINT32                    *PcrUpdateCounter,
-     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
-     OUT  TPML_DIGEST               *PcrValues
+  OUT  UINT32                    *PcrUpdateCounter,
+  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
+  OUT  TPML_DIGEST               *PcrValues
+  );
+
+/**
+   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
+Tpm2ActivePcrRegisterRead (
+  IN      TPMI_DH_PCR                PcrHandle,
+  OUT     TPML_DIGEST                *HashList
   );
 
 /**
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
index ddb15178fb..229fc44139 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
@@ -76,6 +76,297 @@ typedef struct {
 
 #pragma pack()
 
+/**
+  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 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
+Tpm2ActivePcrRegisterRead (
+ 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;
+  UINT32                            PcrIndex;
+  UINT32                            TpmHashAlgorithmBitmap;
+  TPMI_ALG_HASH                     CurrentPcrBankHash;
+  UINT32                            ActivePcrBanks;
+  UINT32                            TcgRegistryHashAlg;
+  UINT32                            Index;
+  UINT32                            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));
+
+  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
+
+  //
+  // 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;
+  }
+
+  for (Index = 0; Index < PcrValues.count; Index++) {
+    DEBUG ((
+      DEBUG_INFO,
+      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
+      PcrSelectionOut.pcrSelections[Index].hash,
+      PcrIndex
+      ));
+
+    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
+      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+
+  if (HashList != NULL) {
+    CopyMem (
+      HashList,
+      &PcrValues,
+      sizeof (TPML_DIGEST)
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
 /**
   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.
@@ -130,14 +421,26 @@ Tpm2PcrExtend (
     Buffer += sizeof(UINT16);
     DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
     if (DigestSize == 0) {
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
+      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_INFO, "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ", Digests->digests[Index].hashAlg, (UINT8) PcrHandle));
+
+    for (Index2 = 0; Index2 < DigestSize; Index2++) {
+      DEBUG ((DEBUG_INFO, "%02x ", Buffer[Index2]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+    DEBUG_CODE_END ();
+
     Buffer += DigestSize;
   }
 
@@ -151,7 +454,7 @@ Tpm2PcrExtend (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -160,7 +463,7 @@ Tpm2PcrExtend (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -168,10 +471,15 @@ Tpm2PcrExtend (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
     return EFI_DEVICE_ERROR;
   }
 
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "Tpm2PcrExtend: PCR read after extend...\n"));
+  Tpm2ActivePcrRegisterRead (PcrHandle, NULL);
+  DEBUG_CODE_END ();
+
   //
   // Unmarshal the response
   //
@@ -246,7 +554,7 @@ Tpm2PcrEvent (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -255,7 +563,7 @@ Tpm2PcrEvent (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -263,7 +571,7 @@ Tpm2PcrEvent (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
     return EFI_DEVICE_ERROR;
   }
 
@@ -284,7 +592,7 @@ Tpm2PcrEvent (
     Buffer += sizeof(UINT16);
     DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
     if (DigestSize == 0) {
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
+      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
       return EFI_DEVICE_ERROR;
     }
     CopyMem(
@@ -298,134 +606,6 @@ Tpm2PcrEvent (
   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 ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
-    return EFI_DEVICE_ERROR;
-  }
-  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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.
 
@@ -513,7 +693,7 @@ Tpm2PcrAllocate (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
     Status = EFI_BUFFER_TOO_SMALL;
     goto Done;
   }
@@ -523,7 +703,7 @@ Tpm2PcrAllocate (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
     Status = EFI_BUFFER_TOO_SMALL;
     goto Done;
   }
@@ -532,7 +712,7 @@ Tpm2PcrAllocate (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
     Status = EFI_DEVICE_ERROR;
     goto Done;
   }
@@ -673,15 +853,15 @@ Tpm2PcrAllocateBanks (
              &SizeNeeded,
              &SizeAvailable
              );
-  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
+  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
   if (EFI_ERROR (Status)) {
     goto Done;
   }
 
-  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
-  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
-  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
-  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
+  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));
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index 19b8e4b318..678826f8a5 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -147,7 +147,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
   }
 };
 
-
 /**
   Record all measured Firmware Volume Information into a Guid Hob
   Guid Hob payload layout is
@@ -223,7 +222,7 @@ SyncPcrAllocationsAndPcrMask (
   UINT32                            Tpm2PcrMask;
   UINT32                            NewTpm2PcrMask;
 
-  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
+  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
 
   //
   // Determine the current TPM support and the Platform PCR mask.
@@ -234,7 +233,7 @@ SyncPcrAllocationsAndPcrMask (
   Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
   if (Tpm2PcrMask == 0) {
     //
-    // if PcdTPm2HashMask is zero, use ActivePcr setting
+    // if PcdTpm2HashMask is zero, use ActivePcr setting
     //
     PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
     Tpm2PcrMask = TpmActivePcrBanks;
@@ -253,9 +252,9 @@ SyncPcrAllocationsAndPcrMask (
   if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
     NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
 
-    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
+    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
     if (NewTpmActivePcrBanks == 0) {
-      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
       ASSERT (FALSE);
     } else {
       Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, NewTpmActivePcrBanks);
@@ -263,7 +262,7 @@ SyncPcrAllocationsAndPcrMask (
         //
         // We can't do much here, but we hope that this doesn't happen.
         //
-        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));
+        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));
         ASSERT_EFI_ERROR (Status);
       }
       //
@@ -280,9 +279,9 @@ SyncPcrAllocationsAndPcrMask (
   if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
     NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
 
-    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
+    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
     if (NewTpm2PcrMask == 0) {
-      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
       ASSERT (FALSE);
     }
 
@@ -321,7 +320,7 @@ LogHashEvent (
   RetStatus = EFI_SUCCESS;
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
     if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
-      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
+      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
       switch (mTcg2EventInfo[Index].LogFormat) {
       case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
         Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
@@ -416,7 +415,7 @@ HashLogExtendEvent (
   }
 
   if (Status == EFI_DEVICE_ERROR) {
-    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
+    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
     BuildGuidHob (&gTpmErrorHobGuid,0);
     REPORT_STATUS_CODE (
       EFI_ERROR_CODE | EFI_ERROR_MINOR,
@@ -925,7 +924,7 @@ PeimEntryMA (
   }
 
   if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
-    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
+    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
     return EFI_DEVICE_ERROR;
   }
 
@@ -989,7 +988,7 @@ PeimEntryMA (
       for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
         Status = MeasureSeparatorEventWithError (PcrIndex);
         if (EFI_ERROR (Status)) {
-          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
+          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured. Error!\n"));
         }
       }
     }
@@ -1006,6 +1005,13 @@ PeimEntryMA (
       }
     }
 
+    DEBUG_CODE_BEGIN ();
+    //
+    // Peek into TPM PCR 00 before any BIOS measurement.
+    //
+    Tpm2ActivePcrRegisterRead (00, NULL);
+    DEBUG_CODE_END ();
+
     //
     // Only install TpmInitializedPpi on success
     //
@@ -1020,7 +1026,7 @@ PeimEntryMA (
 
 Done:
   if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
+    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
     BuildGuidHob (&gTpmErrorHobGuid,0);
     REPORT_STATUS_CODE (
       EFI_ERROR_CODE | EFI_ERROR_MINOR,
-- 
2.27.0.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
  2020-07-20 22:28 [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations Rodrigo Gonzalez del Cueto
@ 2020-07-23  2:06 ` Yao, Jiewen
  0 siblings, 0 replies; 8+ messages in thread
From: Yao, Jiewen @ 2020-07-23  2:06 UTC (permalink / raw)
  To: Gonzalez Del Cueto, Rodrigo, devel@edk2.groups.io
  Cc: Wang, Jian J, Zhang, Qi1

Here is some initial feedback:

1) Please don't change function header Tpm2PcrEvent() and Tpm2PcrRead() in Tpm2CommandLib.h

2) Please don't move Tpm2PcrRead() function in Tpm2Integrity.c, so that I can know what you have changed.

3) Please add Tpm2ActivePcrRegisterRead() as the last function in Tpm2Integrity.c

4) Please use DEBUG_VERBOSE for the new debug log. We got feedback before that there are too many debug messages in TPM driver.

5) Below code is weird in Tpm2ActivePcrRegisterRead().
  UINT32                            PcrIndex; 
  PcrIndex = (UINT8)PcrHandle;

Why you define it as UINT32 and cast it as UINT8?

6) Please use 2 spaces indent for the function header.

EFI_STATUS
EFIAPI
Tpm2ActivePcrRegisterRead (
 IN      TPMI_DH_PCR                PcrHandle,
 OUT     TPML_DIGEST                *HashList
)

7) The name of Tpm2ActivePcrRegisterRead() is confusing. What you try to do is to read the PCR for the active bank. Maybe Tpm2PcrReadForActiveBank() ?

Thank you
Yao Jiewen


> -----Original Message-----
> From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>
> Sent: Tuesday, July 21, 2020 6:29 AM
> To: devel@edk2.groups.io
> Cc: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Zhang,
> Qi1 <qi1.zhang@intel.com>
> Subject: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858
> 
> Add debug functionality to examine TPM extend operations
> performed by BIOS and inspect the PCR 00 value prior to
> any BIOS measurements.
> 
> Replaced usage of EFI_D_* for DEBUG_* definitions in debug
> messages.
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Qi Zhang <qi1.zhang@intel.com>
> Signed-off-by: Rodrigo Gonzalez del Cueto
> <rodrigo.gonzalez.del.cueto@intel.com>
> ---
>  SecurityPkg/Include/Library/Tpm2CommandLib.h  |  25 +-
>  .../Library/Tpm2CommandLib/Tpm2Integrity.c    | 468 ++++++++++++------
>  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c             |  32 +-
>  3 files changed, 364 insertions(+), 161 deletions(-)
> 
> diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> index ce381e786b..bfa5bd82f4 100644
> --- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> +++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> @@ -505,7 +505,7 @@ EFIAPI
>  Tpm2PcrEvent (
> 
>    IN      TPMI_DH_PCR               PcrHandle,
> 
>    IN      TPM2B_EVENT               *EventData,
> 
> -     OUT  TPML_DIGEST_VALUES        *Digests
> 
> +  OUT  TPML_DIGEST_VALUES        *Digests
> 
>    );
[Jiewen] Why you need this this?

> 
> 
> 
>  /**
> 
> @@ -523,9 +523,26 @@ EFI_STATUS
>  EFIAPI
> 
>  Tpm2PcrRead (
> 
>    IN      TPML_PCR_SELECTION        *PcrSelectionIn,
> 
> -     OUT  UINT32                    *PcrUpdateCounter,
> 
> -     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> 
> -     OUT  TPML_DIGEST               *PcrValues
> 
> +  OUT  UINT32                    *PcrUpdateCounter,
> 
> +  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> 
> +  OUT  TPML_DIGEST               *PcrValues
> 
> +  ); 
> 
> +
> 
> +/**
> 
> +   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
> 
> +Tpm2ActivePcrRegisterRead (
> 
> +  IN      TPMI_DH_PCR                PcrHandle,
> 
> +  OUT     TPML_DIGEST                *HashList
> 
>    );
> 
> 
> 
>  /**
> 
> diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> index ddb15178fb..229fc44139 100644
> --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> @@ -76,6 +76,297 @@ typedef struct {
> 
> 
>  #pragma pack()
> 
> 
> 
> +/**
> 
> +  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 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
> 
> +Tpm2ActivePcrRegisterRead (
> 
> + 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;
> 
> +  UINT32                            PcrIndex;
> 
> +  UINT32                            TpmHashAlgorithmBitmap;
> 
> +  TPMI_ALG_HASH                     CurrentPcrBankHash;
> 
> +  UINT32                            ActivePcrBanks;
> 
> +  UINT32                            TcgRegistryHashAlg;
> 
> +  UINT32                            Index;
> 
> +  UINT32                            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));
> 
> +
> 
> +  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
> 
> +
> 
> +  //
> 
> +  // 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;
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < PcrValues.count; Index++) {
> 
> +    DEBUG ((
> 
> +      DEBUG_INFO,
> 
> +      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
> 
> +      PcrSelectionOut.pcrSelections[Index].hash,
> 
> +      PcrIndex
> 
> +      ));
> 
> +
> 
> +    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
> 
> +      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
> 
> +    }
> 
> +    DEBUG ((DEBUG_INFO, "\n"));
> 
> +  }
> 
> +
> 
> +  if (HashList != NULL) {
> 
> +    CopyMem (
> 
> +      HashList,
> 
> +      &PcrValues,
> 
> +      sizeof (TPML_DIGEST)
> 
> +      );
> 
> +  }
> 
> +
> 
> +  return EFI_SUCCESS;
> 
> +}
> 
> +
> 
>  /**
> 
>    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.
> 
> @@ -130,14 +421,26 @@ Tpm2PcrExtend (
>      Buffer += sizeof(UINT16);
> 
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
> 
>      if (DigestSize == 0) {
> 
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> 
> +      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_INFO, "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest
> = ", Digests->digests[Index].hashAlg, (UINT8) PcrHandle));
> 
> +
> 
> +    for (Index2 = 0; Index2 < DigestSize; Index2++) {
> 
> +      DEBUG ((DEBUG_INFO, "%02x ", Buffer[Index2]));
> 
> +    }
> 
> +    DEBUG ((DEBUG_INFO, "\n"));
> 
> +    DEBUG_CODE_END ();
> 
> +
> 
>      Buffer += DigestSize;
> 
>    }
> 
> 
> 
> @@ -151,7 +454,7 @@ Tpm2PcrExtend (
>    }
> 
> 
> 
>    if (ResultBufSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> 
>      return EFI_BUFFER_TOO_SMALL;
> 
>    }
> 
> 
> 
> @@ -160,7 +463,7 @@ Tpm2PcrExtend (
>    //
> 
>    RespSize = SwapBytes32(Res.Header.paramSize);
> 
>    if (RespSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
> 
>      return EFI_BUFFER_TOO_SMALL;
> 
>    }
> 
> 
> 
> @@ -168,10 +471,15 @@ Tpm2PcrExtend (
>    // Fail if command failed
> 
>    //
> 
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
> 
>      return EFI_DEVICE_ERROR;
> 
>    }
> 
> 
> 
> +  DEBUG_CODE_BEGIN ();
> 
> +  DEBUG ((DEBUG_INFO, "Tpm2PcrExtend: PCR read after extend...\n"));
> 
> +  Tpm2ActivePcrRegisterRead (PcrHandle, NULL);
> 
> +  DEBUG_CODE_END ();
> 
> +
> 
>    //
> 
>    // Unmarshal the response
> 
>    //
> 
> @@ -246,7 +554,7 @@ Tpm2PcrEvent (
>    }
> 
> 
> 
>    if (ResultBufSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> 
>      return EFI_BUFFER_TOO_SMALL;
> 
>    }
> 
> 
> 
> @@ -255,7 +563,7 @@ Tpm2PcrEvent (
>    //
> 
>    RespSize = SwapBytes32(Res.Header.paramSize);
> 
>    if (RespSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
> 
>      return EFI_BUFFER_TOO_SMALL;
> 
>    }
> 
> 
> 
> @@ -263,7 +571,7 @@ Tpm2PcrEvent (
>    // Fail if command failed
> 
>    //
> 
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
> 
>      return EFI_DEVICE_ERROR;
> 
>    }
> 
> 
> 
> @@ -284,7 +592,7 @@ Tpm2PcrEvent (
>      Buffer += sizeof(UINT16);
> 
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
> 
>      if (DigestSize == 0) {
> 
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> 
> +      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> 
>        return EFI_DEVICE_ERROR;
> 
>      }
> 
>      CopyMem(
> 
> @@ -298,134 +606,6 @@ Tpm2PcrEvent (
>    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 ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> 
> -    return EFI_DEVICE_ERROR;
> 
> -  }
> 
> -  if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
> 
> -    DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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.
> 
> 
> 
> @@ -513,7 +693,7 @@ Tpm2PcrAllocate (
>    }
> 
> 
> 
>    if (ResultBufSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand:
> Buffer Too Small\r\n"));
> 
>      Status = EFI_BUFFER_TOO_SMALL;
> 
>      goto Done;
> 
>    }
> 
> @@ -523,7 +703,7 @@ Tpm2PcrAllocate (
>    //
> 
>    RespSize = SwapBytes32(Res.Header.paramSize);
> 
>    if (RespSize > sizeof(Res)) {
> 
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n",
> RespSize));
> 
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too
> large! %d\r\n", RespSize));
> 
>      Status = EFI_BUFFER_TOO_SMALL;
> 
>      goto Done;
> 
>    }
> 
> @@ -532,7 +712,7 @@ Tpm2PcrAllocate (
>    // Fail if command failed
> 
>    //
> 
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> 
> -    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> 
> +    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
> 
>      Status = EFI_DEVICE_ERROR;
> 
>      goto Done;
> 
>    }
> 
> @@ -673,15 +853,15 @@ Tpm2PcrAllocateBanks (
>               &SizeNeeded,
> 
>               &SizeAvailable
> 
>               );
> 
> -  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
> 
> +  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
> 
>    if (EFI_ERROR (Status)) {
> 
>      goto Done;
> 
>    }
> 
> 
> 
> -  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
> 
> -  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
> 
> -  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
> 
> -  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
> 
> +  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));
> 
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index 19b8e4b318..678826f8a5 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -147,7 +147,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
>    }
> 
>  };
> 
> 
> 
> -
> 
>  /**
> 
>    Record all measured Firmware Volume Information into a Guid Hob
> 
>    Guid Hob payload layout is
> 
> @@ -223,7 +222,7 @@ SyncPcrAllocationsAndPcrMask (
>    UINT32                            Tpm2PcrMask;
> 
>    UINT32                            NewTpm2PcrMask;
> 
> 
> 
> -  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> 
> +  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> 
> 
> 
>    //
> 
>    // Determine the current TPM support and the Platform PCR mask.
> 
> @@ -234,7 +233,7 @@ SyncPcrAllocationsAndPcrMask (
>    Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
> 
>    if (Tpm2PcrMask == 0) {
> 
>      //
> 
> -    // if PcdTPm2HashMask is zero, use ActivePcr setting
> 
> +    // if PcdTpm2HashMask is zero, use ActivePcr setting
> 
>      //
> 
>      PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
> 
>      Tpm2PcrMask = TpmActivePcrBanks;
> 
> @@ -253,9 +252,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
> 
>      NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
> 
> 
> 
> -    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
> 
> +    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
> 
>      if (NewTpmActivePcrBanks == 0) {
> 
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> 
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> 
>        ASSERT (FALSE);
> 
>      } else {
> 
>        Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap,
> NewTpmActivePcrBanks);
> 
> @@ -263,7 +262,7 @@ SyncPcrAllocationsAndPcrMask (
>          //
> 
>          // We can't do much here, but we hope that this doesn't happen.
> 
>          //
> 
> -        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
> 
> +        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
> 
>          ASSERT_EFI_ERROR (Status);
> 
>        }
> 
>        //
> 
> @@ -280,9 +279,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
> 
>      NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
> 
> 
> 
> -    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
> 
> +    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
> 
>      if (NewTpm2PcrMask == 0) {
> 
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> 
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> 
>        ASSERT (FALSE);
> 
>      }
> 
> 
> 
> @@ -321,7 +320,7 @@ LogHashEvent (
>    RetStatus = EFI_SUCCESS;
> 
>    for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]);
> Index++) {
> 
>      if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
> 
> -      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
> 
> +      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
> 
>        switch (mTcg2EventInfo[Index].LogFormat) {
> 
>        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
> 
>          Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList,
> &NewEventHdr->Digest);
> 
> @@ -416,7 +415,7 @@ HashLogExtendEvent (
>    }
> 
> 
> 
>    if (Status == EFI_DEVICE_ERROR) {
> 
> -    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
> 
> +    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n",
> Status));
> 
>      BuildGuidHob (&gTpmErrorHobGuid,0);
> 
>      REPORT_STATUS_CODE (
> 
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> 
> @@ -925,7 +924,7 @@ PeimEntryMA (
>    }
> 
> 
> 
>    if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
> 
> -    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
> 
> +    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
> 
>      return EFI_DEVICE_ERROR;
> 
>    }
> 
> 
> 
> @@ -989,7 +988,7 @@ PeimEntryMA (
>        for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
> 
>          Status = MeasureSeparatorEventWithError (PcrIndex);
> 
>          if (EFI_ERROR (Status)) {
> 
> -          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
> 
> +          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
> 
>          }
> 
>        }
> 
>      }
> 
> @@ -1006,6 +1005,13 @@ PeimEntryMA (
>        }
> 
>      }
> 
> 
> 
> +    DEBUG_CODE_BEGIN ();
> 
> +    //
> 
> +    // Peek into TPM PCR 00 before any BIOS measurement.
> 
> +    //
> 
> +    Tpm2ActivePcrRegisterRead (00, NULL);
> 
> +    DEBUG_CODE_END ();
> 
> +
> 
>      //
> 
>      // Only install TpmInitializedPpi on success
> 
>      //
> 
> @@ -1020,7 +1026,7 @@ PeimEntryMA (
> 
> 
>  Done:
> 
>    if (EFI_ERROR (Status)) {
> 
> -    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
> 
> +    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
> 
>      BuildGuidHob (&gTpmErrorHobGuid,0);
> 
>      REPORT_STATUS_CODE (
> 
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> 
> --
> 2.27.0.windows.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
@ 2021-07-29 22:43 Rodrigo Gonzalez del Cueto
  2021-08-09  1:24 ` Yao, Jiewen
  0 siblings, 1 reply; 8+ messages in thread
From: Rodrigo Gonzalez del Cueto @ 2021-07-29 22:43 UTC (permalink / raw)
  To: devel; +Cc: Rodrigo Gonzalez del Cueto, Jiewen Yao, Jian J Wang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858

Add debug functionality to examine TPM extend operations
performed by BIOS and inspect the PCR 00 value prior to
any BIOS measurements.

Replaced usage of EFI_D_* for DEBUG_* definitions in debug
messages.

Signed-off-by: Rodrigo Gonzalez del Cueto <rodrigo.gonzalez.del.cueto@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h       |  28 ++++++++++++++++++++++------
 SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
 SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |  34 ++++++++++++++++++++--------------
 3 files changed, 245 insertions(+), 43 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index ee8eb62295..5e5c340893 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
 /** @file
   This library is used by other modules to send TPM2 command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -505,7 +505,7 @@ EFIAPI
 Tpm2PcrEvent (
   IN      TPMI_DH_PCR               PcrHandle,
   IN      TPM2B_EVENT               *EventData,
-     OUT  TPML_DIGEST_VALUES        *Digests
+  OUT     TPML_DIGEST_VALUES        *Digests
   );
 
 /**
@@ -522,10 +522,10 @@ Tpm2PcrEvent (
 EFI_STATUS
 EFIAPI
 Tpm2PcrRead (
-  IN      TPML_PCR_SELECTION        *PcrSelectionIn,
-     OUT  UINT32                    *PcrUpdateCounter,
-     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
-     OUT  TPML_DIGEST               *PcrValues
+  IN   TPML_PCR_SELECTION        *PcrSelectionIn,
+  OUT  UINT32                    *PcrUpdateCounter,
+  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
+  OUT  TPML_DIGEST               *PcrValues
   );
 
 /**
@@ -1113,4 +1113,20 @@ GetDigestFromDigestList(
   OUT VOID              *Digest
   );
 
+  /**
+   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
+  );
 #endif
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
index ddb15178fb..3b49192b93 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
@@ -1,7 +1,7 @@
 /** @file
   Implement TPM2 Integrity related command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -109,7 +109,6 @@ Tpm2PcrExtend (
   Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
   Cmd.PcrHandle          = SwapBytes32(PcrHandle);
 
-
   //
   // Add in Auth session
   //
@@ -130,14 +129,26 @@ Tpm2PcrExtend (
     Buffer += sizeof(UINT16);
     DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
     if (DigestSize == 0) {
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
+      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;
   }
 
@@ -151,7 +162,7 @@ Tpm2PcrExtend (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -160,7 +171,7 @@ Tpm2PcrExtend (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -168,10 +179,15 @@ Tpm2PcrExtend (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    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
   //
@@ -246,7 +262,7 @@ Tpm2PcrEvent (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -255,7 +271,7 @@ Tpm2PcrEvent (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));
     return EFI_BUFFER_TOO_SMALL;
   }
 
@@ -263,7 +279,7 @@ Tpm2PcrEvent (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
     return EFI_DEVICE_ERROR;
   }
 
@@ -284,7 +300,7 @@ Tpm2PcrEvent (
     Buffer += sizeof(UINT16);
     DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
     if (DigestSize == 0) {
-      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
+      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));
       return EFI_DEVICE_ERROR;
     }
     CopyMem(
@@ -298,6 +314,7 @@ Tpm2PcrEvent (
   return EFI_SUCCESS;
 }
 
+
 /**
   This command returns the values of all PCR specified in pcrSelect.
 
@@ -353,11 +370,11 @@ Tpm2PcrRead (
   }
 
   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
     return EFI_DEVICE_ERROR;
   }
   if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
     return EFI_NOT_FOUND;
   }
 
@@ -369,7 +386,7 @@ Tpm2PcrRead (
   // PcrUpdateCounter
   //
   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
     return EFI_DEVICE_ERROR;
   }
   *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
@@ -378,7 +395,7 @@ Tpm2PcrRead (
   // PcrSelectionOut
   //
   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
     return EFI_DEVICE_ERROR;
   }
   PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
@@ -388,7 +405,7 @@ Tpm2PcrRead (
   }
 
   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));
     return EFI_DEVICE_ERROR;
   }
   for (Index = 0; Index < PcrSelectionOut->count; Index++) {
@@ -513,7 +530,7 @@ Tpm2PcrAllocate (
   }
 
   if (ResultBufSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
     Status = EFI_BUFFER_TOO_SMALL;
     goto Done;
   }
@@ -523,7 +540,7 @@ Tpm2PcrAllocate (
   //
   RespSize = SwapBytes32(Res.Header.paramSize);
   if (RespSize > sizeof(Res)) {
-    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));
     Status = EFI_BUFFER_TOO_SMALL;
     goto Done;
   }
@@ -532,7 +549,7 @@ Tpm2PcrAllocate (
   // Fail if command failed
   //
   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
-    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
+    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
     Status = EFI_DEVICE_ERROR;
     goto Done;
   }
@@ -673,17 +690,180 @@ Tpm2PcrAllocateBanks (
              &SizeNeeded,
              &SizeAvailable
              );
-  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
+  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));
   if (EFI_ERROR (Status)) {
     goto Done;
   }
 
-  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
-  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
-  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
-  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
+  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));
+
+  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
+
+  //
+  // 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;
+  }
+
+  for (Index = 0; Index < PcrValues.count; Index++) {
+    DEBUG ((
+      DEBUG_INFO,
+      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
+      PcrSelectionOut.pcrSelections[Index].hash,
+      PcrIndex
+      ));
+
+    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
+      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
+    }
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+
+  if (HashList != NULL) {
+    CopyMem (
+      HashList,
+      &PcrValues,
+      sizeof (TPML_DIGEST)
+      );
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index 93a8803ff6..ea79fa0af6 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -1,7 +1,7 @@
 /** @file
   Initialize TPM2 device and measure FVs before handing off control to DXE.
 
-Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
 Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -191,7 +191,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
   }
 };
 
-
 /**
   Record all measured Firmware Volume Information into a Guid Hob
   Guid Hob payload layout is
@@ -267,7 +266,7 @@ SyncPcrAllocationsAndPcrMask (
   UINT32                            Tpm2PcrMask;
   UINT32                            NewTpm2PcrMask;
 
-  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
+  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
 
   //
   // Determine the current TPM support and the Platform PCR mask.
@@ -278,7 +277,7 @@ SyncPcrAllocationsAndPcrMask (
   Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
   if (Tpm2PcrMask == 0) {
     //
-    // if PcdTPm2HashMask is zero, use ActivePcr setting
+    // if PcdTpm2HashMask is zero, use ActivePcr setting
     //
     PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
     Tpm2PcrMask = TpmActivePcrBanks;
@@ -297,9 +296,9 @@ SyncPcrAllocationsAndPcrMask (
   if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
     NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
 
-    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
+    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
     if (NewTpmActivePcrBanks == 0) {
-      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
       ASSERT (FALSE);
     } else {
       Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, NewTpmActivePcrBanks);
@@ -307,7 +306,7 @@ SyncPcrAllocationsAndPcrMask (
         //
         // We can't do much here, but we hope that this doesn't happen.
         //
-        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));
+        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__));
         ASSERT_EFI_ERROR (Status);
       }
       //
@@ -324,9 +323,9 @@ SyncPcrAllocationsAndPcrMask (
   if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
     NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
 
-    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
+    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
     if (NewTpm2PcrMask == 0) {
-      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
+      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
       ASSERT (FALSE);
     }
 
@@ -365,7 +364,7 @@ LogHashEvent (
   RetStatus = EFI_SUCCESS;
   for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) {
     if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
-      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
+      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat));
       switch (mTcg2EventInfo[Index].LogFormat) {
       case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
         Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
@@ -476,7 +475,7 @@ HashLogExtendEvent (
   }
 
   if (Status == EFI_DEVICE_ERROR) {
-    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
+    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
     BuildGuidHob (&gTpmErrorHobGuid,0);
     REPORT_STATUS_CODE (
       EFI_ERROR_CODE | EFI_ERROR_MINOR,
@@ -1011,7 +1010,7 @@ PeimEntryMA (
   }
 
   if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
-    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
+    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
     return EFI_DEVICE_ERROR;
   }
 
@@ -1075,7 +1074,7 @@ PeimEntryMA (
       for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
         Status = MeasureSeparatorEventWithError (PcrIndex);
         if (EFI_ERROR (Status)) {
-          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
+          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured. Error!\n"));
         }
       }
     }
@@ -1092,6 +1091,13 @@ PeimEntryMA (
       }
     }
 
+    DEBUG_CODE_BEGIN ();
+    //
+    // Peek into TPM PCR 00 before any BIOS measurement.
+    //
+    Tpm2PcrReadForActiveBank (00, NULL);
+    DEBUG_CODE_END ();
+
     //
     // Only install TpmInitializedPpi on success
     //
@@ -1106,7 +1112,7 @@ PeimEntryMA (
 
 Done:
   if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
+    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
     BuildGuidHob (&gTpmErrorHobGuid,0);
     REPORT_STATUS_CODE (
       EFI_ERROR_CODE | EFI_ERROR_MINOR,
-- 
2.31.1.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
  2021-07-29 22:43 Rodrigo Gonzalez del Cueto
@ 2021-08-09  1:24 ` Yao, Jiewen
  2021-08-10  6:40   ` Rodrigo Gonzalez del Cueto
  0 siblings, 1 reply; 8+ messages in thread
From: Yao, Jiewen @ 2021-08-09  1:24 UTC (permalink / raw)
  To: Gonzalez Del Cueto, Rodrigo, devel@edk2.groups.io; +Cc: Wang, Jian J

Some feedback:

1) I think it is OK to add Tpm2PcrReadForActiveBank() API.
But I feel we will add too many noise to dump Tpm2PcrReadForActiveBank() in the code everytime.
I am not sure why it is needed.
What is the problem statement?

2) Below definition does not follow EDKII coding style. Please use 2 "space" as indent.
EFI_STATUS
EFIAPI
Tpm2PcrReadForActiveBank (
 IN      TPMI_DH_PCR                PcrHandle,
 OUT     TPML_DIGEST                *HashList
)



> -----Original Message-----
> From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>
> Sent: Friday, July 30, 2021 6:43 AM
> To: devel@edk2.groups.io
> Cc: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>
> Subject: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858
> 
> Add debug functionality to examine TPM extend operations
> performed by BIOS and inspect the PCR 00 value prior to
> any BIOS measurements.
> 
> Replaced usage of EFI_D_* for DEBUG_* definitions in debug
> messages.
> 
> Signed-off-by: Rodrigo Gonzalez del Cueto
> <rodrigo.gonzalez.del.cueto@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> ---
>  SecurityPkg/Include/Library/Tpm2CommandLib.h       |  28
> ++++++++++++++++++++++------
>  SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 226
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++-----------------------
>  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |  34 ++++++++++++++++++++------
> --------
>  3 files changed, 245 insertions(+), 43 deletions(-)
> 
> diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> index ee8eb62295..5e5c340893 100644
> --- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> +++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> @@ -1,7 +1,7 @@
>  /** @file
>    This library is used by other modules to send TPM2 command.
> 
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -505,7 +505,7 @@ EFIAPI
>  Tpm2PcrEvent (
>    IN      TPMI_DH_PCR               PcrHandle,
>    IN      TPM2B_EVENT               *EventData,
> -     OUT  TPML_DIGEST_VALUES        *Digests
> +  OUT     TPML_DIGEST_VALUES        *Digests
>    );
> 
>  /**
> @@ -522,10 +522,10 @@ Tpm2PcrEvent (
>  EFI_STATUS
>  EFIAPI
>  Tpm2PcrRead (
> -  IN      TPML_PCR_SELECTION        *PcrSelectionIn,
> -     OUT  UINT32                    *PcrUpdateCounter,
> -     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> -     OUT  TPML_DIGEST               *PcrValues
> +  IN   TPML_PCR_SELECTION        *PcrSelectionIn,
> +  OUT  UINT32                    *PcrUpdateCounter,
> +  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> +  OUT  TPML_DIGEST               *PcrValues
>    );
> 
>  /**
> @@ -1113,4 +1113,20 @@ GetDigestFromDigestList(
>    OUT VOID              *Digest
>    );
> 
> +  /**
> +   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
> +  );
>  #endif
> diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> index ddb15178fb..3b49192b93 100644
> --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Implement TPM2 Integrity related command.
> 
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -109,7 +109,6 @@ Tpm2PcrExtend (
>    Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
>    Cmd.PcrHandle          = SwapBytes32(PcrHandle);
> 
> -
>    //
>    // Add in Auth session
>    //
> @@ -130,14 +129,26 @@ Tpm2PcrExtend (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      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;
>    }
> 
> @@ -151,7 +162,7 @@ Tpm2PcrExtend (
>    }
> 
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
> 
> @@ -160,7 +171,7 @@ Tpm2PcrExtend (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
> 
> @@ -168,10 +179,15 @@ Tpm2PcrExtend (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    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
>    //
> @@ -246,7 +262,7 @@ Tpm2PcrEvent (
>    }
> 
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
> 
> @@ -255,7 +271,7 @@ Tpm2PcrEvent (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
> 
> @@ -263,7 +279,7 @@ Tpm2PcrEvent (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      return EFI_DEVICE_ERROR;
>    }
> 
> @@ -284,7 +300,7 @@ Tpm2PcrEvent (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
>        return EFI_DEVICE_ERROR;
>      }
>      CopyMem(
> @@ -298,6 +314,7 @@ Tpm2PcrEvent (
>    return EFI_SUCCESS;
>  }
> 
> +
>  /**
>    This command returns the values of all PCR specified in pcrSelect.
> 
> @@ -353,11 +370,11 @@ Tpm2PcrRead (
>    }
> 
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
>      return EFI_NOT_FOUND;
>    }
> 
> @@ -369,7 +386,7 @@ Tpm2PcrRead (
>    // PcrUpdateCounter
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
> @@ -378,7 +395,7 @@ Tpm2PcrRead (
>    // PcrSelectionOut
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
> @@ -388,7 +405,7 @@ Tpm2PcrRead (
>    }
> 
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count) +
> sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    for (Index = 0; Index < PcrSelectionOut->count; Index++) {
> @@ -513,7 +530,7 @@ Tpm2PcrAllocate (
>    }
> 
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand:
> Buffer Too Small\r\n"));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -523,7 +540,7 @@ Tpm2PcrAllocate (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too
> large! %d\r\n", RespSize));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -532,7 +549,7 @@ Tpm2PcrAllocate (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      Status = EFI_DEVICE_ERROR;
>      goto Done;
>    }
> @@ -673,17 +690,180 @@ Tpm2PcrAllocateBanks (
>               &SizeNeeded,
>               &SizeAvailable
>               );
> -  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
> +  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
>    if (EFI_ERROR (Status)) {
>      goto Done;
>    }
> 
> -  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
> -  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
> -  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
> -  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
> +  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));
> +
> +  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
> +
> +  //
> +  // 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;
> +  }
> +
> +  for (Index = 0; Index < PcrValues.count; Index++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
> +      PcrSelectionOut.pcrSelections[Index].hash,
> +      PcrIndex
> +      ));
> +
> +    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
> +      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +
> +  if (HashList != NULL) {
> +    CopyMem (
> +      HashList,
> +      &PcrValues,
> +      sizeof (TPML_DIGEST)
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index 93a8803ff6..ea79fa0af6 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Initialize TPM2 device and measure FVs before handing off control to DXE.
> 
> -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
>  Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -191,7 +191,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
>    }
>  };
> 
> -
>  /**
>    Record all measured Firmware Volume Information into a Guid Hob
>    Guid Hob payload layout is
> @@ -267,7 +266,7 @@ SyncPcrAllocationsAndPcrMask (
>    UINT32                            Tpm2PcrMask;
>    UINT32                            NewTpm2PcrMask;
> 
> -  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> +  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> 
>    //
>    // Determine the current TPM support and the Platform PCR mask.
> @@ -278,7 +277,7 @@ SyncPcrAllocationsAndPcrMask (
>    Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
>    if (Tpm2PcrMask == 0) {
>      //
> -    // if PcdTPm2HashMask is zero, use ActivePcr setting
> +    // if PcdTpm2HashMask is zero, use ActivePcr setting
>      //
>      PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
>      Tpm2PcrMask = TpmActivePcrBanks;
> @@ -297,9 +296,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
>      NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
> 
> -    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
> +    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
>      if (NewTpmActivePcrBanks == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      } else {
>        Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap,
> NewTpmActivePcrBanks);
> @@ -307,7 +306,7 @@ SyncPcrAllocationsAndPcrMask (
>          //
>          // We can't do much here, but we hope that this doesn't happen.
>          //
> -        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
> +        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
>          ASSERT_EFI_ERROR (Status);
>        }
>        //
> @@ -324,9 +323,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
>      NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
> 
> -    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
> +    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
>      if (NewTpm2PcrMask == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      }
> 
> @@ -365,7 +364,7 @@ LogHashEvent (
>    RetStatus = EFI_SUCCESS;
>    for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]);
> Index++) {
>      if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
> -      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
> +      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
>        switch (mTcg2EventInfo[Index].LogFormat) {
>        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
>          Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList,
> &NewEventHdr->Digest);
> @@ -476,7 +475,7 @@ HashLogExtendEvent (
>    }
> 
>    if (Status == EFI_DEVICE_ERROR) {
> -    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
> +    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n",
> Status));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> @@ -1011,7 +1010,7 @@ PeimEntryMA (
>    }
> 
>    if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
>      return EFI_DEVICE_ERROR;
>    }
> 
> @@ -1075,7 +1074,7 @@ PeimEntryMA (
>        for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
>          Status = MeasureSeparatorEventWithError (PcrIndex);
>          if (EFI_ERROR (Status)) {
> -          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
> +          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
>          }
>        }
>      }
> @@ -1092,6 +1091,13 @@ PeimEntryMA (
>        }
>      }
> 
> +    DEBUG_CODE_BEGIN ();
> +    //
> +    // Peek into TPM PCR 00 before any BIOS measurement.
> +    //
> +    Tpm2PcrReadForActiveBank (00, NULL);
> +    DEBUG_CODE_END ();
> +
>      //
>      // Only install TpmInitializedPpi on success
>      //
> @@ -1106,7 +1112,7 @@ PeimEntryMA (
> 
>  Done:
>    if (EFI_ERROR (Status)) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> --
> 2.31.1.windows.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
  2021-08-09  1:24 ` Yao, Jiewen
@ 2021-08-10  6:40   ` Rodrigo Gonzalez del Cueto
  2021-08-11  5:39     ` Yao, Jiewen
  0 siblings, 1 reply; 8+ messages in thread
From: Rodrigo Gonzalez del Cueto @ 2021-08-10  6:40 UTC (permalink / raw)
  To: Yao, Jiewen, devel@edk2.groups.io; +Cc: Wang, Jian J

[-- Attachment #1: Type: text/plain, Size: 26252 bytes --]

Hi Jiewen,

The intention of such API would be to ease debugging and auditing PCR attestation along the boot; it has been a common task while debugging several issues and TPM configurations.

a) Configurations in which BIOS is not the S-CRTM and we need to attest what has been measured to the TPM prior to any measurements performed by BIOS.
b) Verifying the values in all the active and supported PCR banks: attestation or capping of the PCRs. (See BZ: 3515<https://bugzilla.tianocore.org/show_bug.cgi?id=3515>)

Such API together with the TCG event log print out it allows us to audit and debug the measured boot sequence.

Regards,
-Rodrigo
________________________________
From: Yao, Jiewen <jiewen.yao@intel.com>
Sent: Sunday, August 8, 2021 6:24 PM
To: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>; devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Wang, Jian J <jian.j.wang@intel.com>
Subject: RE: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.

Some feedback:

1) I think it is OK to add Tpm2PcrReadForActiveBank() API.
But I feel we will add too many noise to dump Tpm2PcrReadForActiveBank() in the code everytime.
I am not sure why it is needed.
What is the problem statement?

2) Below definition does not follow EDKII coding style. Please use 2 "space" as indent.
EFI_STATUS
EFIAPI
Tpm2PcrReadForActiveBank (
 IN      TPMI_DH_PCR                PcrHandle,
 OUT     TPML_DIGEST                *HashList
)



> -----Original Message-----
> From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>
> Sent: Friday, July 30, 2021 6:43 AM
> To: devel@edk2.groups.io
> Cc: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>
> Subject: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858
>
> Add debug functionality to examine TPM extend operations
> performed by BIOS and inspect the PCR 00 value prior to
> any BIOS measurements.
>
> Replaced usage of EFI_D_* for DEBUG_* definitions in debug
> messages.
>
> Signed-off-by: Rodrigo Gonzalez del Cueto
> <rodrigo.gonzalez.del.cueto@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> ---
>  SecurityPkg/Include/Library/Tpm2CommandLib.h       |  28
> ++++++++++++++++++++++------
>  SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 226
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++-----------------------
>  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |  34 ++++++++++++++++++++------
> --------
>  3 files changed, 245 insertions(+), 43 deletions(-)
>
> diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> index ee8eb62295..5e5c340893 100644
> --- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> +++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> @@ -1,7 +1,7 @@
>  /** @file
>    This library is used by other modules to send TPM2 command.
>
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
>  **/
> @@ -505,7 +505,7 @@ EFIAPI
>  Tpm2PcrEvent (
>    IN      TPMI_DH_PCR               PcrHandle,
>    IN      TPM2B_EVENT               *EventData,
> -     OUT  TPML_DIGEST_VALUES        *Digests
> +  OUT     TPML_DIGEST_VALUES        *Digests
>    );
>
>  /**
> @@ -522,10 +522,10 @@ Tpm2PcrEvent (
>  EFI_STATUS
>  EFIAPI
>  Tpm2PcrRead (
> -  IN      TPML_PCR_SELECTION        *PcrSelectionIn,
> -     OUT  UINT32                    *PcrUpdateCounter,
> -     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> -     OUT  TPML_DIGEST               *PcrValues
> +  IN   TPML_PCR_SELECTION        *PcrSelectionIn,
> +  OUT  UINT32                    *PcrUpdateCounter,
> +  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> +  OUT  TPML_DIGEST               *PcrValues
>    );
>
>  /**
> @@ -1113,4 +1113,20 @@ GetDigestFromDigestList(
>    OUT VOID              *Digest
>    );
>
> +  /**
> +   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
> +  );
>  #endif
> diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> index ddb15178fb..3b49192b93 100644
> --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Implement TPM2 Integrity related command.
>
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
>  **/
> @@ -109,7 +109,6 @@ Tpm2PcrExtend (
>    Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
>    Cmd.PcrHandle          = SwapBytes32(PcrHandle);
>
> -
>    //
>    // Add in Auth session
>    //
> @@ -130,14 +129,26 @@ Tpm2PcrExtend (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      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;
>    }
>
> @@ -151,7 +162,7 @@ Tpm2PcrExtend (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -160,7 +171,7 @@ Tpm2PcrExtend (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -168,10 +179,15 @@ Tpm2PcrExtend (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    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
>    //
> @@ -246,7 +262,7 @@ Tpm2PcrEvent (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -255,7 +271,7 @@ Tpm2PcrEvent (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -263,7 +279,7 @@ Tpm2PcrEvent (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      return EFI_DEVICE_ERROR;
>    }
>
> @@ -284,7 +300,7 @@ Tpm2PcrEvent (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
>        return EFI_DEVICE_ERROR;
>      }
>      CopyMem(
> @@ -298,6 +314,7 @@ Tpm2PcrEvent (
>    return EFI_SUCCESS;
>  }
>
> +
>  /**
>    This command returns the values of all PCR specified in pcrSelect.
>
> @@ -353,11 +370,11 @@ Tpm2PcrRead (
>    }
>
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
>      return EFI_NOT_FOUND;
>    }
>
> @@ -369,7 +386,7 @@ Tpm2PcrRead (
>    // PcrUpdateCounter
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
> @@ -378,7 +395,7 @@ Tpm2PcrRead (
>    // PcrSelectionOut
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
> @@ -388,7 +405,7 @@ Tpm2PcrRead (
>    }
>
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count) +
> sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    for (Index = 0; Index < PcrSelectionOut->count; Index++) {
> @@ -513,7 +530,7 @@ Tpm2PcrAllocate (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand:
> Buffer Too Small\r\n"));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -523,7 +540,7 @@ Tpm2PcrAllocate (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too
> large! %d\r\n", RespSize));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -532,7 +549,7 @@ Tpm2PcrAllocate (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      Status = EFI_DEVICE_ERROR;
>      goto Done;
>    }
> @@ -673,17 +690,180 @@ Tpm2PcrAllocateBanks (
>               &SizeNeeded,
>               &SizeAvailable
>               );
> -  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
> +  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
>    if (EFI_ERROR (Status)) {
>      goto Done;
>    }
>
> -  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
> -  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
> -  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
> -  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
> +  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));
> +
> +  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
> +
> +  //
> +  // 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;
> +  }
> +
> +  for (Index = 0; Index < PcrValues.count; Index++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
> +      PcrSelectionOut.pcrSelections[Index].hash,
> +      PcrIndex
> +      ));
> +
> +    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
> +      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +
> +  if (HashList != NULL) {
> +    CopyMem (
> +      HashList,
> +      &PcrValues,
> +      sizeof (TPML_DIGEST)
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index 93a8803ff6..ea79fa0af6 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Initialize TPM2 device and measure FVs before handing off control to DXE.
>
> -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
>  Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -191,7 +191,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
>    }
>  };
>
> -
>  /**
>    Record all measured Firmware Volume Information into a Guid Hob
>    Guid Hob payload layout is
> @@ -267,7 +266,7 @@ SyncPcrAllocationsAndPcrMask (
>    UINT32                            Tpm2PcrMask;
>    UINT32                            NewTpm2PcrMask;
>
> -  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> +  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
>
>    //
>    // Determine the current TPM support and the Platform PCR mask.
> @@ -278,7 +277,7 @@ SyncPcrAllocationsAndPcrMask (
>    Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
>    if (Tpm2PcrMask == 0) {
>      //
> -    // if PcdTPm2HashMask is zero, use ActivePcr setting
> +    // if PcdTpm2HashMask is zero, use ActivePcr setting
>      //
>      PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
>      Tpm2PcrMask = TpmActivePcrBanks;
> @@ -297,9 +296,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
>      NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
>
> -    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
> +    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
>      if (NewTpmActivePcrBanks == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      } else {
>        Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap,
> NewTpmActivePcrBanks);
> @@ -307,7 +306,7 @@ SyncPcrAllocationsAndPcrMask (
>          //
>          // We can't do much here, but we hope that this doesn't happen.
>          //
> -        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
> +        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
>          ASSERT_EFI_ERROR (Status);
>        }
>        //
> @@ -324,9 +323,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
>      NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
>
> -    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
> +    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
>      if (NewTpm2PcrMask == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      }
>
> @@ -365,7 +364,7 @@ LogHashEvent (
>    RetStatus = EFI_SUCCESS;
>    for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]);
> Index++) {
>      if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
> -      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
> +      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
>        switch (mTcg2EventInfo[Index].LogFormat) {
>        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
>          Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList,
> &NewEventHdr->Digest);
> @@ -476,7 +475,7 @@ HashLogExtendEvent (
>    }
>
>    if (Status == EFI_DEVICE_ERROR) {
> -    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
> +    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n",
> Status));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> @@ -1011,7 +1010,7 @@ PeimEntryMA (
>    }
>
>    if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
>      return EFI_DEVICE_ERROR;
>    }
>
> @@ -1075,7 +1074,7 @@ PeimEntryMA (
>        for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
>          Status = MeasureSeparatorEventWithError (PcrIndex);
>          if (EFI_ERROR (Status)) {
> -          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
> +          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
>          }
>        }
>      }
> @@ -1092,6 +1091,13 @@ PeimEntryMA (
>        }
>      }
>
> +    DEBUG_CODE_BEGIN ();
> +    //
> +    // Peek into TPM PCR 00 before any BIOS measurement.
> +    //
> +    Tpm2PcrReadForActiveBank (00, NULL);
> +    DEBUG_CODE_END ();
> +
>      //
>      // Only install TpmInitializedPpi on success
>      //
> @@ -1106,7 +1112,7 @@ PeimEntryMA (
>
>  Done:
>    if (EFI_ERROR (Status)) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> --
> 2.31.1.windows.1


[-- Attachment #2: Type: text/html, Size: 46863 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
  2021-08-10  6:40   ` Rodrigo Gonzalez del Cueto
@ 2021-08-11  5:39     ` Yao, Jiewen
  0 siblings, 0 replies; 8+ messages in thread
From: Yao, Jiewen @ 2021-08-11  5:39 UTC (permalink / raw)
  To: Gonzalez Del Cueto, Rodrigo, devel@edk2.groups.io; +Cc: Wang, Jian J

[-- Attachment #1: Type: text/plain, Size: 27341 bytes --]

I am OK to add API to the library.

I am OK to add one function call to dump PCR[0] in TcgPei to show if there is any measurement before BIOS. That is good use case for BootGuard.

But I don't think we need dump the PCR every time in PCR_Extend - assuming TPM hardware is good, then it should always be correct.

Thank you
Yao Jiewen

From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>
Sent: Tuesday, August 10, 2021 2:41 PM
To: Yao, Jiewen <jiewen.yao@intel.com>; devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@intel.com>
Subject: Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.

Hi Jiewen,

The intention of such API would be to ease debugging and auditing PCR attestation along the boot; it has been a common task while debugging several issues and TPM configurations.

a) Configurations in which BIOS is not the S-CRTM and we need to attest what has been measured to the TPM prior to any measurements performed by BIOS.
b) Verifying the values in all the active and supported PCR banks: attestation or capping of the PCRs. (See BZ: 3515<https://bugzilla.tianocore.org/show_bug.cgi?id=3515>)

Such API together with the TCG event log print out it allows us to audit and debug the measured boot sequence.

Regards,
-Rodrigo
________________________________
From: Yao, Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
Sent: Sunday, August 8, 2021 6:24 PM
To: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com<mailto:rodrigo.gonzalez.del.cueto@intel.com>>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>>
Cc: Wang, Jian J <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
Subject: RE: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.

Some feedback:

1) I think it is OK to add Tpm2PcrReadForActiveBank() API.
But I feel we will add too many noise to dump Tpm2PcrReadForActiveBank() in the code everytime.
I am not sure why it is needed.
What is the problem statement?

2) Below definition does not follow EDKII coding style. Please use 2 "space" as indent.
EFI_STATUS
EFIAPI
Tpm2PcrReadForActiveBank (
 IN      TPMI_DH_PCR                PcrHandle,
 OUT     TPML_DIGEST                *HashList
)



> -----Original Message-----
> From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com<mailto:rodrigo.gonzalez.del.cueto@intel.com>>
> Sent: Friday, July 30, 2021 6:43 AM
> To: devel@edk2.groups.io<mailto:devel@edk2.groups.io>
> Cc: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com<mailto:rodrigo.gonzalez.del.cueto@intel.com>>; Yao,
> Jiewen <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>; Wang, Jian J <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> Subject: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858
>
> Add debug functionality to examine TPM extend operations
> performed by BIOS and inspect the PCR 00 value prior to
> any BIOS measurements.
>
> Replaced usage of EFI_D_* for DEBUG_* definitions in debug
> messages.
>
> Signed-off-by: Rodrigo Gonzalez del Cueto
> <rodrigo.gonzalez.del.cueto@intel.com<mailto:rodrigo.gonzalez.del.cueto@intel.com>>
> Cc: Jiewen Yao <jiewen.yao@intel.com<mailto:jiewen.yao@intel.com>>
> Cc: Jian J Wang <jian.j.wang@intel.com<mailto:jian.j.wang@intel.com>>
> ---
>  SecurityPkg/Include/Library/Tpm2CommandLib.h       |  28
> ++++++++++++++++++++++------
>  SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 226
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++-----------------------
>  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |  34 ++++++++++++++++++++------
> --------
>  3 files changed, 245 insertions(+), 43 deletions(-)
>
> diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> index ee8eb62295..5e5c340893 100644
> --- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> +++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> @@ -1,7 +1,7 @@
>  /** @file
>    This library is used by other modules to send TPM2 command.
>
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
>  **/
> @@ -505,7 +505,7 @@ EFIAPI
>  Tpm2PcrEvent (
>    IN      TPMI_DH_PCR               PcrHandle,
>    IN      TPM2B_EVENT               *EventData,
> -     OUT  TPML_DIGEST_VALUES        *Digests
> +  OUT     TPML_DIGEST_VALUES        *Digests
>    );
>
>  /**
> @@ -522,10 +522,10 @@ Tpm2PcrEvent (
>  EFI_STATUS
>  EFIAPI
>  Tpm2PcrRead (
> -  IN      TPML_PCR_SELECTION        *PcrSelectionIn,
> -     OUT  UINT32                    *PcrUpdateCounter,
> -     OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> -     OUT  TPML_DIGEST               *PcrValues
> +  IN   TPML_PCR_SELECTION        *PcrSelectionIn,
> +  OUT  UINT32                    *PcrUpdateCounter,
> +  OUT  TPML_PCR_SELECTION        *PcrSelectionOut,
> +  OUT  TPML_DIGEST               *PcrValues
>    );
>
>  /**
> @@ -1113,4 +1113,20 @@ GetDigestFromDigestList(
>    OUT VOID              *Digest
>    );
>
> +  /**
> +   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
> +  );
>  #endif
> diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> index ddb15178fb..3b49192b93 100644
> --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Implement TPM2 Integrity related command.
>
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
>  **/
> @@ -109,7 +109,6 @@ Tpm2PcrExtend (
>    Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);
>    Cmd.PcrHandle          = SwapBytes32(PcrHandle);
>
> -
>    //
>    // Add in Auth session
>    //
> @@ -130,14 +129,26 @@ Tpm2PcrExtend (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      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;
>    }
>
> @@ -151,7 +162,7 @@ Tpm2PcrExtend (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -160,7 +171,7 @@ Tpm2PcrExtend (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -168,10 +179,15 @@ Tpm2PcrExtend (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    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
>    //
> @@ -246,7 +262,7 @@ Tpm2PcrEvent (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -255,7 +271,7 @@ Tpm2PcrEvent (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n",
> RespSize));
>      return EFI_BUFFER_TOO_SMALL;
>    }
>
> @@ -263,7 +279,7 @@ Tpm2PcrEvent (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      return EFI_DEVICE_ERROR;
>    }
>
> @@ -284,7 +300,7 @@ Tpm2PcrEvent (
>      Buffer += sizeof(UINT16);
>      DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);
>      if (DigestSize == 0) {
> -      DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
> +      DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests-
> >digests[Index].hashAlg));
>        return EFI_DEVICE_ERROR;
>      }
>      CopyMem(
> @@ -298,6 +314,7 @@ Tpm2PcrEvent (
>    return EFI_SUCCESS;
>  }
>
> +
>  /**
>    This command returns the values of all PCR specified in pcrSelect.
>
> @@ -353,11 +370,11 @@ Tpm2PcrRead (
>    }
>
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n",
> SwapBytes32(RecvBuffer.Header.responseCode)));
>      return EFI_NOT_FOUND;
>    }
>
> @@ -369,7 +386,7 @@ Tpm2PcrRead (
>    // PcrUpdateCounter
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);
> @@ -378,7 +395,7 @@ Tpm2PcrRead (
>    // PcrSelectionOut
>    //
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);
> @@ -388,7 +405,7 @@ Tpm2PcrRead (
>    }
>
>    if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) +
> sizeof(RecvBuffer.PcrUpdateCounter) +
> sizeof(RecvBuffer.PcrSelectionOut.count) +
> sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n",
> RecvBufferSize));
>      return EFI_DEVICE_ERROR;
>    }
>    for (Index = 0; Index < PcrSelectionOut->count; Index++) {
> @@ -513,7 +530,7 @@ Tpm2PcrAllocate (
>    }
>
>    if (ResultBufSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer
> Too Small\r\n"));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand:
> Buffer Too Small\r\n"));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -523,7 +540,7 @@ Tpm2PcrAllocate (
>    //
>    RespSize = SwapBytes32(Res.Header.paramSize);
>    if (RespSize > sizeof(Res)) {
> -    DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n",
> RespSize));
> +    DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too
> large! %d\r\n", RespSize));
>      Status = EFI_BUFFER_TOO_SMALL;
>      goto Done;
>    }
> @@ -532,7 +549,7 @@ Tpm2PcrAllocate (
>    // Fail if command failed
>    //
>    if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
> -    DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n",
> SwapBytes32(Res.Header.responseCode)));
> +    DEBUG((DEBUG_ERROR,"Tpm2PcrAllocate: Response Code error!
> 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
>      Status = EFI_DEVICE_ERROR;
>      goto Done;
>    }
> @@ -673,17 +690,180 @@ Tpm2PcrAllocateBanks (
>               &SizeNeeded,
>               &SizeAvailable
>               );
> -  DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
> +  DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n",
> Status));
>    if (EFI_ERROR (Status)) {
>      goto Done;
>    }
>
> -  DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));
> -  DEBUG ((EFI_D_INFO, "MaxPCR            - %08x\n", MaxPCR));
> -  DEBUG ((EFI_D_INFO, "SizeNeeded        - %08x\n", SizeNeeded));
> -  DEBUG ((EFI_D_INFO, "SizeAvailable     - %08x\n", SizeAvailable));
> +  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));
> +
> +  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
> +
> +  //
> +  // 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;
> +  }
> +
> +  for (Index = 0; Index < PcrValues.count; Index++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
> +      PcrSelectionOut.pcrSelections[Index].hash,
> +      PcrIndex
> +      ));
> +
> +    for(Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
> +      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
> +    }
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +
> +  if (HashList != NULL) {
> +    CopyMem (
> +      HashList,
> +      &PcrValues,
> +      sizeof (TPML_DIGEST)
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index 93a8803ff6..ea79fa0af6 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Initialize TPM2 device and measure FVs before handing off control to DXE.
>
> -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
>  Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>
> @@ -191,7 +191,6 @@ EFI_PEI_NOTIFY_DESCRIPTOR           mNotifyList[] = {
>    }
>  };
>
> -
>  /**
>    Record all measured Firmware Volume Information into a Guid Hob
>    Guid Hob payload layout is
> @@ -267,7 +266,7 @@ SyncPcrAllocationsAndPcrMask (
>    UINT32                            Tpm2PcrMask;
>    UINT32                            NewTpm2PcrMask;
>
> -  DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
> +  DEBUG ((DEBUG_ERROR, "SyncPcrAllocationsAndPcrMask!\n"));
>
>    //
>    // Determine the current TPM support and the Platform PCR mask.
> @@ -278,7 +277,7 @@ SyncPcrAllocationsAndPcrMask (
>    Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask);
>    if (Tpm2PcrMask == 0) {
>      //
> -    // if PcdTPm2HashMask is zero, use ActivePcr setting
> +    // if PcdTpm2HashMask is zero, use ActivePcr setting
>      //
>      PcdSet32S (PcdTpm2HashMask, TpmActivePcrBanks);
>      Tpm2PcrMask = TpmActivePcrBanks;
> @@ -297,9 +296,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) {
>      NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask;
>
> -    DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
> +    DEBUG ((DEBUG_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n",
> __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks));
>      if (NewTpmActivePcrBanks == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs active! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      } else {
>        Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap,
> NewTpmActivePcrBanks);
> @@ -307,7 +306,7 @@ SyncPcrAllocationsAndPcrMask (
>          //
>          // We can't do much here, but we hope that this doesn't happen.
>          //
> -        DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
> +        DEBUG ((DEBUG_ERROR, "%a - Failed to reallocate PCRs!\n",
> __FUNCTION__));
>          ASSERT_EFI_ERROR (Status);
>        }
>        //
> @@ -324,9 +323,9 @@ SyncPcrAllocationsAndPcrMask (
>    if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) {
>      NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap;
>
> -    DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
> +    DEBUG ((DEBUG_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to
> 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask));
>      if (NewTpm2PcrMask == 0) {
> -      DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
> +      DEBUG ((DEBUG_ERROR, "%a - No viable PCRs supported! Please set a less
> restrictive value for PcdTpm2HashMask!\n", __FUNCTION__));
>        ASSERT (FALSE);
>      }
>
> @@ -365,7 +364,7 @@ LogHashEvent (
>    RetStatus = EFI_SUCCESS;
>    for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]);
> Index++) {
>      if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) {
> -      DEBUG ((EFI_D_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
> +      DEBUG ((DEBUG_INFO, "  LogFormat - 0x%08x\n",
> mTcg2EventInfo[Index].LogFormat));
>        switch (mTcg2EventInfo[Index].LogFormat) {
>        case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2:
>          Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList,
> &NewEventHdr->Digest);
> @@ -476,7 +475,7 @@ HashLogExtendEvent (
>    }
>
>    if (Status == EFI_DEVICE_ERROR) {
> -    DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
> +    DEBUG ((DEBUG_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n",
> Status));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> @@ -1011,7 +1010,7 @@ PeimEntryMA (
>    }
>
>    if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error!\n"));
>      return EFI_DEVICE_ERROR;
>    }
>
> @@ -1075,7 +1074,7 @@ PeimEntryMA (
>        for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
>          Status = MeasureSeparatorEventWithError (PcrIndex);
>          if (EFI_ERROR (Status)) {
> -          DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
> +          DEBUG ((DEBUG_ERROR, "Separator Event with Error not Measured.
> Error!\n"));
>          }
>        }
>      }
> @@ -1092,6 +1091,13 @@ PeimEntryMA (
>        }
>      }
>
> +    DEBUG_CODE_BEGIN ();
> +    //
> +    // Peek into TPM PCR 00 before any BIOS measurement.
> +    //
> +    Tpm2PcrReadForActiveBank (00, NULL);
> +    DEBUG_CODE_END ();
> +
>      //
>      // Only install TpmInitializedPpi on success
>      //
> @@ -1106,7 +1112,7 @@ PeimEntryMA (
>
>  Done:
>    if (EFI_ERROR (Status)) {
> -    DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
> +    DEBUG ((DEBUG_ERROR, "TPM2 error! Build Hob\n"));
>      BuildGuidHob (&gTpmErrorHobGuid,0);
>      REPORT_STATUS_CODE (
>        EFI_ERROR_CODE | EFI_ERROR_MINOR,
> --
> 2.31.1.windows.1

[-- Attachment #2: Type: text/html, Size: 49851 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations
@ 2021-12-17  2:47 Rodrigo Gonzalez del Cueto
  2021-12-17 15:08 ` Yao, Jiewen
  0 siblings, 1 reply; 8+ messages in thread
From: Rodrigo Gonzalez del Cueto @ 2021-12-17  2:47 UTC (permalink / raw)
  To: devel; +Cc: Rodrigo Gonzalez del Cueto, Jiewen Yao, Jian J Wang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858

In V2: Fixed patch format and uncrustify cleanup

In V1: Add debug functionality to examine TPM extend operations
performed by BIOS and inspect the PCR 00 value prior to
any BIOS measurements.

Signed-off-by: Rodrigo Gonzalez del Cueto <rodrigo.gonzalez.del.cueto@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h       |  33 +++++++++++++++++++++++++--------
 SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |   9 ++++++++-
 3 files changed, 222 insertions(+), 10 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index 2e83a2f474..a2fb97f18d 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
 /** @file
   This library is used by other modules to send TPM2 command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -503,9 +503,9 @@ Tpm2PcrExtend (
 EFI_STATUS
 EFIAPI
 Tpm2PcrEvent (
-  IN      TPMI_DH_PCR      PcrHandle,
-  IN      TPM2B_EVENT      *EventData,
-  OUT  TPML_DIGEST_VALUES  *Digests
+  IN      TPMI_DH_PCR         PcrHandle,
+  IN      TPM2B_EVENT         *EventData,
+  OUT     TPML_DIGEST_VALUES  *Digests
   );
 
 /**
@@ -522,10 +522,10 @@ Tpm2PcrEvent (
 EFI_STATUS
 EFIAPI
 Tpm2PcrRead (
-  IN      TPML_PCR_SELECTION  *PcrSelectionIn,
-  OUT  UINT32                 *PcrUpdateCounter,
-  OUT  TPML_PCR_SELECTION     *PcrSelectionOut,
-  OUT  TPML_DIGEST            *PcrValues
+  IN   TPML_PCR_SELECTION  *PcrSelectionIn,
+  OUT  UINT32              *PcrUpdateCounter,
+  OUT  TPML_PCR_SELECTION  *PcrSelectionOut,
+  OUT  TPML_DIGEST         *PcrValues
   );
 
 /**
@@ -1113,4 +1113,21 @@ GetDigestFromDigestList (
   OUT VOID               *Digest
   );
 
+/**
+   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
+  );
+
 #endif
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
index 8dde5f34a2..94e93b2642 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
@@ -1,7 +1,7 @@
 /** @file
   Implement TPM2 Integrity related command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -138,6 +138,23 @@ Tpm2PcrExtend (
       &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;
   }
 
@@ -172,6 +189,11 @@ Tpm2PcrExtend (
     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
   //
@@ -705,3 +727,169 @@ 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));
+
+  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
+
+  //
+  // 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;
+  }
+
+  for (Index = 0; Index < PcrValues.count; Index++) {
+    DEBUG ((
+      DEBUG_INFO,
+      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
+      PcrSelectionOut.pcrSelections[Index].hash,
+      PcrIndex
+      ));
+
+    for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
+      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
+    }
+
+    DEBUG ((DEBUG_INFO, "\n"));
+  }
+
+  if (HashList != NULL) {
+    CopyMem (
+      HashList,
+      &PcrValues,
+      sizeof (TPML_DIGEST)
+      );
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
index a97a4e7f2d..622989aff3 100644
--- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
+++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
@@ -1,7 +1,7 @@
 /** @file
   Initialize TPM2 device and measure FVs before handing off control to DXE.
 
-Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
 Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -1106,6 +1106,13 @@ PeimEntryMA (
       }
     }
 
+    DEBUG_CODE_BEGIN ();
+    //
+    // Peek into TPM PCR 00 before any BIOS measurement.
+    //
+    Tpm2PcrReadForActiveBank (00, NULL);
+    DEBUG_CODE_END ();
+
     //
     // Only install TpmInitializedPpi on success
     //
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations
  2021-12-17  2:47 Rodrigo Gonzalez del Cueto
@ 2021-12-17 15:08 ` Yao, Jiewen
  0 siblings, 0 replies; 8+ messages in thread
From: Yao, Jiewen @ 2021-12-17 15:08 UTC (permalink / raw)
  To: Gonzalez Del Cueto, Rodrigo, devel@edk2.groups.io; +Cc: Wang, Jian J

Pushed: 8ed8568922be9b5f7111fc1297317106aba7ab52

> -----Original Message-----
> From: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>
> Sent: Friday, December 17, 2021 10:47 AM
> To: devel@edk2.groups.io
> Cc: Gonzalez Del Cueto, Rodrigo <rodrigo.gonzalez.del.cueto@intel.com>; Yao,
> Jiewen <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>
> Subject: [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2858
> 
> In V2: Fixed patch format and uncrustify cleanup
> 
> In V1: Add debug functionality to examine TPM extend operations
> performed by BIOS and inspect the PCR 00 value prior to
> any BIOS measurements.
> 
> Signed-off-by: Rodrigo Gonzalez del Cueto
> <rodrigo.gonzalez.del.cueto@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> ---
>  SecurityPkg/Include/Library/Tpm2CommandLib.h       |  33
> +++++++++++++++++++++++++--------
>  SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c | 190
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c                  |   9 ++++++++-
>  3 files changed, 222 insertions(+), 10 deletions(-)
> 
> diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> index 2e83a2f474..a2fb97f18d 100644
> --- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
> +++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
> @@ -1,7 +1,7 @@
>  /** @file
>    This library is used by other modules to send TPM2 command.
> 
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -503,9 +503,9 @@ Tpm2PcrExtend (
>  EFI_STATUS
>  EFIAPI
>  Tpm2PcrEvent (
> -  IN      TPMI_DH_PCR      PcrHandle,
> -  IN      TPM2B_EVENT      *EventData,
> -  OUT  TPML_DIGEST_VALUES  *Digests
> +  IN      TPMI_DH_PCR         PcrHandle,
> +  IN      TPM2B_EVENT         *EventData,
> +  OUT     TPML_DIGEST_VALUES  *Digests
>    );
> 
>  /**
> @@ -522,10 +522,10 @@ Tpm2PcrEvent (
>  EFI_STATUS
>  EFIAPI
>  Tpm2PcrRead (
> -  IN      TPML_PCR_SELECTION  *PcrSelectionIn,
> -  OUT  UINT32                 *PcrUpdateCounter,
> -  OUT  TPML_PCR_SELECTION     *PcrSelectionOut,
> -  OUT  TPML_DIGEST            *PcrValues
> +  IN   TPML_PCR_SELECTION  *PcrSelectionIn,
> +  OUT  UINT32              *PcrUpdateCounter,
> +  OUT  TPML_PCR_SELECTION  *PcrSelectionOut,
> +  OUT  TPML_DIGEST         *PcrValues
>    );
> 
>  /**
> @@ -1113,4 +1113,21 @@ GetDigestFromDigestList (
>    OUT VOID               *Digest
>    );
> 
> +/**
> +   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
> +  );
> +
>  #endif
> diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> index 8dde5f34a2..94e93b2642 100644
> --- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> +++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Implement TPM2 Integrity related command.
> 
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
> +Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -138,6 +138,23 @@ Tpm2PcrExtend (
>        &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;
>    }
> 
> @@ -172,6 +189,11 @@ Tpm2PcrExtend (
>      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
>    //
> @@ -705,3 +727,169 @@ 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));
> +
> +  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));
> +
> +  //
> +  // 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;
> +  }
> +
> +  for (Index = 0; Index < PcrValues.count; Index++) {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
> +      PcrSelectionOut.pcrSelections[Index].hash,
> +      PcrIndex
> +      ));
> +
> +    for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {
> +      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));
> +    }
> +
> +    DEBUG ((DEBUG_INFO, "\n"));
> +  }
> +
> +  if (HashList != NULL) {
> +    CopyMem (
> +      HashList,
> +      &PcrValues,
> +      sizeof (TPML_DIGEST)
> +      );
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> index a97a4e7f2d..622989aff3 100644
> --- a/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> +++ b/SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c
> @@ -1,7 +1,7 @@
>  /** @file
>    Initialize TPM2 device and measure FVs before handing off control to DXE.
> 
> -Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
>  Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> @@ -1106,6 +1106,13 @@ PeimEntryMA (
>        }
>      }
> 
> +    DEBUG_CODE_BEGIN ();
> +    //
> +    // Peek into TPM PCR 00 before any BIOS measurement.
> +    //
> +    Tpm2PcrReadForActiveBank (00, NULL);
> +    DEBUG_CODE_END ();
> +
>      //
>      // Only install TpmInitializedPpi on success
>      //
> --
> 2.26.2.windows.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-12-17 15:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-20 22:28 [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations Rodrigo Gonzalez del Cueto
2020-07-23  2:06 ` Yao, Jiewen
  -- strict thread matches above, loose matches on Subject: below --
2021-07-29 22:43 Rodrigo Gonzalez del Cueto
2021-08-09  1:24 ` Yao, Jiewen
2021-08-10  6:40   ` Rodrigo Gonzalez del Cueto
2021-08-11  5:39     ` Yao, Jiewen
2021-12-17  2:47 Rodrigo Gonzalez del Cueto
2021-12-17 15:08 ` Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox