[edk2-devel] [PATCH] SecurityPkg: Debug code to audit BIOS TPM extend operations

Rodrigo Gonzalez del Cueto rodrigo.gonzalez.del.cueto at intel.com
Fri Dec 17 02:47:07 UTC 2021


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 at intel.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
Cc: Jian J Wang <jian.j.wang at 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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85038): https://edk2.groups.io/g/devel/message/85038
Mute This Topic: https://groups.io/mt/87782211/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list