From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.158.5]) by mx.groups.io with SMTP id smtpd.web08.23782.1628782228897962248 for ; Thu, 12 Aug 2021 08:30:34 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@ibm.com header.s=pp1 header.b=S/azLLLq; spf=pass (domain: linux.ibm.com, ip: 148.163.158.5, mailfrom: stefanb@linux.ibm.com) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 17CF5vJN017004; Thu, 12 Aug 2021 11:30:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=subject : to : cc : references : from : message-id : date : in-reply-to : content-type : mime-version; s=pp1; bh=AV70Zfe2RT6BNx+Qxo5ScL1hbPPs57Z7SeW3B6tDTGo=; b=S/azLLLqKFBecu35HG1ncsxfjO0T/GS5O2ooKjEWi2Ej+jYd96LCVWVOM2ZZyzhdFeA4 lB+fL2Ft6iO5cK79H1E0fYd7RlH9J1UjSVHBkSsGBXMWHjqdFeyWTaP7Va6+2VMpbVXM WxlISU1SmIAyNHHtnd0HNa8VjVgWLZvCOjwYwF1S0IPM5KKtOZE55f0JUOxrYIuEvvrI ZwM0InV6KJHuOKWP5aoO8mvg+UKt/q6HDe7SfOCX077GJKst1bB0QVSOpsdnqpw4sZXH lj0/m9B9dhd9LmKiHE0jKVH5A/F54oeYCXFi/5LSrAFajJ99yf5QQvZkqOtpus8xY9XH iQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ad4qakfdx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Aug 2021 11:30:27 -0400 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 17CF6BxA018056; Thu, 12 Aug 2021 11:30:26 -0400 Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ad4qakfdk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Aug 2021 11:30:26 -0400 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 17CFBXNi020280; Thu, 12 Aug 2021 15:30:25 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma02wdc.us.ibm.com with ESMTP id 3aapjcmedx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 12 Aug 2021 15:30:25 +0000 Received: from b01ledav002.gho.pok.ibm.com (b01ledav002.gho.pok.ibm.com [9.57.199.107]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 17CFUPAF32571672 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 12 Aug 2021 15:30:25 GMT Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1DFD7124066; Thu, 12 Aug 2021 15:30:25 +0000 (GMT) Received: from b01ledav002.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EA66F124072; Thu, 12 Aug 2021 15:30:24 +0000 (GMT) Received: from [9.47.158.152] (unknown [9.47.158.152]) by b01ledav002.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 12 Aug 2021 15:30:24 +0000 (GMT) Subject: Re: [edk2-devel] [PATCH v3 1/6] OvmfPkg/TPM: Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms To: devel@edk2.groups.io, mlureau@redhat.com, Stefan Berger Cc: jiewen.yao@intel.com, Laszlo Ersek , dick_wilkins@phoenix.com, James.Bottomley@hansenpartnership.com References: <20210810172029.4166819-1-stefanb@linux.vnet.ibm.com> <20210810172029.4166819-2-stefanb@linux.vnet.ibm.com> From: "Stefan Berger" Message-ID: <6646affc-2bc1-5a10-2f49-30897c82c96b@linux.ibm.com> Date: Thu, 12 Aug 2021 11:30:24 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 In-Reply-To: X-TM-AS-GCONF: 00 X-Proofpoint-GUID: KClFlvjvYrCqhYhNkPUIRahqnorMiSdT X-Proofpoint-ORIG-GUID: -xThMZSYYTvkrwE8MGG-29NBexUBJvUh X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391,18.0.790 definitions=2021-08-12_05:2021-08-12,2021-08-12 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 adultscore=0 lowpriorityscore=0 malwarescore=0 spamscore=0 mlxlogscore=999 mlxscore=0 bulkscore=0 suspectscore=0 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2108120098 Content-Type: multipart/alternative; boundary="------------D7E8BC6DEDFB9D33C49A0D23" Content-Language: en-US --------------D7E8BC6DEDFB9D33C49A0D23 Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by mx0b-001b2d01.pphosted.com id 17CF5vJN017004 On 8/12/21 9:48 AM, Marc-Andr=C3=A9 Lureau wrote: > Hi On Tue, Aug 10, 2021 at 9:22 PM Stefan Berger=20 > wrote: Import=20 > PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms. Modify it so that=20 > ConfigureTpmPlatformHierarchy() is the only public function provided =E2= =80=8D=20 > =E2=80=8D ZjQcmQRYFpfptBannerStart > This Message Is From an External Sender > This message came from outside your organization. > ZjQcmQRYFpfptBannerEnd > Hi > > On Tue, Aug 10, 2021 at 9:22 PM Stefan Berger=20 > > wrote: > > Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms. Modify > it so > that ConfigureTpmPlatformHierarchy() is the only public function > provided > by this file. > > Signed-off-by: Stefan Berger > > --- > =C2=A0.../Include/Library/TpmPlatformHierarchyLib.h |=C2=A0 27 +++ > =C2=A0.../PeiDxeTpmPlatformHierarchyLib.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0| 210 > ++++++++++++++++++ > =C2=A0.../PeiDxeTpmPlatformHierarchyLib.inf=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0|=C2=A0 40 ++++ > =C2=A03 files changed, 277 insertions(+) > =C2=A0create mode 100644 OvmfPkg/Include/Library/TpmPlatformHierarchy= Lib.h > =C2=A0create mode 100644 > OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierar= chyLib.c > =C2=A0create mode 100644 > OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierar= chyLib.inf > > diff --git a/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h > b/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h > new file mode 100644 > index 0000000000..a872fa09dc > --- /dev/null > +++ b/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h > @@ -0,0 +1,27 @@ > +/** @file > +=C2=A0 =C2=A0 TPM Platform Hierarchy configuration library. > + > +=C2=A0 =C2=A0 This library provides functions for customizing the TP= M's > Platform Hierarchy > +=C2=A0 =C2=A0 Authorization Value (platformAuth) and Platform Hierar= chy > Authorization > +=C2=A0 =C2=A0 Policy (platformPolicy) can be defined through this fu= nction. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +Copyright (c) Microsoft Corporation.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _TPM_PLATFORM_HIERARCHY_LIB_H_ > +#define _TPM_PLATFORM_HIERARCHY_LIB_H_ > + > +/** > +=C2=A0 =C2=A0This service will perform the TPM Platform Hierarchy > configuration at the SmmReadyToLock event. > + > +**/ > +VOID > +EFIAPI > +ConfigureTpmPlatformHierarchy ( > +=C2=A0 VOID > +=C2=A0 ); > + > +#endif > diff --git > a/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.c > b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.c > new file mode 100644 > index 0000000000..ba2d99bb53 > --- /dev/null > +++ > b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.c > @@ -0,0 +1,210 @@ > +/** @file > +=C2=A0 =C2=A0 TPM Platform Hierarchy configuration library. > + > +=C2=A0 =C2=A0 This library provides functions for customizing the TP= M's > Platform Hierarchy > +=C2=A0 =C2=A0 Authorization Value (platformAuth) and Platform Hierar= chy > Authorization > +=C2=A0 =C2=A0 Policy (platformPolicy) can be defined through this fu= nction. > + > +=C2=A0 =C2=A0 Copyright (c) 2019, Intel Corporation. All rights rese= rved.
> +=C2=A0 =C2=A0 Copyright (c) Microsoft Corporation.
> +=C2=A0 =C2=A0 SPDX-License-Identifier: BSD-2-Clause-Patent > + > +=C2=A0 =C2=A0 @par Specification Reference: > + > https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-= guidance/ > > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +// > +// The authorization value may be no larger than the digest > produced by the hash > +//=C2=A0 =C2=A0algorithm used for context integrity. > +// > +#define=C2=A0 =C2=A0 =C2=A0 MAX_NEW_AUTHORIZATION_SIZE SHA512_DIGEST= _SIZE > + > +UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0mAuthSize; > + > +/** > +=C2=A0 Generate high-quality entropy source through RDRAND. > + > +=C2=A0 @param[in]=C2=A0 =C2=A0Length=C2=A0 =C2=A0 =C2=A0 =C2=A0 Size= of the buffer, in bytes, to > fill with. > +=C2=A0 @param[out]=C2=A0 Entropy=C2=A0 =C2=A0 =C2=A0 =C2=A0Pointer t= o the buffer to store the > entropy data. > + > +=C2=A0 @retval EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 Entropy genera= tion succeeded. > +=C2=A0 @retval EFI_NOT_READY=C2=A0 =C2=A0 =C2=A0 Failed to request r= andom data. > + > +**/ > +EFI_STATUS > +EFIAPI > +RdRandGenerateEntropy ( > +=C2=A0 IN UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Length, > +=C2=A0 OUT UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0 *Entropy > +=C2=A0 ) > +{ > +=C2=A0 EFI_STATUS=C2=A0 Status; > +=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0BlockCount; > +=C2=A0 UINT64=C2=A0 =C2=A0 =C2=A0 Seed[2]; > +=C2=A0 UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0*Ptr; > + > +=C2=A0 Status =3D EFI_NOT_READY; > +=C2=A0 BlockCount =3D Length / 64; > +=C2=A0 Ptr =3D (UINT8 *)Entropy; > + > +=C2=A0 // > +=C2=A0 // Generate high-quality seed for DRBG Entropy > +=C2=A0 // > +=C2=A0 while (BlockCount > 0) { > +=C2=A0 =C2=A0 Status =3D GetRandomNumber128 (Seed); > +=C2=A0 =C2=A0 if (EFI_ERROR (Status)) { > +=C2=A0 =C2=A0 =C2=A0 return Status; > +=C2=A0 =C2=A0 } > +=C2=A0 =C2=A0 CopyMem (Ptr, Seed, 64); > > > This looks like it's copying past the Seed buffer, which is 2 *=20 > sizeof(u64) =3D 16. Ha! Thanks for looking at this. Those seem to be the pitfalls of blindly=20 importing code from edk2-platforms. Now the question is whether to leave=20 it broken in edk2-platforms or fix it there first before trying to=20 import it to edk2. In the interest of time I'd rather fix it here.=20 Obviously the BlockCount is also wrong. > > + > +=C2=A0 =C2=A0 BlockCount--; > +=C2=A0 =C2=A0 Ptr =3D Ptr + 64; > +=C2=A0 } > + > +=C2=A0 // > +=C2=A0 // Populate the remained data as request. > +=C2=A0 // > +=C2=A0 Status =3D GetRandomNumber128 (Seed); > +=C2=A0 if (EFI_ERROR (Status)) { > +=C2=A0 =C2=A0 return Status; > +=C2=A0 } > +=C2=A0 CopyMem (Ptr, Seed, (Length % 64)); > > > And then again. > > Isn't there a better way to fill a buffer with random data in edk2? I don't know. On ARM it *looks like* the path goes down to an assembly=20 instruction getting 64bit random number from the hardware:=20 MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm On x86 it will end up calling GenerateRandomNumberViaNist800Algorithm:=20 MdePkg/Library/DxeRngLib/DxeRngLib.c CryptoPkg/Drvier/Crypto.c has this here: BOOLEAN EFIAPI CryptoServiceRandomSeed ( =C2=A0 IN=C2=A0 CONST=C2=A0 UINT8=C2=A0 *Seed=C2=A0 OPTIONAL, =C2=A0 IN=C2=A0 UINTN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Seed= Size =C2=A0 ) { =C2=A0 return CALL_BASECRYPTLIB (Random.Services.Seed, RandomSeed, (Seed,= =20 SeedSize) } and this one: BOOLEAN EFIAPI CryptoServiceRandomBytes ( =C2=A0 OUT=C2=A0 UINT8=C2=A0 *Output, =C2=A0 IN=C2=A0=C2=A0 UINTN=C2=A0 Size =C2=A0 ) { =C2=A0 return CALL_BASECRYPTLIB (Random.Services.Bytes, RandomBytes,=20 (Output, Size) } Those are pseudorandom numbers. I don't know about others. > > + > +=C2=A0 return Status; > +} > + > +/** > +=C2=A0 This function returns the maximum size of TPM2B_AUTH; this > structure is used for an authorization value > +=C2=A0 and limits an authValue to being no larger than the largest > digest produced by a TPM. > + > +=C2=A0 @param[out] AuthSize=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0Tpm2 Auth size > + > +=C2=A0 @retval EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Auth size returned. > +=C2=A0 @retval EFI_DEVICE_ERROR=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0Can not return platform > auth due to device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetAuthSize ( > +=C2=A0 OUT UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *AuthSize > +=C2=A0 ) > +{ > +=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Status; > +=C2=A0 TPML_PCR_SELECTION=C2=A0 =C2=A0 Pcrs; > +=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0Index; > +=C2=A0 UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= DigestSize; > + > +=C2=A0 Status =3D EFI_SUCCESS; > + > +=C2=A0 while (mAuthSize =3D=3D 0) { > > > This is a bit odd, but ok. > > + > +=C2=A0 =C2=A0 mAuthSize =3D SHA1_DIGEST_SIZE; > +=C2=A0 =C2=A0 ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION)); > +=C2=A0 =C2=A0 Status =3D Tpm2GetCapabilityPcrs (&Pcrs); > + > +=C2=A0 =C2=A0 if (EFI_ERROR (Status)) { > +=C2=A0 =C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs fai= l!\n")); > +=C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 } > + > +=C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - %08x\n", > Pcrs.count)); > + > +=C2=A0 =C2=A0 for (Index =3D 0; Index < Pcrs.count; Index++) { > +=C2=A0 =C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "alg - %x\n", > Pcrs.pcrSelections[Index].hash)); > + > +=C2=A0 =C2=A0 =C2=A0 switch (Pcrs.pcrSelections[Index].hash) { > +=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA1: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA1_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA256: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA256_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA384: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA384_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA512: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA512_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SM3_256: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SM3_256_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 default: > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA1_DIGEST_SIZE; > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break; > +=C2=A0 =C2=A0 =C2=A0 } > + > +=C2=A0 =C2=A0 =C2=A0 if (DigestSize > mAuthSize) { > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mAuthSize =3D DigestSize; > +=C2=A0 =C2=A0 =C2=A0 } > +=C2=A0 =C2=A0 } > +=C2=A0 =C2=A0 break; > +=C2=A0 } > + > +=C2=A0 *AuthSize =3D mAuthSize; > +=C2=A0 return Status; > +} > + > +/** > +=C2=A0 Set PlatformAuth to random value. > +**/ > +VOID > +RandomizePlatformAuth ( > +=C2=A0 VOID > +=C2=A0 ) > +{ > +=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Status; > +=C2=A0 UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AuthSize; > +=C2=A0 UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*Rand; > +=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RandSize; > +=C2=A0 TPM2B_AUTH=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NewPlatformAuth; > + > +=C2=A0 // > +=C2=A0 // Send Tpm2HierarchyChange Auth with random value to avoid > PlatformAuth being null > +=C2=A0 // > + > +=C2=A0 GetAuthSize (&AuthSize); > + > +=C2=A0 ZeroMem (NewPlatformAuth.buffer, AuthSize); > +=C2=A0 NewPlatformAuth.size =3D AuthSize; > + > +=C2=A0 // > +=C2=A0 // Allocate one buffer to store random data. > +=C2=A0 // > +=C2=A0 RandSize =3D MAX_NEW_AUTHORIZATION_SIZE; > +=C2=A0 Rand =3D AllocatePool (RandSize); > + > +=C2=A0 RdRandGenerateEntropy (RandSize, Rand); > +=C2=A0 CopyMem (NewPlatformAuth.buffer, Rand, AuthSize); > > > Why generate random data for MAX_NEW_AUTHORIZATION to only copy a=20 > subset after? > > + > +=C2=A0 FreePool (Rand); > + > +=C2=A0 // > +=C2=A0 // Send Tpm2HierarchyChangeAuth command with the new Auth val= ue > +=C2=A0 // > +=C2=A0 Status =3D Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM, NULL, > &NewPlatformAuth); > +=C2=A0 DEBUG ((DEBUG_INFO, "Tpm2HierarchyChangeAuth Result: - %r\n", > Status)); > +=C2=A0 ZeroMem (NewPlatformAuth.buffer, AuthSize); > +=C2=A0 ZeroMem (Rand, RandSize); > > > Isn't Rand free at this point? Indeed! > > +} > + > +/** > +=C2=A0 =C2=A0This service defines the configuration of the Platform > Hierarchy Authorization Value (platformAuth) > +=C2=A0 =C2=A0and Platform Hierarchy Authorization Policy (platformPo= licy) > + > +**/ > +VOID > +EFIAPI > +ConfigureTpmPlatformHierarchy ( > +=C2=A0 ) > +{ > +=C2=A0 RandomizePlatformAuth (); > +} > diff --git > a/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.inf > b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.inf > new file mode 100644 > index 0000000000..a413e02302 > --- /dev/null > +++ > b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHier= archyLib.inf > @@ -0,0 +1,40 @@ > +### @file > +# > +#=C2=A0 =C2=A0TPM Platform Hierarchy configuration library. > +# > +#=C2=A0 =C2=A0This library provides functions for customizing the TP= M's > Platform Hierarchy > +#=C2=A0 =C2=A0Authorization Value (platformAuth) and Platform Hierar= chy > Authorization > +#=C2=A0 =C2=A0Policy (platformPolicy) can be defined through this fu= nction. > +# > +# Copyright (c) 2019, Intel Corporation. All rights reserved.
> +# Copyright (c) Microsoft Corporation.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +### > + > +[Defines] > +=C2=A0 INF_VERSION=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D 0x00010005 > +=C2=A0 BASE_NAME=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D PeiDxeTpmPlatformHierarchyLib > +=C2=A0 FILE_GUID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =3D > 7794F92C-4E8E-4E57-9E4A-49A0764C7D73 > +=C2=A0 MODULE_TYPE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D PEIM > +=C2=A0 VERSION_STRING=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0=3D 1.0 > +=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =3D TpmPlatformHierarchyLib|PEIM > DXE_DRIVER > + > +[LibraryClasses] > +=C2=A0 BaseLib > +=C2=A0 BaseMemoryLib > +=C2=A0 DebugLib > +=C2=A0 MemoryAllocationLib > +=C2=A0 RngLib > +=C2=A0 Tpm2CommandLib > +=C2=A0 Tpm2DeviceLib > + > +[Packages] > +=C2=A0 MdePkg/MdePkg.dec > +=C2=A0 MdeModulePkg/MdeModulePkg.dec > +=C2=A0 SecurityPkg/SecurityPkg.dec > +=C2=A0 CryptoPkg/CryptoPkg.dec > + > +[Sources] > +=C2=A0 PeiDxeTpmPlatformHierarchyLib.c > --=20 > 2.31.1 > >=20 --------------D7E8BC6DEDFB9D33C49A0D23 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable


On 8/12/21 9:48 AM, Marc-Andr=C3=A9 Lure= au wrote:
=20 =20
Hi

On Tue, Aug 10, 2021 at 9:2= 2 PM Stefan Berger <stefanb@linux.vnet.ibm.com> wrote:
Import PeiDxeTpmPlatformHierarchyLib.c from edk2-platforms. Modify it so
that ConfigureTpmPlatformHierarchy() is the only public function provided
by this file.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
=C2=A0.../Include/Library/TpmPlatformHierarchyLib.h |=C2=A0 27 = +++
=C2=A0.../PeiDxeTpmPlatformHierarchyLib.c=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0| 210 ++++++++++++++++++
=C2=A0.../PeiDxeTpmPlatformHierarchyLib.inf=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0|=C2=A0 40 ++++
=C2=A03 files changed, 277 insertions(+)
=C2=A0create mode 100644 OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h
=C2=A0create mode 100644 OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib= .c
=C2=A0create mode 100644 OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib= .inf

diff --git a/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h b/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h
new file mode 100644
index 0000000000..a872fa09dc
--- /dev/null
+++ b/OvmfPkg/Include/Library/TpmPlatformHierarchyLib.h
@@ -0,0 +1,27 @@
+/** @file
+=C2=A0 =C2=A0 TPM Platform Hierarchy configuration library. +
+=C2=A0 =C2=A0 This library provides functions for customizing = the TPM's Platform Hierarchy
+=C2=A0 =C2=A0 Authorization Value (platformAuth) and Platform Hierarchy Authorization
+=C2=A0 =C2=A0 Policy (platformPolicy) can be defined through t= his 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_
+
+/**
+=C2=A0 =C2=A0This service will perform the TPM Platform Hierar= chy configuration at the SmmReadyToLock event.
+
+**/
+VOID
+EFIAPI
+ConfigureTpmPlatformHierarchy (
+=C2=A0 VOID
+=C2=A0 );
+
+#endif
diff --git a/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.c b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.c
new file mode 100644
index 0000000000..ba2d99bb53
--- /dev/null
+++ b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.c
@@ -0,0 +1,210 @@
+/** @file
+=C2=A0 =C2=A0 TPM Platform Hierarchy configuration library. +
+=C2=A0 =C2=A0 This library provides functions for customizing = the TPM's Platform Hierarchy
+=C2=A0 =C2=A0 Authorization Value (platformAuth) and Platform Hierarchy Authorization
+=C2=A0 =C2=A0 Policy (platformPolicy) can be defined through t= his function.
+
+=C2=A0 =C2=A0 Copyright (c) 2019, Intel Corporation. All right= s reserved.<BR>
+=C2=A0 =C2=A0 Copyright (c) Microsoft Corporation.<BR> +=C2=A0 =C2=A0 SPDX-License-Identifier: BSD-2-Clause-Patent
+
+=C2=A0 =C2=A0 @par Specification Reference:
+=C2=A0 =C2=A0 https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guida= nce/
+**/
+
+#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
+//=C2=A0 =C2=A0algorithm used for context integrity.
+//
+#define=C2=A0 =C2=A0 =C2=A0 MAX_NEW_AUTHORIZATION_SIZE SHA512_= DIGEST_SIZE
+
+UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0mAuthSize;
+
+/**
+=C2=A0 Generate high-quality entropy source through RDRAND. +
+=C2=A0 @param[in]=C2=A0 =C2=A0Length=C2=A0 =C2=A0 =C2=A0 =C2= =A0 Size of the buffer, in bytes, to fill with.
+=C2=A0 @param[out]=C2=A0 Entropy=C2=A0 =C2=A0 =C2=A0 =C2=A0Poi= nter to the buffer to store the entropy data.
+
+=C2=A0 @retval EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 Entropy = generation succeeded.
+=C2=A0 @retval EFI_NOT_READY=C2=A0 =C2=A0 =C2=A0 Failed to req= uest random data.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGenerateEntropy (
+=C2=A0 IN UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Length,
+=C2=A0 OUT UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0 *Entropy
+=C2=A0 )
+{
+=C2=A0 EFI_STATUS=C2=A0 Status;
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0BlockCount;
+=C2=A0 UINT64=C2=A0 =C2=A0 =C2=A0 Seed[2];
+=C2=A0 UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0*Ptr;
+
+=C2=A0 Status =3D EFI_NOT_READY;
+=C2=A0 BlockCount =3D Length / 64;
+=C2=A0 Ptr =3D (UINT8 *)Entropy;
+
+=C2=A0 //
+=C2=A0 // Generate high-quality seed for DRBG Entropy
+=C2=A0 //
+=C2=A0 while (BlockCount > 0) {
+=C2=A0 =C2=A0 Status =3D GetRandomNumber128 (Seed);
+=C2=A0 =C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 =C2=A0 return Status;
+=C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 CopyMem (Ptr, Seed, 64);

This looks like it's copying past the Seed buffer, which is 2 * sizeof(u64) =3D 16.

Ha! Thanks for looking at this. Those seem to be the pitfalls of blindly importing code from edk2-platforms. Now the question is whether to leave it broken in edk2-platforms or fix it there first before trying to import it to edk2. In the interest of time I'd rather fix it here. Obviously the BlockCount is also wrong.



+
+=C2=A0 =C2=A0 BlockCount--;
+=C2=A0 =C2=A0 Ptr =3D Ptr + 64;
+=C2=A0 }
+
+=C2=A0 //
+=C2=A0 // Populate the remained data as request.
+=C2=A0 //
+=C2=A0 Status =3D GetRandomNumber128 (Seed);
+=C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 return Status;
+=C2=A0 }
+=C2=A0 CopyMem (Ptr, Seed, (Length % 64));

And then again.

Isn't there a better way to fill a buffer with random data in edk2?

I don't know. On ARM it *looks like* the path goes down to an assembly instruction getting 64bit random number from the hardware: MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm

On x86 it will end up calling GenerateRandomNumberViaNist800Algorithm: MdePkg/Library/DxeRngLib/DxeRngLib.c


CryptoPkg/Drvier/Crypto.c has this here:

BOOLEAN
EFIAPI
CryptoServiceRandomSeed (
=C2=A0 IN=C2=A0 CONST=C2=A0 UINT8=C2=A0 *Seed=C2=A0 OPTIONAL,
=C2=A0 IN=C2=A0 UINTN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= SeedSize
=C2=A0 )
{
=C2=A0 return CALL_BASECRYPTLIB (Random.Services.Seed, RandomSeed, (Seed, SeedSize)
}

and this one:

BOOLEAN
EFIAPI
CryptoServiceRandomBytes (
=C2=A0 OUT=C2=A0 UINT8=C2=A0 *Output,
=C2=A0 IN=C2=A0=C2=A0 UINTN=C2=A0 Size
=C2=A0 )
{
=C2=A0 return CALL_BASECRYPTLIB (Random.Services.Bytes, RandomBytes, (Output, Size)
}


Those are pseudorandom numbers. I don't know about others.



+
+=C2=A0 return Status;
+}
+
+/**
+=C2=A0 This function returns the maximum size of TPM2B_AUTH; this structure is used for an authorization value
+=C2=A0 and limits an authValue to being no larger than the largest digest produced by a TPM.
+
+=C2=A0 @param[out] AuthSize=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0Tpm2 Auth size
+
+=C2=A0 @retval EFI_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 Auth size returned.
+=C2=A0 @retval EFI_DEVICE_ERROR=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0Can not return platform auth due to device error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAuthSize (
+=C2=A0 OUT UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *Au= thSize
+=C2=A0 )
+{
+=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Sta= tus;
+=C2=A0 TPML_PCR_SELECTION=C2=A0 =C2=A0 Pcrs;
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0Index;
+=C2=A0 UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 DigestSize;
+
+=C2=A0 Status =3D EFI_SUCCESS;
+
+=C2=A0 while (mAuthSize =3D=3D 0) {

This is a bit odd, but ok.

+
+=C2=A0 =C2=A0 mAuthSize =3D SHA1_DIGEST_SIZE;
+=C2=A0 =C2=A0 ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION))= ;
+=C2=A0 =C2=A0 Status =3D Tpm2GetCapabilityPcrs (&Pcrs); +
+=C2=A0 =C2=A0 if (EFI_ERROR (Status)) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPc= rs fail!\n"));
+=C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - %0= 8x\n", Pcrs.count));
+
+=C2=A0 =C2=A0 for (Index =3D 0; Index < Pcrs.count; Index++= ) {
+=C2=A0 =C2=A0 =C2=A0 DEBUG ((DEBUG_ERROR, "alg - %x\n", Pcrs.pcrSelections[Index].hash));
+
+=C2=A0 =C2=A0 =C2=A0 switch (Pcrs.pcrSelections[Index].hash) {=
+=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA1:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA1_DIGEST_SIZE; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA256:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA256_DIGEST_SIZE;=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA384:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA384_DIGEST_SIZE;=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SHA512:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA512_DIGEST_SIZE;=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 case TPM_ALG_SM3_256:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SM3_256_DIGEST_SIZE= ;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DigestSize =3D SHA1_DIGEST_SIZE; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 if (DigestSize > mAuthSize) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 mAuthSize =3D DigestSize;
+=C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 break;
+=C2=A0 }
+
+=C2=A0 *AuthSize =3D mAuthSize;
+=C2=A0 return Status;
+}
+
+/**
+=C2=A0 Set PlatformAuth to random value.
+**/
+VOID
+RandomizePlatformAuth (
+=C2=A0 VOID
+=C2=A0 )
+{
+=C2=A0 EFI_STATUS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Status;
+=C2=A0 UINT16=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AuthSize;
+=C2=A0 UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*Rand;
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0RandSize;
+=C2=A0 TPM2B_AUTH=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NewPlatformAuth;
+
+=C2=A0 //
+=C2=A0 // Send Tpm2HierarchyChange Auth with random value to avoid PlatformAuth being null
+=C2=A0 //
+
+=C2=A0 GetAuthSize (&AuthSize);
+
+=C2=A0 ZeroMem (NewPlatformAuth.buffer, AuthSize);
+=C2=A0 NewPlatformAuth.size =3D AuthSize;
+
+=C2=A0 //
+=C2=A0 // Allocate one buffer to store random data.
+=C2=A0 //
+=C2=A0 RandSize =3D MAX_NEW_AUTHORIZATION_SIZE;
+=C2=A0 Rand =3D AllocatePool (RandSize);
+
+=C2=A0 RdRandGenerateEntropy (RandSize, Rand);
+=C2=A0 CopyMem (NewPlatformAuth.buffer, Rand, AuthSize);

Why generate random data for MAX_NEW_AUTHORIZATION to only copy a subset after?

+
+=C2=A0 FreePool (Rand);
+
+=C2=A0 //
+=C2=A0 // Send Tpm2HierarchyChangeAuth command with the new Au= th value
+=C2=A0 //
+=C2=A0 Status =3D Tpm2HierarchyChangeAuth (TPM_RH_PLATFORM, NU= LL, &NewPlatformAuth);
+=C2=A0 DEBUG ((DEBUG_INFO, "Tpm2HierarchyChangeAuth Result: - %r\n", Status));
+=C2=A0 ZeroMem (NewPlatformAuth.buffer, AuthSize);
+=C2=A0 ZeroMem (Rand, RandSize);

Isn't Rand free at this point?


Indeed!



+}
+
+/**
+=C2=A0 =C2=A0This service defines the configuration of the Pla= tform Hierarchy Authorization Value (platformAuth)
+=C2=A0 =C2=A0and Platform Hierarchy Authorization Policy (platformPolicy)
+
+**/
+VOID
+EFIAPI
+ConfigureTpmPlatformHierarchy (
+=C2=A0 )
+{
+=C2=A0 RandomizePlatformAuth ();
+}
diff --git a/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.inf b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.inf
new file mode 100644
index 0000000000..a413e02302
--- /dev/null
+++ b/OvmfPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyL= ib.inf
@@ -0,0 +1,40 @@
+### @file
+#
+#=C2=A0 =C2=A0TPM Platform Hierarchy configuration library. +#
+#=C2=A0 =C2=A0This library provides functions for customizing = the TPM's Platform Hierarchy
+#=C2=A0 =C2=A0Authorization Value (platformAuth) and Platform Hierarchy Authorization
+#=C2=A0 =C2=A0Policy (platformPolicy) can be defined through t= his function.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+=C2=A0 INF_VERSION=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 0x00010005
+=C2=A0 BASE_NAME=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D PeiDxeTpmPlatformHierarchyLib
+=C2=A0 FILE_GUID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D 7794F92C-4E8E-4E57-9E4A-49A0764C7D73
+=C2=A0 MODULE_TYPE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D PEIM
+=C2=A0 VERSION_STRING=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0=3D 1.0
+=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D TpmPlatformHierarchyLib|PEIM DXE_DRIVER
+
+[LibraryClasses]
+=C2=A0 BaseLib
+=C2=A0 BaseMemoryLib
+=C2=A0 DebugLib
+=C2=A0 MemoryAllocationLib
+=C2=A0 RngLib
+=C2=A0 Tpm2CommandLib
+=C2=A0 Tpm2DeviceLib
+
+[Packages]
+=C2=A0 MdePkg/MdePkg.dec
+=C2=A0 MdeModulePkg/MdeModulePkg.dec
+=C2=A0 SecurityPkg/SecurityPkg.dec
+=C2=A0 CryptoPkg/CryptoPkg.dec
+
+[Sources]
+=C2=A0 PeiDxeTpmPlatformHierarchyLib.c
--
2.31.1

=20
--------------D7E8BC6DEDFB9D33C49A0D23--