123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /** @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/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.
- //
- 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 / sizeof (Seed);
- 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, sizeof (Seed));
- BlockCount--;
- Ptr = Ptr + sizeof (Seed);
- }
- //
- // Populate the remained data as request.
- //
- Status = GetRandomNumber128 (Seed);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- CopyMem (Ptr, Seed, (Length % sizeof (Seed)));
- 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;
- TPM2B_AUTH NewPlatformAuth;
- //
- // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
- //
- GetAuthSize (&AuthSize);
- NewPlatformAuth.size = AuthSize;
- //
- // Create the random bytes in the destination buffer
- //
- RdRandGenerateEntropy (NewPlatformAuth.size, NewPlatformAuth.buffer);
- //
- // 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);
- }
- /**
- 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 ();
- }
- }
|