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
)) {
67 CopyMem (Ptr
, Seed
, sizeof (Seed
));
70 Ptr
= Ptr
+ sizeof (Seed
);
74 // Populate the remained data as request.
76 Status
= GetRandomNumber128 (Seed
);
77 if (EFI_ERROR (Status
)) {
81 CopyMem (Ptr
, Seed
, (Length
% sizeof (Seed
)));
87 This function returns the maximum size of TPM2B_AUTH; this structure is used for an authorization value
88 and limits an authValue to being no larger than the largest digest produced by a TPM.
90 @param[out] AuthSize Tpm2 Auth size
92 @retval EFI_SUCCESS Auth size returned.
93 @retval EFI_DEVICE_ERROR Can not return platform auth due to device error.
103 TPML_PCR_SELECTION Pcrs
;
107 Status
= EFI_SUCCESS
;
109 while (mAuthSize
== 0) {
110 mAuthSize
= SHA1_DIGEST_SIZE
;
111 ZeroMem (&Pcrs
, sizeof (TPML_PCR_SELECTION
));
112 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
114 if (EFI_ERROR (Status
)) {
115 DEBUG ((DEBUG_ERROR
, "Tpm2GetCapabilityPcrs fail!\n"));
119 DEBUG ((DEBUG_ERROR
, "Tpm2GetCapabilityPcrs - %08x\n", Pcrs
.count
));
121 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
122 DEBUG ((DEBUG_ERROR
, "alg - %x\n", Pcrs
.pcrSelections
[Index
].hash
));
124 switch (Pcrs
.pcrSelections
[Index
].hash
) {
126 DigestSize
= SHA1_DIGEST_SIZE
;
129 DigestSize
= SHA256_DIGEST_SIZE
;
132 DigestSize
= SHA384_DIGEST_SIZE
;
135 DigestSize
= SHA512_DIGEST_SIZE
;
137 case TPM_ALG_SM3_256
:
138 DigestSize
= SM3_256_DIGEST_SIZE
;
141 DigestSize
= SHA1_DIGEST_SIZE
;
145 if (DigestSize
> mAuthSize
) {
146 mAuthSize
= DigestSize
;
153 *AuthSize
= mAuthSize
;
158 Set PlatformAuth to random value.
161 RandomizePlatformAuth (
167 TPM2B_AUTH NewPlatformAuth
;
170 // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
173 GetAuthSize (&AuthSize
);
175 NewPlatformAuth
.size
= AuthSize
;
178 // Create the random bytes in the destination buffer
181 RdRandGenerateEntropy (NewPlatformAuth
.size
, NewPlatformAuth
.buffer
);
184 // Send Tpm2HierarchyChangeAuth command with the new Auth value
186 Status
= Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM
, NULL
, &NewPlatformAuth
);
187 DEBUG ((DEBUG_INFO
, "Tpm2HierarchyChangeAuth Result: - %r\n", Status
));
188 ZeroMem (NewPlatformAuth
.buffer
, AuthSize
);
192 Disable the TPM platform hierarchy.
194 @retval EFI_SUCCESS The TPM was disabled successfully.
195 @retval Others An error occurred attempting to disable the TPM platform hierarchy.
199 DisableTpmPlatformHierarchy (
205 // Make sure that we have use of the TPM.
206 Status
= Tpm2RequestUseTpm ();
207 if (EFI_ERROR (Status
)) {
208 DEBUG ((DEBUG_ERROR
, "%a:%a() - Tpm2RequestUseTpm Failed! %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
209 ASSERT_EFI_ERROR (Status
);
213 // Let's do what we can to shut down the hierarchies.
215 // Disable the PH NV.
216 // IMPORTANT NOTE: We *should* be able to disable the PH NV here, but TPM parts have
217 // been known to store the EK cert in the PH NV. If we disable it, the
218 // EK cert will be unreadable.
221 Status
= Tpm2HierarchyControl (
222 TPM_RH_PLATFORM
, // AuthHandle
224 TPM_RH_PLATFORM
, // Hierarchy
227 DEBUG ((DEBUG_VERBOSE
, "%a:%a() - Disable PH = %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
228 if (EFI_ERROR (Status
)) {
229 DEBUG ((DEBUG_ERROR
, "%a:%a() - Disable PH Failed! %r\n", gEfiCallerBaseName
, __FUNCTION__
, Status
));
230 ASSERT_EFI_ERROR (Status
);
237 This service defines the configuration of the Platform Hierarchy Authorization Value (platformAuth)
238 and Platform Hierarchy Authorization Policy (platformPolicy).
243 ConfigureTpmPlatformHierarchy (
246 if (PcdGetBool (PcdRandomizePlatformHierarchy
)) {
248 // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
250 RandomizePlatformAuth ();
253 // Disable the hierarchy entirely (do not randomize it)
255 DisableTpmPlatformHierarchy ();