public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: devel@edk2.groups.io
Cc: mhaeuser@posteo.de, spbrogan@outlook.com,
	marcandre.lureau@redhat.com, kraxel@redhat.com,
	jiewen.yao@intel.com, Stefan Berger <stefanb@linux.vnet.ibm.com>,
	Stefan Berger <stefanb@linux.ibm.com>
Subject: [PATCH v5 1/8] SecurityPkg/TPM: Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms
Date: Wed,  1 Sep 2021 16:12:31 -0400	[thread overview]
Message-ID: <20210901201238.3152761-2-stefanb@linux.vnet.ibm.com> (raw)
In-Reply-To: <20210901201238.3152761-1-stefanb@linux.vnet.ibm.com>

Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 .../Include/Library/TpmPlatformHierarchyLib.h |  27 ++
 .../PeiDxeTpmPlatformHierarchyLib.c           | 266 ++++++++++++++++++
 .../PeiDxeTpmPlatformHierarchyLib.inf         |  45 +++
 3 files changed, 338 insertions(+)
 create mode 100644 SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h
 create mode 100644 SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c
 create mode 100644 SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf

diff --git a/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h
new file mode 100644
index 0000000000..a872fa09dc
--- /dev/null
+++ b/SecurityPkg/Include/Library/TpmPlatformHierarchyLib.h
@@ -0,0 +1,27 @@
+/** @file
+    TPM Platform Hierarchy configuration library.
+
+    This library provides functions for customizing the TPM's Platform Hierarchy
+    Authorization Value (platformAuth) and Platform Hierarchy Authorization
+    Policy (platformPolicy) can be defined through this function.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _TPM_PLATFORM_HIERARCHY_LIB_H_
+#define _TPM_PLATFORM_HIERARCHY_LIB_H_
+
+/**
+   This service will perform the TPM Platform Hierarchy configuration at the SmmReadyToLock event.
+
+**/
+VOID
+EFIAPI
+ConfigureTpmPlatformHierarchy (
+  VOID
+  );
+
+#endif
diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c
new file mode 100644
index 0000000000..9812ab99ab
--- /dev/null
+++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.c
@@ -0,0 +1,266 @@
+/** @file
+    TPM Platform Hierarchy configuration library.
+
+    This library provides functions for customizing the TPM's Platform Hierarchy
+    Authorization Value (platformAuth) and Platform Hierarchy Authorization
+    Policy (platformPolicy) can be defined through this function.
+
+    Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+    Copyright (c) Microsoft Corporation.<BR>
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+    @par Specification Reference:
+    https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance/
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/RngLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+
+//
+// The authorization value may be no larger than the digest produced by the hash
+//   algorithm used for context integrity.
+//
+#define      MAX_NEW_AUTHORIZATION_SIZE SHA512_DIGEST_SIZE
+
+UINT16       mAuthSize;
+
+/**
+  Generate high-quality entropy source through RDRAND.
+
+  @param[in]   Length        Size of the buffer, in bytes, to fill with.
+  @param[out]  Entropy       Pointer to the buffer to store the entropy data.
+
+  @retval EFI_SUCCESS        Entropy generation succeeded.
+  @retval EFI_NOT_READY      Failed to request random data.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGenerateEntropy (
+  IN UINTN         Length,
+  OUT UINT8        *Entropy
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       BlockCount;
+  UINT64      Seed[2];
+  UINT8       *Ptr;
+
+  Status = EFI_NOT_READY;
+  BlockCount = Length / 64;
+  Ptr = (UINT8 *)Entropy;
+
+  //
+  // Generate high-quality seed for DRBG Entropy
+  //
+  while (BlockCount > 0) {
+    Status = GetRandomNumber128 (Seed);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    CopyMem (Ptr, Seed, 64);
+
+    BlockCount--;
+    Ptr = Ptr + 64;
+  }
+
+  //
+  // Populate the remained data as request.
+  //
+  Status = GetRandomNumber128 (Seed);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  CopyMem (Ptr, Seed, (Length % 64));
+
+  return Status;
+}
+
+/**
+  This function returns the maximum size of TPM2B_AUTH; this structure is used for an authorization value
+  and limits an authValue to being no larger than the largest digest produced by a TPM.
+
+  @param[out] AuthSize                 Tpm2 Auth size
+
+  @retval EFI_SUCCESS                  Auth size returned.
+  @retval EFI_DEVICE_ERROR             Can not return platform auth due to device error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAuthSize (
+  OUT UINT16            *AuthSize
+  )
+{
+  EFI_STATUS            Status;
+  TPML_PCR_SELECTION    Pcrs;
+  UINTN                 Index;
+  UINT16                DigestSize;
+
+  Status = EFI_SUCCESS;
+
+  while (mAuthSize == 0) {
+
+    mAuthSize = SHA1_DIGEST_SIZE;
+    ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));
+    Status = Tpm2GetCapabilityPcrs (&Pcrs);
+
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));
+      break;
+    }
+
+    DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - %08x\n", Pcrs.count));
+
+    for (Index = 0; Index < Pcrs.count; Index++) {
+      DEBUG ((DEBUG_ERROR, "alg - %x\n", Pcrs.pcrSelections[Index].hash));
+
+      switch (Pcrs.pcrSelections[Index].hash) {
+      case TPM_ALG_SHA1:
+        DigestSize = SHA1_DIGEST_SIZE;
+        break;
+      case TPM_ALG_SHA256:
+        DigestSize = SHA256_DIGEST_SIZE;
+        break;
+      case TPM_ALG_SHA384:
+        DigestSize = SHA384_DIGEST_SIZE;
+        break;
+      case TPM_ALG_SHA512:
+        DigestSize = SHA512_DIGEST_SIZE;
+        break;
+      case TPM_ALG_SM3_256:
+        DigestSize = SM3_256_DIGEST_SIZE;
+        break;
+      default:
+        DigestSize = SHA1_DIGEST_SIZE;
+        break;
+      }
+
+      if (DigestSize > mAuthSize) {
+        mAuthSize = DigestSize;
+      }
+    }
+    break;
+  }
+
+  *AuthSize = mAuthSize;
+  return Status;
+}
+
+/**
+  Set PlatformAuth to random value.
+**/
+VOID
+RandomizePlatformAuth (
+  VOID
+  )
+{
+  EFI_STATUS                        Status;
+  UINT16                            AuthSize;
+  UINT8                             *Rand;
+  UINTN                             RandSize;
+  TPM2B_AUTH                        NewPlatformAuth;
+
+  //
+  // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
+  //
+
+  GetAuthSize (&AuthSize);
+
+  ZeroMem (NewPlatformAuth.buffer, AuthSize);
+  NewPlatformAuth.size = AuthSize;
+
+  //
+  // Allocate one buffer to store random data.
+  //
+  RandSize = MAX_NEW_AUTHORIZATION_SIZE;
+  Rand = AllocatePool (RandSize);
+
+  RdRandGenerateEntropy (RandSize, Rand);
+  CopyMem (NewPlatformAuth.buffer, Rand, AuthSize);
+
+  FreePool (Rand);
+
+  //
+  // Send Tpm2HierarchyChangeAuth command with the new Auth value
+  //
+  Status = Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM, NULL, &NewPlatformAuth);
+  DEBUG ((DEBUG_INFO, "Tpm2HierarchyChangeAuth Result: - %r\n", Status));
+  ZeroMem (NewPlatformAuth.buffer, AuthSize);
+  ZeroMem (Rand, RandSize);
+}
+
+/**
+  Disable the TPM platform hierarchy.
+
+  @retval   EFI_SUCCESS       The TPM was disabled successfully.
+  @retval   Others            An error occurred attempting to disable the TPM platform hierarchy.
+
+**/
+EFI_STATUS
+DisableTpmPlatformHierarchy (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  // Make sure that we have use of the TPM.
+  Status = Tpm2RequestUseTpm ();
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a:%a() - Tpm2RequestUseTpm Failed! %r\n", gEfiCallerBaseName, __FUNCTION__, Status));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // Let's do what we can to shut down the hierarchies.
+
+  // Disable the PH NV.
+  // IMPORTANT NOTE: We *should* be able to disable the PH NV here, but TPM parts have
+  //                 been known to store the EK cert in the PH NV. If we disable it, the
+  //                 EK cert will be unreadable.
+
+  // Disable the PH.
+  Status =  Tpm2HierarchyControl (
+              TPM_RH_PLATFORM,     // AuthHandle
+              NULL,                // AuthSession
+              TPM_RH_PLATFORM,     // Hierarchy
+              NO                   // State
+              );
+  DEBUG ((DEBUG_VERBOSE, "%a:%a() -  Disable PH = %r\n", gEfiCallerBaseName, __FUNCTION__, Status));
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a:%a() -  Disable PH Failed! %r\n", gEfiCallerBaseName, __FUNCTION__, Status));
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+/**
+   This service defines the configuration of the Platform Hierarchy Authorization Value (platformAuth)
+   and Platform Hierarchy Authorization Policy (platformPolicy)
+
+**/
+VOID
+EFIAPI
+ConfigureTpmPlatformHierarchy (
+  )
+{
+  if (PcdGetBool (PcdRandomizePlatformHierarchy)) {
+    //
+    // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
+    //
+    RandomizePlatformAuth ();
+  } else {
+    //
+    // Disable the hierarchy entirely (do not randomize it)
+    //
+    DisableTpmPlatformHierarchy ();
+  }
+}
diff --git a/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
new file mode 100644
index 0000000000..b7a7fb0a08
--- /dev/null
+++ b/SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
@@ -0,0 +1,45 @@
+### @file
+#
+#   TPM Platform Hierarchy configuration library.
+#
+#   This library provides functions for customizing the TPM's Platform Hierarchy
+#   Authorization Value (platformAuth) and Platform Hierarchy Authorization
+#   Policy (platformPolicy) can be defined through this function.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiDxeTpmPlatformHierarchyLib
+  FILE_GUID                      = 7794F92C-4E8E-4E57-9E4A-49A0764C7D73
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TpmPlatformHierarchyLib|PEIM DXE_DRIVER
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PcdLib
+  RngLib
+  Tpm2CommandLib
+  Tpm2DeviceLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[Sources]
+  PeiDxeTpmPlatformHierarchyLib.c
+
+[Pcd]
+  gMinPlatformPkgTokenSpaceGuid.PcdRandomizePlatformHierarchy
-- 
2.31.1


  reply	other threads:[~2021-09-01 20:12 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-01 20:12 [PATCH v5 0/8] Ovmf: Disable the TPM2 platform hierarchy Stefan Berger
2021-09-01 20:12 ` Stefan Berger [this message]
2021-09-01 20:12 ` [PATCH v5 2/8] SecurityPkg/TPM: Fix bugs in imported PeiDxeTpmPlatformHierarchyLib Stefan Berger
2021-09-01 20:12 ` [PATCH v5 3/8] SecurityPkg/TPM: Add a NULL implementation of TpmPlatformHierarchyLib Stefan Berger
2021-09-01 20:12 ` [PATCH v5 4/8] SecurityPkg: Introduce new PCD PcdRandomizePlatformHierarchy Stefan Berger
2021-09-01 20:12 ` [PATCH v5 5/8] OvmfPkg: Reference new TPM classes in the build system for compilation Stefan Berger
2021-09-01 20:12 ` [PATCH v5 6/8] OvmfPkg: Disable the TPM2 platform hierarchy Stefan Berger
2021-09-01 20:12 ` [PATCH v5 7/8] ArmVirtPkg: Reference new TPM classes in the build system for compilation Stefan Berger
2021-09-01 20:12 ` [PATCH v5 8/8] ArmVirtPkg: Disable the TPM2 platform hierarchy Stefan Berger
  -- strict thread matches above, loose matches on Subject: below --
2021-09-01 21:18 [PATCH v5 0/8] Ovmf: " Stefan Berger
2021-09-01 21:18 ` [PATCH v5 1/8] SecurityPkg/TPM: Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms Stefan Berger
2021-09-01 21:21 [PATCH v5 0/8] Ovmf: Disable the TPM2 platform hierarchy Stefan Berger
2021-09-01 21:21 ` [PATCH v5 1/8] SecurityPkg/TPM: Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms Stefan Berger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210901201238.3152761-2-stefanb@linux.vnet.ibm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox