2 TPM Platform Hierarchy configuration library.
4 This library provides functions for customizing the TPM's Platform Hierarchy
5 Authorization Value (platformAuth) and Platform Hierarchy Authorization
6 Policy (platformPolicy) can be defined through this function.
8 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
9 Copyright (c) Microsoft Corporation.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
12 @par Specification Reference:
13 https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance/
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/RngLib.h>
22 #include <Library/Tpm2CommandLib.h>
23 #include <Library/Tpm2DeviceLib.h>
26 // The authorization value may be no larger than the digest produced by the hash
27 // algorithm used for context integrity.
33 Generate high-quality entropy source through RDRAND.
35 @param[in] Length Size of the buffer, in bytes, to fill with.
36 @param[out] Entropy Pointer to the buffer to store the entropy data.
38 @retval EFI_SUCCESS Entropy generation succeeded.
39 @retval EFI_NOT_READY Failed to request random data.
44 RdRandGenerateEntropy (
54 Status
= EFI_NOT_READY
;
55 BlockCount
= Length
/ sizeof(Seed
);
56 Ptr
= (UINT8
*)Entropy
;
59 // Generate high-quality seed for DRBG Entropy
61 while (BlockCount
> 0) {
62 Status
= GetRandomNumber128 (Seed
);
63 if (EFI_ERROR (Status
)) {
66 CopyMem (Ptr
, Seed
, sizeof(Seed
));
69 Ptr
= Ptr
+ sizeof(Seed
);
73 // Populate the remained data as request.
75 Status
= GetRandomNumber128 (Seed
);
76 if (EFI_ERROR (Status
)) {
79 CopyMem (Ptr
, Seed
, (Length
% sizeof(Seed
)));
85 This function returns the maximum size of TPM2B_AUTH; this structure is used for an authorization value
86 and limits an authValue to being no larger than the largest digest produced by a TPM.
88 @param[out] AuthSize Tpm2 Auth size
90 @retval EFI_SUCCESS Auth size returned.
91 @retval EFI_DEVICE_ERROR Can not return platform auth due to device error.
101 TPML_PCR_SELECTION Pcrs
;
105 Status
= EFI_SUCCESS
;
107 while (mAuthSize
== 0) {
109 mAuthSize
= SHA1_DIGEST_SIZE
;
110 ZeroMem (&Pcrs
, sizeof (TPML_PCR_SELECTION
));
111 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
113 if (EFI_ERROR (Status
)) {
114 DEBUG ((DEBUG_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
118 DEBUG ((DEBUG_ERROR
, "Tpm2GetCapabilityPcrs - %08x\n", Pcrs
.count
));
120 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
121 DEBUG ((DEBUG_ERROR
, "alg - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
123 switch (Pcrs
.pcrSelections
[Index
].hash
) {
125 DigestSize
= SHA1_DIGEST_SIZE
;
128 DigestSize
= SHA256_DIGEST_SIZE
;
131 DigestSize
= SHA384_DIGEST_SIZE
;
134 DigestSize
= SHA512_DIGEST_SIZE
;
136 case TPM_ALG_SM3_256
:
137 DigestSize
= SM3_256_DIGEST_SIZE
;
140 DigestSize
= SHA1_DIGEST_SIZE
;
144 if (DigestSize
> mAuthSize
) {
145 mAuthSize
= DigestSize
;
151 *AuthSize
= mAuthSize
;
156 Set PlatformAuth to random value.
159 RandomizePlatformAuth (
165 TPM2B_AUTH NewPlatformAuth
;
168 // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
171 GetAuthSize (&AuthSize
);
173 NewPlatformAuth
.size
= AuthSize
;
176 // Create the random bytes in the destination buffer
179 RdRandGenerateEntropy (NewPlatformAuth
.size
, NewPlatformAuth
.buffer
);
182 // Send Tpm2HierarchyChangeAuth command with the new Auth value
184 Status
= Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM
, NULL
, &NewPlatformAuth
);
185 DEBUG ((DEBUG_INFO
, "Tpm2HierarchyChangeAuth Result: - %r\n", Status
));
186 ZeroMem (NewPlatformAuth
.buffer
, AuthSize
);
190 Disable the TPM platform hierarchy.
192 @retval EFI_SUCCESS The TPM was disabled successfully.
193 @retval Others An error occurred attempting to disable the TPM platform hierarchy.
197 DisableTpmPlatformHierarchy (
203 // Make sure that we have use of the TPM.
204 Status
= Tpm2RequestUseTpm ();
205 if (EFI_ERROR (Status
)) {
206 DEBUG ((DEBUG_ERROR
, "%a:%a() - Tpm2RequestUseTpm Failed! %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
207 ASSERT_EFI_ERROR (Status
);
211 // Let's do what we can to shut down the hierarchies.
213 // Disable the PH NV.
214 // IMPORTANT NOTE: We *should* be able to disable the PH NV here, but TPM parts have
215 // been known to store the EK cert in the PH NV. If we disable it, the
216 // EK cert will be unreadable.
219 Status
= Tpm2HierarchyControl (
220 TPM_RH_PLATFORM
, // AuthHandle
222 TPM_RH_PLATFORM
, // Hierarchy
225 DEBUG ((DEBUG_VERBOSE
, "%a:%a() - Disable PH = %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
226 if (EFI_ERROR (Status
)) {
227 DEBUG ((DEBUG_ERROR
, "%a:%a() - Disable PH Failed! %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
228 ASSERT_EFI_ERROR (Status
);
235 This service defines the configuration of the Platform Hierarchy Authorization Value (platformAuth)
236 and Platform Hierarchy Authorization Policy (platformPolicy).
241 ConfigureTpmPlatformHierarchy (
244 if (PcdGetBool (PcdRandomizePlatformHierarchy
)) {
246 // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
248 RandomizePlatformAuth ();
251 // Disable the hierarchy entirely (do not randomize it)
253 DisableTpmPlatformHierarchy ();