]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg: Debug code to audit BIOS TPM extend operations
authorRodrigo Gonzalez del Cueto <rodrigo.gonzalez.del.cueto@intel.com>
Fri, 17 Dec 2021 02:47:07 +0000 (10:47 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 17 Dec 2021 15:03:43 +0000 (15:03 +0000)
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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
SecurityPkg/Include/Library/Tpm2CommandLib.h
SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.c

index 2e83a2f4743cc7436360e774c4095f5694142486..a2fb97f18dfe6e99e427021a542d3a0399cbed79 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This library is used by other modules to send TPM2 command.\r
 \r
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -503,9 +503,9 @@ Tpm2PcrExtend (
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrEvent (\r
-  IN      TPMI_DH_PCR      PcrHandle,\r
-  IN      TPM2B_EVENT      *EventData,\r
-  OUT  TPML_DIGEST_VALUES  *Digests\r
+  IN      TPMI_DH_PCR         PcrHandle,\r
+  IN      TPM2B_EVENT         *EventData,\r
+  OUT     TPML_DIGEST_VALUES  *Digests\r
   );\r
 \r
 /**\r
@@ -522,10 +522,10 @@ Tpm2PcrEvent (
 EFI_STATUS\r
 EFIAPI\r
 Tpm2PcrRead (\r
-  IN      TPML_PCR_SELECTION  *PcrSelectionIn,\r
-  OUT  UINT32                 *PcrUpdateCounter,\r
-  OUT  TPML_PCR_SELECTION     *PcrSelectionOut,\r
-  OUT  TPML_DIGEST            *PcrValues\r
+  IN   TPML_PCR_SELECTION  *PcrSelectionIn,\r
+  OUT  UINT32              *PcrUpdateCounter,\r
+  OUT  TPML_PCR_SELECTION  *PcrSelectionOut,\r
+  OUT  TPML_DIGEST         *PcrValues\r
   );\r
 \r
 /**\r
@@ -1113,4 +1113,21 @@ GetDigestFromDigestList (
   OUT VOID               *Digest\r
   );\r
 \r
+/**\r
+   This function will query the TPM to determine which hashing algorithms and\r
+   get the digests of all active and supported PCR banks of a specific PCR register.\r
+\r
+   @param[in]     PcrHandle     The index of the PCR register to be read.\r
+   @param[out]    HashList      List of digests from PCR register being read.\r
+\r
+   @retval EFI_SUCCESS           The Pcr was read successfully.\r
+   @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrReadForActiveBank (\r
+  IN      TPMI_DH_PCR  PcrHandle,\r
+  OUT     TPML_DIGEST  *HashList\r
+  );\r
+\r
 #endif\r
index 8dde5f34a27338fa6245f09d4f7799a237c5f4a3..94e93b26428fa35073b10699c63c21940511adfc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implement TPM2 Integrity related command.\r
 \r
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -138,6 +138,23 @@ Tpm2PcrExtend (
       &Digests->digests[Index].digest,\r
       DigestSize\r
       );\r
+\r
+    DEBUG_CODE_BEGIN ();\r
+    UINTN  Index2;\r
+    DEBUG ((\r
+      DEBUG_VERBOSE,\r
+      "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",\r
+      Digests->digests[Index].hashAlg,\r
+      (UINT8)PcrHandle\r
+      ));\r
+\r
+    for (Index2 = 0; Index2 < DigestSize; Index2++) {\r
+      DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));\r
+    }\r
+\r
+    DEBUG ((DEBUG_VERBOSE, "\n"));\r
+    DEBUG_CODE_END ();\r
+\r
     Buffer += DigestSize;\r
   }\r
 \r
@@ -172,6 +189,11 @@ Tpm2PcrExtend (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  DEBUG_CODE_BEGIN ();\r
+  DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));\r
+  Tpm2PcrReadForActiveBank (PcrHandle, NULL);\r
+  DEBUG_CODE_END ();\r
+\r
   //\r
   // Unmarshal the response\r
   //\r
@@ -705,3 +727,169 @@ Done:
   ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));\r
   return Status;\r
 }\r
+\r
+/**\r
+   This function will query the TPM to determine which hashing algorithms and\r
+   get the digests of all active and supported PCR banks of a specific PCR register.\r
+\r
+   @param[in]     PcrHandle     The index of the PCR register to be read.\r
+   @param[out]    HashList      List of digests from PCR register being read.\r
+\r
+   @retval EFI_SUCCESS           The Pcr was read successfully.\r
+   @retval EFI_DEVICE_ERROR      The command was unsuccessful.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm2PcrReadForActiveBank (\r
+  IN      TPMI_DH_PCR  PcrHandle,\r
+  OUT     TPML_DIGEST  *HashList\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  TPML_PCR_SELECTION  Pcrs;\r
+  TPML_PCR_SELECTION  PcrSelectionIn;\r
+  TPML_PCR_SELECTION  PcrSelectionOut;\r
+  TPML_DIGEST         PcrValues;\r
+  UINT32              PcrUpdateCounter;\r
+  UINT8               PcrIndex;\r
+  UINT32              TpmHashAlgorithmBitmap;\r
+  TPMI_ALG_HASH       CurrentPcrBankHash;\r
+  UINT32              ActivePcrBanks;\r
+  UINT32              TcgRegistryHashAlg;\r
+  UINTN               Index;\r
+  UINTN               Index2;\r
+\r
+  PcrIndex = (UINT8)PcrHandle;\r
+\r
+  if ((PcrIndex < 0) ||\r
+      (PcrIndex >= IMPLEMENTATION_PCR))\r
+  {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));\r
+  ZeroMem (&PcrUpdateCounter, sizeof (UINT32));\r
+  ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));\r
+  ZeroMem (&PcrValues, sizeof (PcrValues));\r
+  ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));\r
+\r
+  DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));\r
+\r
+  //\r
+  // Read TPM capabilities\r
+  //\r
+  Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Get Active Pcrs\r
+  //\r
+  Status = Tpm2GetCapabilitySupportedAndActivePcrs (\r
+             &TpmHashAlgorithmBitmap,\r
+             &ActivePcrBanks\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Select from Active PCRs\r
+  //\r
+  for (Index = 0; Index < Pcrs.count; Index++) {\r
+    CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;\r
+\r
+    switch (CurrentPcrBankHash) {\r
+      case TPM_ALG_SHA1:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA1;\r
+        break;\r
+      case TPM_ALG_SHA256:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA256;\r
+        break;\r
+      case TPM_ALG_SHA384:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA384;\r
+        break;\r
+      case TPM_ALG_SHA512:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SHA512;\r
+        break;\r
+      case TPM_ALG_SM3_256:\r
+        DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));\r
+        TcgRegistryHashAlg = HASH_ALG_SM3_256;\r
+        break;\r
+      default:\r
+        //\r
+        // Unsupported algorithm\r
+        //\r
+        DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));\r
+        TcgRegistryHashAlg = 0;\r
+        break;\r
+    }\r
+\r
+    //\r
+    // Skip unsupported and inactive PCR banks\r
+    //\r
+    if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {\r
+      DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Select PCR from current active bank\r
+    //\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash         = Pcrs.pcrSelections[Index].hash;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;\r
+    PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;\r
+    PcrSelectionIn.count++;\r
+  }\r
+\r
+  //\r
+  // Read PCRs\r
+  //\r
+  Status = Tpm2PcrRead (\r
+             &PcrSelectionIn,\r
+             &PcrUpdateCounter,\r
+             &PcrSelectionOut,\r
+             &PcrValues\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  for (Index = 0; Index < PcrValues.count; Index++) {\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",\r
+      PcrSelectionOut.pcrSelections[Index].hash,\r
+      PcrIndex\r
+      ));\r
+\r
+    for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {\r
+      DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));\r
+    }\r
+\r
+    DEBUG ((DEBUG_INFO, "\n"));\r
+  }\r
+\r
+  if (HashList != NULL) {\r
+    CopyMem (\r
+      HashList,\r
+      &PcrValues,\r
+      sizeof (TPML_DIGEST)\r
+      );\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
index a97a4e7f2d7a40e971bcff7ae3a438d277a0fe18..622989aff34f1798adddb7b84eed9bd2edb9ec69 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Initialize TPM2 device and measure FVs before handing off control to DXE.\r
 \r
-Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>\r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
@@ -1106,6 +1106,13 @@ PeimEntryMA (
       }\r
     }\r
 \r
+    DEBUG_CODE_BEGIN ();\r
+    //\r
+    // Peek into TPM PCR 00 before any BIOS measurement.\r
+    //\r
+    Tpm2PcrReadForActiveBank (00, NULL);\r
+    DEBUG_CODE_END ();\r
+\r
     //\r
     // Only install TpmInitializedPpi on success\r
     //\r