From nobody Mon Feb 9 12:43:20 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+82716+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82716+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1635269956; cv=none; d=zohomail.com; s=zohoarc; b=PU47sBAUm2ahnG0bl4/qAm41oiml6rX1exo9+VK2xp5v8BOfvrAKL1SPRyELkmnKr448P5UIu/PvY/mIcynbRLB6y3rm6E43RZ9Ykh4bpc2L0KVqIGwgdRkFd2ptBmUJ2Wycl/g0yf0xomvbreHLO+bFkZPnhq2lyT8zAOlOa9U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1635269956; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=1yAeRTMqRoGlsoGroplaqXmoZcuW2cDCqjjrq5tCB7A=; b=D//5JlxnOMjXZjoT+AGztDMNtt5T8pogUV+90HqrsgcFLVreCbBf3bmaCo5lZD/OgUN0x15aO0xmYZEpPLocfsVNB0D8Og0oaFy99YNqiV0cejRduVOOZ9Garc7KzMvjAynHneDEGYUOcpfBNigNJQ4tMIxdPxY84dAWI2cHHUU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+82716+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1635269956553437.17604421457065; Tue, 26 Oct 2021 10:39:16 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id tTIVYY1788612xLVx6fhgnnN; Tue, 26 Oct 2021 10:39:16 -0700 X-Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by mx.groups.io with SMTP id smtpd.web12.474.1635269954984269854 for ; Tue, 26 Oct 2021 10:39:15 -0700 X-Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19QFh46Z009527; Tue, 26 Oct 2021 17:39:14 GMT X-Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3bx4k8rx91-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 26 Oct 2021 17:39:13 +0000 X-Received: from m0098417.ppops.net (m0098417.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 19QHL3fj031478; Tue, 26 Oct 2021 17:39:12 GMT X-Received: from ppma01wdc.us.ibm.com (fd.55.37a9.ip4.static.sl-reverse.com [169.55.85.253]) by mx0a-001b2d01.pphosted.com with ESMTP id 3bx4k8rx8g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 26 Oct 2021 17:39:12 +0000 X-Received: from pps.filterd (ppma01wdc.us.ibm.com [127.0.0.1]) by ppma01wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 19QHbmF6015978; Tue, 26 Oct 2021 17:39:11 GMT X-Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma01wdc.us.ibm.com with ESMTP id 3bx4efhgrk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 26 Oct 2021 17:39:11 +0000 X-Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 19QHdAlH40567250 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 26 Oct 2021 17:39:10 GMT X-Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4B6C46E05D; Tue, 26 Oct 2021 17:39:10 +0000 (GMT) X-Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 116E86E050; Tue, 26 Oct 2021 17:39:09 +0000 (GMT) X-Received: from sbct-2.pok.ibm.com (unknown [9.47.158.152]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 26 Oct 2021 17:39:08 +0000 (GMT) From: "Stefan Berger" To: devel@edk2.groups.io, kraxel@redhat.com, marcandre.lureau@redhat.com Cc: Stefan Berger , Jiewen Yao , Jian J Wang , Ard Biesheuvel , Jordan Justen Subject: [edk2-devel] [PATCH 3/4] OvmfPkg: Enable physical presence interface for TPM 1.2 Date: Tue, 26 Oct 2021 13:38:59 -0400 Message-Id: <20211026173900.1695306-4-stefanb@linux.ibm.com> In-Reply-To: <20211026173900.1695306-1-stefanb@linux.ibm.com> References: <20211026173900.1695306-1-stefanb@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: HyM5aEuGfMeLpo3UPOertG95aIsILVY0 X-Proofpoint-ORIG-GUID: JSIi24qIGvrQGI4m1Q9ja9vgW3H3qIbj Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,stefanb@linux.ibm.com X-Gm-Message-State: ioYHhCW2ZwBlpRxEMOVL3J7Fx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1635269956; bh=+/JSp+Cioek8bClclLVM6/aw8eu9nXkK8GXCwQp1w5M=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=ZysLII+pm/0XQ5tg6AcI9CrUfHc/SZRCVlPSyFsxPmcSGXtdGgnk0IqMDxauFEiSDWZ /R0QW0P7lzVSbfInDxeeoUFZeZ/99jvhHfrxBTM+tR4/zlk+fm7W0Za4iI6poVxlIFJ/t KeFvDXec9Koj6ST7rZM/Xa7w6gk51rZgpLA= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1635269957437100005 Content-Type: text/plain; charset="utf-8" Enable the physical presence interface for TPM 1.2. It is required for the TPM 1.2 menu to work. Cc: Jiewen Yao Cc: Jian J Wang Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Gerd Hoffmann Cc: Marc-Andr=C3=A9 Lureau Signed-off-by: Stefan Berger --- OvmfPkg/Include/Library/QemuPPI.h | 33 + .../PlatformBootManagerLib/BdsPlatform.c | 2 + .../PlatformBootManagerLib.inf | 1 + .../DxeTcgPhysicalPresenceLib.c | 22 + .../DxeTcgPhysicalPresenceLib.inf | 27 + .../DxeTcgPhysicalPresenceLib.c | 1452 +++++++++++++++++ .../DxeTcgPhysicalPresenceLib.inf | 64 + .../PhysicalPresenceStrings.uni | 46 + OvmfPkg/OvmfPkg.dec | 3 + OvmfPkg/OvmfTpmLibs.dsc.inc | 4 + .../Include/Library/TcgPhysicalPresenceLib.h | 39 + SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf | 1 + 12 files changed, 1694 insertions(+) create mode 100644 OvmfPkg/Include/Library/QemuPPI.h create mode 100644 OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysic= alPresenceLib.c create mode 100644 OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysic= alPresenceLib.inf create mode 100644 OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysic= alPresenceLib.c create mode 100644 OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysic= alPresenceLib.inf create mode 100644 OvmfPkg/Library/TcgPhysicalPresenceLibQemu/PhysicalPres= enceStrings.uni diff --git a/OvmfPkg/Include/Library/QemuPPI.h b/OvmfPkg/Include/Library/Qe= muPPI.h new file mode 100644 index 0000000000..84a575620e --- /dev/null +++ b/OvmfPkg/Include/Library/QemuPPI.h @@ -0,0 +1,33 @@ +/** @file + QEMU Physical Presence Interface + + Copyright (c) 2021 IBM Corporation + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __QEMU_PPI__ +#define __QEMU_PPI__ + +#include +#include +#include + +#define TPM_PPI_PROVISION_FLAGS(PpiFlags) \ + ((PpiFlags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) !=3D= 0) \ + ? QEMU_TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ \ + : QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ + +#define TPM_PPI_CLEAR_FLAGS(PpiFlags) \ + ((PpiFlags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) !=3D 0) \ + ? QEMU_TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ \ + : QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ + +#define TPM_PPI_CLEAR_MAINT_FLAGS(PpiFlags) \ + ((PpiFlags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) !=3D 0 &= & \ + (PpiFlags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != =3D 0) \ + ? QEMU_TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ \ + : QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ + +#endif diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg= /Library/PlatformBootManagerLib/BdsPlatform.c index 9b21ba2bd6..f56aff2ec5 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 =20 @@ -396,6 +397,7 @@ PlatformBootManagerBeforeConsole ( // // Process TPM PPI request; this may require keyboard input // + TcgPhysicalPresenceLibProcessRequest (); Tcg2PhysicalPresenceLibProcessRequest (NULL); =20 // diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.= inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf index c249a3cf1e..f12975d065 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -54,6 +54,7 @@ ReportStatusCodeLib UefiLib PlatformBmPrintScLib + TcgPhysicalPresenceLib Tcg2PhysicalPresenceLib XenPlatformLib =20 diff --git a/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPrese= nceLib.c b/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPresenc= eLib.c new file mode 100644 index 0000000000..d434175717 --- /dev/null +++ b/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPresenceLib.c @@ -0,0 +1,22 @@ +/** @file + NULL TcgPhysicalPresenceLib library instance + + Copyright (C) 2021, IBM Corporation + Copyright (c) 2018, Red Hat, Inc. + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +VOID +EFIAPI +TcgPhysicalPresenceLibProcessRequest ( + VOID + ) +{ + // + // do nothing + // +} diff --git a/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPrese= nceLib.inf b/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPrese= nceLib.inf new file mode 100644 index 0000000000..4d4349870f --- /dev/null +++ b/OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcgPhysicalPresenceLib.= inf @@ -0,0 +1,27 @@ +# NULL Tcg2PhysicalPresenceLib library instance +# +# Under SecurityPkg, the corresponding library instance will check and +# execute TPM 2.0 request from OS or BIOS; the request may ask for user +# confirmation before execution. This Null instance implements a no-op +# Tcg2PhysicalPresenceLibProcessRequest(), without user interaction. +# +# Copyright (C) 2018, Red Hat, Inc. +# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeTcgPhysicalPresenceLibNull + FILE_GUID =3D B648575C-ED00-4C0D-BD7F-B705B9B0CC93 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TcgPhysicalPresenceLib|DXE_DRIVER DXE= _RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + +[Sources] + DxeTcgPhysicalPresenceLib.c + +[Packages] + MdePkg/MdePkg.dec + SecurityPkg/SecurityPkg.dec diff --git a/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPrese= nceLib.c b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPresenc= eLib.c new file mode 100644 index 0000000000..d7fd11cae9 --- /dev/null +++ b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPresenceLib.c @@ -0,0 +1,1452 @@ +/** @file + + Execute pending TPM requests from OS or BIOS and Lock TPM. + + Caution: This module requires additional review when modified. + This driver will have external input - variable. + This external input must be validated carefully to avoid security issue. + + ExecutePendingTpmRequest() will receive untrusted input and do validatio= n. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONFIRM_BUFFER_SIZE 4096 + +EFI_HII_HANDLE mPpStringPackHandle; + +STATIC volatile QEMU_TPM_PPI *mPpi; + +/** + Reads QEMU PPI config from fw_cfg. + + @param[out] The Config structure to read to. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size. +**/ +STATIC +EFI_STATUS +QemuTpmReadConfig ( + OUT QEMU_FWCFG_TPM_CONFIG *Config + ) +{ + EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + + Status =3D QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status)) { + return Status; + } + + if (FwCfgSize !=3D sizeof (*Config)) { + return EFI_PROTOCOL_ERROR; + } + + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (sizeof (*Config), Config); + return EFI_SUCCESS; +} + + +/** + Initilalize the QEMU PPI memory region's function array +**/ +STATIC +VOID +QemuTpmInitPPIFunc( + EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags + ) +{ + ZeroMem ((void *)mPpi->Func, sizeof(mPpi->Func)); + + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE] =3D TPM_PPI_PROVISION_FLAGS(Ppi= Flags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_DISABLE] =3D TPM_PPI_PROVISION_FLAGS(Pp= iFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_ACTIVATE] =3D TPM_PPI_PROVISION_FLAGS(P= piFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_DEACTIVATE] =3D TPM_PPI_PROVISION_FLAGS= (PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_CLEAR] =3D TPM_PPI_CLEAR_FLAGS(PpiFlags= ); + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE_ACTIVATE] =3D TPM_PPI_PROVISION_= FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_DEACTIVATE_DISABLE] =3D TPM_PPI_PROVISI= ON_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE] =3D TPM_PPI_PRO= VISION_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE] =3D TPM_PPI_PR= OVISION_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE] =3D TPM_PPI= _PROVISION_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE] =3D TPM= _PPI_PROVISION_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_OPERATOR_AUTH] =3D TPM_PPI_PROVISIO= N_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE] =3D TPM_PPI_CLEA= R_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE] =3D QEMU_TP= M_PPI_FUNC_ALLOWED_USR_NOT_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE] =3D QEMU_TPM= _PPI_FUNC_ALLOWED_USR_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE] =3D QEMU_TPM_PP= I_FUNC_ALLOWED_USR_NOT_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE] =3D QEMU_TPM_PPI= _FUNC_ALLOWED_USR_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE] =3D QEMU_= TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE] =3D QEMU_T= PM_PPI_FUNC_ALLOWED_USR_REQ; + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR] =3D TPM_PPI_CLEA= R_MAINT_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE] = =3D TPM_PPI_CLEAR_MAINT_FLAGS(PpiFlags); + mPpi->Func[TCG_PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR] =3D TPM_PPI_CLEA= R_MAINT_FLAGS(PpiFlags); +} + + +/** + Initializes QEMU PPI memory region. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_PROTOCOL_ERROR PPI address is invalid. +**/ +STATIC +EFI_STATUS +QemuTpmInitPPI ( + VOID + ) +{ + EFI_STATUS Status; + QEMU_FWCFG_TPM_CONFIG Config; + EFI_PHYSICAL_ADDRESS PpiAddress64; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags; + + if (mPpi !=3D NULL) { + return EFI_SUCCESS; + } + + Status =3D QemuTpmReadConfig (&Config); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Config.TpmVersion !=3D QEMU_TPM_VERSION_1_2) { + DEBUG ((DEBUG_ERROR, "[TPMPP] Not setting up PPI. This is not a TPM 1.= 2.\n")); + return EFI_PROTOCOL_ERROR; + } + + mPpi =3D (QEMU_TPM_PPI *)(UINTN)Config.PpiAddress; + if (mPpi =3D=3D NULL) { + return EFI_PROTOCOL_ERROR; + } + + DEBUG ((DEBUG_INFO, "[TPMPP] mPpi=3D%p version=3D%d\n", mPpi, Config.Tpm= Version)); + + PpiAddress64 =3D (UINTN)mPpi; + if ((PpiAddress64 & ~(UINT64)EFI_PAGE_MASK) !=3D + ((PpiAddress64 + sizeof *mPpi - 1) & ~(UINT64)EFI_PAGE_MASK)) { + DEBUG ((DEBUG_ERROR, "[TPMPP] mPpi crosses a page boundary\n")); + goto InvalidPpiAddress; + } + + Status =3D gDS->GetMemorySpaceDescriptor (PpiAddress64, &Descriptor); + if (EFI_ERROR (Status) && Status !=3D EFI_NOT_FOUND) { + ASSERT_EFI_ERROR (Status); + goto InvalidPpiAddress; + } + if (!EFI_ERROR (Status) && + (Descriptor.GcdMemoryType !=3D EfiGcdMemoryTypeMemoryMappedIo && + Descriptor.GcdMemoryType !=3D EfiGcdMemoryTypeNonExistent)) { + DEBUG ((DEBUG_ERROR, "[TPMPP] mPpi has an invalid memory type\n")); + goto InvalidPpiAddress; + } + + PpiFlags.PPFlags =3D 0; + QemuTpmInitPPIFunc(PpiFlags); + + if (mPpi->In =3D=3D 0) { + mPpi->In =3D 1; + mPpi->Request =3D PHYSICAL_PRESENCE_NO_ACTION; + mPpi->LastRequest =3D PHYSICAL_PRESENCE_NO_ACTION; + mPpi->NextStep =3D PHYSICAL_PRESENCE_NO_ACTION; + } + + return EFI_SUCCESS; + +InvalidPpiAddress: + mPpi =3D NULL; + return EFI_PROTOCOL_ERROR; +} + +/** + Get string by string id from HII Interface. + + @param[in] Id String ID. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +PhysicalPresenceGetStringById ( + IN EFI_STRING_ID Id + ) +{ + return HiiGetString (mPpStringPackHandle, Id, NULL); +} + +/** + Get TPM physical presence permanent flags. + + @param[in] TcgProtocol EFI TCG Protocol instance. + @param[out] LifetimeLock physicalPresenceLifetimeLock permanent flag. + @param[out] CmdEnable physicalPresenceCMDEnable permanent flag. + + @retval EFI_SUCCESS Flags were returns successfully. + @retval other Failed to locate EFI TCG Protocol. + +**/ +EFI_STATUS +GetTpmCapability ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + OUT BOOLEAN *LifetimeLock, + OUT BOOLEAN *CmdEnable + ) +{ + EFI_STATUS Status; + TPM_RQU_COMMAND_HDR *TpmRqu; + TPM_RSP_COMMAND_HDR *TpmRsp; + UINT32 *SendBufPtr; + UINT8 SendBuffer[sizeof (*TpmRqu) + sizeof (= UINT32) * 3]; + TPM_PERMANENT_FLAGS *TpmPermanentFlags; + UINT8 RecvBuffer[40]; + + // + // Fill request header + // + TpmRsp =3D (TPM_RSP_COMMAND_HDR*)RecvBuffer; + TpmRqu =3D (TPM_RQU_COMMAND_HDR*)SendBuffer; + + TpmRqu->tag =3D SwapBytes16 (TPM_TAG_RQU_COMMAND); + TpmRqu->paramSize =3D SwapBytes32 (sizeof (SendBuffer)); + TpmRqu->ordinal =3D SwapBytes32 (TPM_ORD_GetCapability); + + // + // Set request parameter + // + SendBufPtr =3D (UINT32*)(TpmRqu + 1); + WriteUnaligned32 (SendBufPtr++, SwapBytes32 (TPM_CAP_FLAG)); + WriteUnaligned32 (SendBufPtr++, SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMAN= ENT))); + WriteUnaligned32 (SendBufPtr, SwapBytes32 (TPM_CAP_FLAG_PERMANENT)); + + Status =3D TcgProtocol->PassThroughToTpm ( + TcgProtocol, + sizeof (SendBuffer), + (UINT8*)TpmRqu, + sizeof (RecvBuffer), + (UINT8*)&RecvBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if ((TpmRsp->tag !=3D SwapBytes16 (TPM_TAG_RSP_COMMAND)) || (TpmRsp->ret= urnCode !=3D 0)) { + return EFI_DEVICE_ERROR; + } + + TpmPermanentFlags =3D (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP= _COMMAND_HDR) + sizeof (UINT32)]; + + if (LifetimeLock !=3D NULL) { + *LifetimeLock =3D TpmPermanentFlags->physicalPresenceLifetimeLock; + } + + if (CmdEnable !=3D NULL) { + *CmdEnable =3D TpmPermanentFlags->physicalPresenceCMDEnable; + } + + return Status; +} + +/** + Issue TSC_PhysicalPresence command to TPM. + + @param[in] TcgProtocol EFI TCG Protocol instance. + @param[in] PhysicalPresence The state to set the TPM's Physical Pres= ence flags. + + @retval EFI_SUCCESS TPM executed the command successfully. + @retval EFI_SECURITY_VIOLATION TPM returned error when executing the co= mmand. + @retval other Failed to locate EFI TCG Protocol. + +**/ +EFI_STATUS +TpmPhysicalPresence ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN TPM_PHYSICAL_PRESENCE PhysicalPresence + ) +{ + EFI_STATUS Status; + TPM_RQU_COMMAND_HDR *TpmRqu; + TPM_PHYSICAL_PRESENCE *TpmPp; + TPM_RSP_COMMAND_HDR TpmRsp; + UINT8 Buffer[sizeof (*TpmRqu) + sizeof (*Tpm= Pp)]; + + TpmRqu =3D (TPM_RQU_COMMAND_HDR*)Buffer; + TpmPp =3D (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1); + + TpmRqu->tag =3D SwapBytes16 (TPM_TAG_RQU_COMMAND); + TpmRqu->paramSize =3D SwapBytes32 (sizeof (Buffer)); + TpmRqu->ordinal =3D SwapBytes32 (TSC_ORD_PhysicalPresence); + WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) SwapBytes16 (PhysicalPr= esence)); + + Status =3D TcgProtocol->PassThroughToTpm ( + TcgProtocol, + sizeof (Buffer), + (UINT8*)TpmRqu, + sizeof (TpmRsp), + (UINT8*)&TpmRsp + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (TpmRsp.tag !=3D SwapBytes16 (TPM_TAG_RSP_COMMAND)) { + return EFI_DEVICE_ERROR; + } + + if (TpmRsp.returnCode !=3D 0) { + // + // If it fails, some requirements may be needed for this command. + // + return EFI_SECURITY_VIOLATION; + } + + return Status; +} + +/** + Issue a TPM command for which no additional output data will be returned. + + @param[in] TcgProtocol EFI TCG Protocol instance. + @param[in] Ordinal TPM command code. + @param[in] AdditionalParameterSize Additional parameter size. + @param[in] AdditionalParameters Pointer to the Additional parameters. + + @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during se= nding command to TPM or + receiving response from = TPM. + @retval Others Return code from the TPM= device after command execution. + +**/ +UINT32 +TpmCommandNoReturnData ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN TPM_COMMAND_CODE Ordinal, + IN UINTN AdditionalParameterSize, + IN VOID *AdditionalParameters + ) +{ + EFI_STATUS Status; + TPM_RQU_COMMAND_HDR *TpmRqu; + TPM_RSP_COMMAND_HDR TpmRsp; + UINT32 Size; + + TpmRqu =3D (TPM_RQU_COMMAND_HDR*) AllocatePool (sizeof (*TpmRqu) + Addit= ionalParameterSize); + if (TpmRqu =3D=3D NULL) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } + + TpmRqu->tag =3D SwapBytes16 (TPM_TAG_RQU_COMMAND); + Size =3D (UINT32)(sizeof (*TpmRqu) + AdditionalParameterSiz= e); + TpmRqu->paramSize =3D SwapBytes32 (Size); + TpmRqu->ordinal =3D SwapBytes32 (Ordinal); + CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize); + + Status =3D TcgProtocol->PassThroughToTpm ( + TcgProtocol, + Size, + (UINT8*)TpmRqu, + (UINT32)sizeof (TpmRsp), + (UINT8*)&TpmRsp + ); + FreePool (TpmRqu); + if (EFI_ERROR (Status) || (TpmRsp.tag !=3D SwapBytes16 (TPM_TAG_RSP_COMM= AND))) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } + return SwapBytes32 (TpmRsp.returnCode); +} + +/** + Execute physical presence operation requested by the OS. + + @param[in] TcgProtocol EFI TCG Protocol instance. + @param[in] CommandCode Physical presence operation value. + @param[in, out] PpiFlags The physical presence interface flag= s. + + @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presenc= e operation. + @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during se= nding command to TPM or + receiving response from = TPM. + @retval Others Return code from the TPM= device after command execution. + +**/ +UINT32 +ExecutePhysicalPresence ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN UINT32 CommandCode, + IN OUT EFI_PHYSICAL_PRESENCE_FLAGS *PpiFlags + ) +{ + BOOLEAN BoolVal; + UINT32 TpmResponse; + UINT32 InData[5]; + + switch (CommandCode) { + case PHYSICAL_PRESENCE_ENABLE: + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_PhysicalEnable, + 0, + NULL + ); + + case PHYSICAL_PRESENCE_DISABLE: + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_PhysicalDisable, + 0, + NULL + ); + + case PHYSICAL_PRESENCE_ACTIVATE: + BoolVal =3D FALSE; + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_PhysicalSetDeactivated, + sizeof (BoolVal), + &BoolVal + ); + + case PHYSICAL_PRESENCE_DEACTIVATE: + BoolVal =3D TRUE; + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_PhysicalSetDeactivated, + sizeof (BoolVal), + &BoolVal + ); + + case PHYSICAL_PRESENCE_CLEAR: + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_ForceClear, + 0, + NULL + ); + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESE= NCE_ENABLE, PpiFlags); + if (TpmResponse =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_ACTIVATE, PpiFlags); + } + return TpmResponse; + + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESE= NCE_DEACTIVATE, PpiFlags); + if (TpmResponse =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_DISABLE, PpiFlags); + } + return TpmResponse; + + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: + BoolVal =3D TRUE; + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_SetOwnerInstall, + sizeof (BoolVal), + &BoolVal + ); + + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: + BoolVal =3D FALSE; + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_SetOwnerInstall, + sizeof (BoolVal), + &BoolVal + ); + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: + // + // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_SET_OWNER_I= NSTALL_TRUE + // PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE will be executed after r= eboot + // + if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_ENABLE_ACTIVATE, PpiFlags); + PpiFlags->PPFlags |=3D TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } else { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_SET_OWNER_INSTALL_TRUE, PpiFlags); + PpiFlags->PPFlags &=3D ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } + return TpmResponse; + + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESE= NCE_SET_OWNER_INSTALL_FALSE, PpiFlags); + if (TpmResponse =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_DEACTIVATE_DISABLE, PpiFlags); + } + return TpmResponse; + + case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: + InData[0] =3D SwapBytes32 (TPM_SET_STCLEAR_DATA); // Capa= bilityArea + InData[1] =3D SwapBytes32 (sizeof(UINT32)); // SubC= apSize + InData[2] =3D SwapBytes32 (TPM_SD_DEFERREDPHYSICALPRESENCE); // SubC= ap + InData[3] =3D SwapBytes32 (sizeof(UINT32)); // SetV= alueSize + InData[4] =3D SwapBytes32 (1); // Unow= nedFieldUpgrade; bit0 + return TpmCommandNoReturnData ( + TcgProtocol, + TPM_ORD_SetCapability, + sizeof (UINT32) * 5, + InData + ); + + case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: + // + // TPM_SetOperatorAuth + // This command requires UI to prompt user for Auth data + // Here it is NOT implemented + // + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + + case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESE= NCE_CLEAR, PpiFlags); + if (TpmResponse =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_ENABLE_ACTIVATE, PpiFlags); + } + return TpmResponse; + + case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE: + PpiFlags->PPFlags &=3D ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISIO= N; + return 0; + + case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: + PpiFlags->PPFlags |=3D TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION; + return 0; + + case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: + PpiFlags->PPFlags &=3D ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR; + return 0; + + case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: + PpiFlags->PPFlags |=3D TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR; + return 0; + + case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE: + PpiFlags->PPFlags &=3D ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENA= NCE; + return 0; + + case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: + PpiFlags->PPFlags |=3D TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENAN= CE; + return 0; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: + // + // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR + // PHYSICAL_PRESENCE_CLEAR will be executed after reboot. + // + if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_ENABLE_ACTIVATE, PpiFlags); + PpiFlags->PPFlags |=3D TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } else { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_CLEAR, PpiFlags); + PpiFlags->PPFlags &=3D ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } + return TpmResponse; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: + // + // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR_ENABL= E_ACTIVATE + // PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE will be executed after re= boot. + // + if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) =3D=3D 0) { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_ENABLE_ACTIVATE, PpiFlags); + PpiFlags->PPFlags |=3D TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } else { + TpmResponse =3D ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRE= SENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags); + PpiFlags->PPFlags &=3D ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; + } + return TpmResponse; + + default: + ; + } + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; +} + + +/** + Read the specified key for user confirmation. + + @param[in] CautionKey If true, F12 is used as confirm key; + If false, F10 is used as confirm key. + + @retval TRUE User confirmed the changes by input. + @retval FALSE User discarded the changes or device error. + +**/ +BOOLEAN +ReadUserKey ( + IN BOOLEAN CautionKey + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + UINT16 InputKey; + UINTN Index; + + InputKey =3D 0; + do { + Status =3D gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (Status =3D=3D EFI_NOT_READY) { + gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); + continue; + } + + if (Status =3D=3D EFI_DEVICE_ERROR) { + return FALSE; + } + + if (Key.ScanCode =3D=3D SCAN_ESC) { + InputKey =3D Key.ScanCode; + } + if ((Key.ScanCode =3D=3D SCAN_F10) && !CautionKey) { + InputKey =3D Key.ScanCode; + } + if ((Key.ScanCode =3D=3D SCAN_F12) && CautionKey) { + InputKey =3D Key.ScanCode; + } + } while (InputKey =3D=3D 0); + + if (InputKey !=3D SCAN_ESC) { + return TRUE; + } + + return FALSE; +} + +/** + The constructor function register UNI strings into imageHandle. + + It will ASSERT() if that operation fails and it will always return EFI_S= UCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor successfully added string package. + @retval Other value The constructor can't add string package. + +**/ +EFI_STATUS +EFIAPI +TcgPhysicalPresenceLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + mPpStringPackHandle =3D HiiAddPackages (&gEfiPhysicalPresenceGuid, Image= Handle, TcgPhysicalPresenceLibQemuStrings, NULL); + ASSERT (mPpStringPackHandle !=3D NULL); + + return EFI_SUCCESS; +} + +/** + Display the confirm text and get user confirmation. + + @param[in] TpmPpCommand The requested TPM physical presence command. + + @retval TRUE The user has confirmed the changes. + @retval FALSE The user doesn't confirm the changes. +**/ +BOOLEAN +UserConfirm ( + IN UINT32 TpmPpCommand + ) +{ + CHAR16 *ConfirmText; + CHAR16 *TmpStr1; + CHAR16 *TmpStr2; + UINTN BufSize; + BOOLEAN CautionKey; + UINT16 Index; + CHAR16 DstStr[81]; + + TmpStr2 =3D NULL; + CautionKey =3D FALSE; + BufSize =3D CONFIRM_BUFFER_SIZE; + ConfirmText =3D AllocateZeroPool (BufSize); + ASSERT (ConfirmText !=3D NULL); + + switch (TpmPpCommand) { + case PHYSICAL_PRESENCE_ENABLE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE)= ); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_DISABLE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE= )); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_ACTIVATE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVAT= E)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_DEACTIVATE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIV= ATE)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_CLEAR: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize= / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_= ACTIVATE)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIV= ATE_DISABLE)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OF= F)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_T= AKE_OWNERSHIP)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLO= W_TAKE_OWNERSHIP)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON= )); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OF= F)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OF= F)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED= _FIELD_UPGRADE)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE= _HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _MAINTAIN)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: + // + // TPM_SetOperatorAuth + // This command requires UI to prompt user for Auth data + // Here it is NOT implemented + // + break; + + case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_T= URN_ON)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR_CONT)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_= PROVISION)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_= KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_= INFO)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CL= EAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize= / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_= INFO)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_= MAINTAIN)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _MAINTAIN)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_= INFO)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_= ACTIVATE_CLEAR)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize= / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: + CautionKey =3D TRUE; + TmpStr2 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_= ACTIVATE_CLEAR_ENABLE_ACTIVATE)); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_ST= R)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON= )); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING= _CLEAR_CONT)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION= _KEY)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + break; + + default: + ; + } + + if (TmpStr2 =3D=3D NULL) { + FreePool (ConfirmText); + return FALSE; + } + + // Console for user interaction + // We need to connect all trusted consoles for TCG PP. Here we treat all= consoles in OVMF to be trusted consoles. + EfiBootManagerConnectAllDefaultConsoles (); + + TmpStr1 =3D PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY)= ); + BufSize -=3D StrSize (ConfirmText); + UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, Tmp= Str2); + + DstStr[80] =3D L'\0'; + for (Index =3D 0; Index < StrLen (ConfirmText); Index +=3D 80) { + StrnCpyS(DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Inde= x, sizeof (DstStr) / sizeof (CHAR16) - 1); + Print (DstStr); + } + + FreePool (TmpStr1); + FreePool (TmpStr2); + FreePool (ConfirmText); + + if (ReadUserKey (CautionKey)) { + return TRUE; + } + + return FALSE; +} + +/** + Check if there is a valid physical presence command request. Also update= s parameter value + to whether the requested physical presence command already confirmed by = user + + @param[in] TcgPpData EFI TCG Physical Presence request data. + @param[in] Flags The physical presence interface flags. + @param[out] RequestConfirmed If the physical presence operation comm= and required user confirm from UI. + True, it indicates the command doesn't = require user confirm, or already confirmed + in last boot cycle by user. + False, it indicates the command need us= er confirm from UI. + + @retval TRUE Physical Presence operation command is valid. + @retval FALSE Physical Presence operation command is invalid. + +**/ +BOOLEAN +HaveValidTpmRequest ( + IN EFI_PHYSICAL_PRESENCE *TcgPpData, + IN EFI_PHYSICAL_PRESENCE_FLAGS Flags, + OUT BOOLEAN *RequestConfirmed + ) +{ + BOOLEAN IsRequestValid; + + *RequestConfirmed =3D FALSE; + + switch (TcgPpData->PPRequest) { + case PHYSICAL_PRESENCE_NO_ACTION: + *RequestConfirmed =3D TRUE; + return TRUE; + case PHYSICAL_PRESENCE_ENABLE: + case PHYSICAL_PRESENCE_DISABLE: + case PHYSICAL_PRESENCE_ACTIVATE: + case PHYSICAL_PRESENCE_DEACTIVATE: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: + case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: + case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: + if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) = !=3D 0) { + *RequestConfirmed =3D TRUE; + } + break; + + case PHYSICAL_PRESENCE_CLEAR: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: + if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) !=3D= 0) { + *RequestConfirmed =3D TRUE; + } + break; + + case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: + if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE= ) !=3D 0) { + *RequestConfirmed =3D TRUE; + } + break; + + case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: + if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) !=3D= 0 && (Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) !=3D = 0) { + *RequestConfirmed =3D TRUE; + } + break; + + case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE: + case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: + case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE: + *RequestConfirmed =3D TRUE; + break; + + case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: + case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: + case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: + break; + + default: + if (TcgPpData->PPRequest >=3D TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_= OPERATION) { + IsRequestValid =3D FALSE; // vendor-specifc commands are not suppo= rted + if (!IsRequestValid) { + return FALSE; + } else { + break; + } + } else { + // + // Wrong Physical Presence command + // + return FALSE; + } + } + + if ((Flags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) !=3D 0) { + // + // It had been confirmed in last boot, it doesn't need confirm again. + // + *RequestConfirmed =3D TRUE; + } + + // + // Physical Presence command is correct + // + return TRUE; +} + + +/** + Check and execute the requested physical presence command. + + Caution: This function may receive untrusted input. + TcgPpData variable is external input, so this function will validate + its data structure to be valid value. + + @param[in] TcgProtocol EFI TCG Protocol instance. + @param[in] TcgPpData Point to the physical presence NV variab= le. + @param[in] Flags The physical presence interface flags. + +**/ +STATIC +VOID +ExecutePendingTpmRequest ( + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN EFI_PHYSICAL_PRESENCE_FLAGS Flags + ) +{ + EFI_STATUS Status; + BOOLEAN RequestConfirmed; + EFI_PHYSICAL_PRESENCE TcgPpData; + EFI_PHYSICAL_PRESENCE_FLAGS NewFlags; + + DEBUG ((DEBUG_INFO, "[TPMPP] Flags=3D0x%x, PPRequest=3D0x%x\n", Flags.PP= Flags, mPpi->Request)); + + TcgPpData.PPRequest =3D (UINT8)mPpi->Request; + + if (!HaveValidTpmRequest(&TcgPpData, Flags, &RequestConfirmed)) { + // + // Invalid operation request. + // + mPpi->Response =3D TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + mPpi->LastRequest =3D mPpi->Request; + mPpi->Request =3D TCG_PHYSICAL_PRESENCE_NO_ACTION; + mPpi->RequestParameter =3D 0; + return; + } + + if (!RequestConfirmed) { + // + // Print confirm text and wait for approval. + // + RequestConfirmed =3D UserConfirm (mPpi->Request); + } + + // + // Execute requested physical presence command + // + mPpi->Response =3D TCG_PP_OPERATION_RESPONSE_USER_ABORT; + NewFlags =3D Flags; + if (RequestConfirmed) { + mPpi->Response =3D ExecutePhysicalPresence (TcgProtocol, mPpi->Request= , &NewFlags); + } + + // + // Save the flags if it is updated. + // + if (CompareMem (&Flags, &NewFlags, sizeof(EFI_PHYSICAL_PRESENCE_FLAGS)) = !=3D 0) { + Status =3D gRT->SetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE= _ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (EFI_PHYSICAL_PRESENCE_FLAGS), + &NewFlags + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // Update the flags for the commands following PPFlags changes + // + QemuTpmInitPPIFunc(NewFlags); + DEBUG ((DEBUG_INFO, "[TPMPP] New PPFlags =3D 0x%x\n", NewFlags.PPFlags= )); + } + + // + // Clear request + // + if ((NewFlags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) =3D=3D 0) { + mPpi->LastRequest =3D mPpi->Request; + mPpi->Request =3D PHYSICAL_PRESENCE_NO_ACTION; + mPpi->RequestParameter =3D 0; + } + + if (mPpi->Response =3D=3D TCG_PP_OPERATION_RESPONSE_USER_ABORT) { + return; + } + + // + // Reset system to make new TPM settings in effect + // + switch (mPpi->LastRequest) { + case PHYSICAL_PRESENCE_ACTIVATE: + case PHYSICAL_PRESENCE_DEACTIVATE: + case PHYSICAL_PRESENCE_CLEAR: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: + case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: + case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: + case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: + case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: + break; + default: + if (mPpi->Request !=3D TCG_PHYSICAL_PRESENCE_NO_ACTION) { + break; + } + return; + } + + Print (L"Rebooting system to make TPM settings in effect\n"); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + ASSERT (FALSE); +} + +/** + Check and execute the pending TPM request and Lock TPM. + + The TPM request may come from OS or BIOS. This API will display request = information and wait + for user confirmation if TPM request exists. The TPM request will be sen= t to TPM device after + the TPM request is confirmed, and one or more reset may be required to m= ake TPM request to + take effect. At last, it will lock TPM to prevent TPM state change by ma= lware. + + This API should be invoked after console in and console out are all read= y as they are required + to display request information and get user input to confirm the request= . This API should also + be invoked as early as possible as TPM is locked in this function. + +**/ +VOID +EFIAPI +TcgPhysicalPresenceLibProcessRequest ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN LifetimeLock; + BOOLEAN CmdEnable; + UINTN DataSize; + EFI_TCG_PROTOCOL *TcgProtocol; +// EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; + EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags; + + TcgPhysicalPresenceLibConstructor(gImageHandle, NULL); + + Status =3D QemuTpmInitPPI (); + if (EFI_ERROR (Status)) { + return ; + } + + DEBUG ((DEBUG_INFO, "[TPMPP] Detected a TPM 1.2\n")); + + // + // Check S4 resume + // + if (GetBootModeHob () =3D=3D BOOT_ON_S4_RESUME) { + DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n")); + return ; + } + + Status =3D gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&Tc= gProtocol); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Initialize physical presence flags. + // + DataSize =3D sizeof (EFI_PHYSICAL_PRESENCE_FLAGS); + Status =3D gRT->GetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + PpiFlags.PPFlags =3D TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION; + Status =3D gRT->SetVariable ( + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE= _ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (EFI_PHYSICAL_PRESENCE_FLAGS), + &PpiFlags + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM] Set physical presence flag failed, Statu= s =3D %r\n", Status)); + return ; + } + } + DEBUG ((DEBUG_INFO, "[TPM] PpiFlags =3D %x\n", PpiFlags.PPFlags)); + + // + // This flags variable controls whether physical presence is required fo= r TPM command. + // It should be protected from malicious software. We set it as read-onl= y variable here. + // +#if 0 + Status =3D gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (= VOID **)&VariableLockProtocol); + if (!EFI_ERROR (Status)) { + Status =3D VariableLockProtocol->RequestToLock ( + VariableLockProtocol, + PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiPhysicalPresenceGuid + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM] Error when lock variable %s, Status =3D = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status)); + ASSERT_EFI_ERROR (Status); + } + } +#endif + + QemuTpmInitPPIFunc(PpiFlags); + + DEBUG ((DEBUG_INFO, "[TPMPP] Flags=3D0x%x, PPRequest=3D0x%x\n", PpiFlags= .PPFlags, mPpi->Request)); + + if (mPpi->Request =3D=3D PHYSICAL_PRESENCE_NO_ACTION) { + // + // No operation request + // + return; + } + + Status =3D GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable); + if (EFI_ERROR (Status)) { + return ; + } + + if (!CmdEnable) { + if (LifetimeLock) { + // + // physicalPresenceCMDEnable is locked, can't execute physical prese= nce command. + // + return ; + } + Status =3D TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD= _ENABLE); + if (EFI_ERROR (Status)) { + return ; + } + } + + // + // Set operator physical presence flags + // + Status =3D TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESE= NT); + if (EFI_ERROR (Status)) { + return; + } + + // + // Execute pending TPM request. + // + ExecutePendingTpmRequest (TcgProtocol, PpiFlags); + DEBUG ((DEBUG_INFO, "[TPMPP] PPResponse =3D %x\n", mPpi->Response)); + + // + // Lock physical presence. + // + TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM= _PHYSICAL_PRESENCE_LOCK); +} + +/** + The handler for TPM physical presence function: + Submit TPM Operation Request to Pre-OS Environment and + Submit TPM Operation Request to Pre-OS Environment 2. + + Caution: This function may receive untrusted input. + + @param[in] OperationRequest TPM physical presence operation request. + + @return Return Code for Submit TPM Operation Request to Pre-OS Environme= nt and + Submit TPM Operation Request to Pre-OS Environment 2. +**/ +UINT32 +EFIAPI +TcgPhysicalPresenceLibSubmitRequestToPreOSFunction ( + IN UINT32 OperationRequest + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "[TPMPP] SubmitRequestToPreOSFunction, Request =3D %= x\n", OperationRequest)); + + Status =3D QemuTpmInitPPI (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "[TPMPP] no PPI\n")); + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE; + } + + mPpi->Request =3D OperationRequest; + + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS; +} diff --git a/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPrese= nceLib.inf b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPrese= nceLib.inf new file mode 100644 index 0000000000..b239c0eb87 --- /dev/null +++ b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcgPhysicalPresenceLib.= inf @@ -0,0 +1,64 @@ +## @file +# Executes TPM 1.2 requests from OS or BIOS +# +# This library will check and execute TPM 1.2 request from OS or +# BIOS. The request may ask for user confirmation before +# execution. It is a clone of +# "SecurityPkg/Library/DxeTcgPhysicalPresenceLib" +# +# Caution: This module requires additional review when modified. +# This driver will have external input - variable. +# This external input must be validated carefully to avoid security issue. +# +# Copyright (C) 2021, IBM Corporation +# Copyright (C) 2018, Red Hat, Inc. +# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D TcgPhysicalPresenceLibQemu + FILE_GUID =3D DA5A2055-ACD6-49A1-8277-857f3A47BB0C + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TcgPhysicalPresenceLib|DXE_DRIVER DXE= _RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + DxeTcgPhysicalPresenceLib.c + PhysicalPresenceStrings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + DxeServicesTableLib + HiiLib + HobLib + MemoryAllocationLib + PrintLib + QemuFwCfgLib + Tpm2CommandLib + UefiBootManagerLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiTcgProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + ## SOMETIMES_CONSUMES ## HII + gEfiPhysicalPresenceGuid diff --git a/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/PhysicalPresenceStr= ings.uni b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/PhysicalPresenceStrin= gs.uni new file mode 100644 index 0000000000..9d17432ef8 --- /dev/null +++ b/OvmfPkg/Library/TcgPhysicalPresenceLibQemu/PhysicalPresenceStrings.uni @@ -0,0 +1,46 @@ +/** @file + String definitions for TPM 1.2 physical presence confirm text. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#langdef en-US "English" + +#string TPM_HEAD_STR #language en-US "A configuration = change was requested to %s this computer's TPM (Trusted Platform Module)\n\= n" +#string TPM_PPI_HEAD_STR #language en-US "A configuration = change was requested to allow the Operating System to %s the computer's TPM= (Trusted Platform Module) without asking for user confirmation in the futu= re.\n\n" +#string TPM_UPGRADE_HEAD_STR #language en-US "A configuration = change was requested to %s to the TPM's (Trusted Platform Module) firmware.= \n\n" + +#string TPM_ACCEPT_KEY #language en-US "Press F10 " +#string TPM_CAUTION_KEY #language en-US "Press F12 " +#string TPM_REJECT_KEY #language en-US "to %s the TPM \n= Press ESC to reject this change request and continue\n" + +#string TPM_ENABLE #language en-US "enable" +#string TPM_DISABLE #language en-US "disable" +#string TPM_ACTIVATE #language en-US "activate" +#string TPM_DEACTIVATE #language en-US "deactivate" +#string TPM_CLEAR #language en-US "clear" +#string TPM_ENABLE_ACTIVATE #language en-US "enable and activ= ate" +#string TPM_DEACTIVATE_DISABLE #language en-US "deactivate and d= isable" +#string TPM_ALLOW_TAKE_OWNERSHIP #language en-US "allow a user to = take ownership of" +#string TPM_DISALLOW_TAKE_OWNERSHIP #language en-US "disallow a user = to take ownership of" +#string TPM_TURN_ON #language en-US "enable, activate= , and allow a user to take ownership of" +#string TPM_TURN_OFF #language en-US "deactivate, disa= ble, and disallow a user to take ownership of" +#string TPM_CLEAR_TURN_ON #language en-US "clear, enable, a= nd activate" +#string TPM_ENABLE_ACTIVATE_CLEAR #language en-US "enable, activate= and clear" +#string TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE #language en-US = "enable, activate, clear, enable, and activate" +#string TPM_UNOWNED_FIELD_UPGRADE #language en-US "allow field upgr= ade" + +#string TPM_NO_PPI_PROVISION #language en-US "provision" +#string TPM_NO_PPI_MAINTAIN #language en-US "maintain" +#string TPM_NO_PPI_INFO #language en-US "to approve futur= e Operating System requests " + +#string TPM_WARNING_MAINTAIN #language en-US "WARNING: Allowin= g changes to the TPM's firmware may affect the operation of the TPM and may= erase information stored on the TPM.\nYou may lose all created keys and ac= cess to data encrypted by these keys.\n\n" +#string TPM_WARNING #language en-US "WARNING: Doing s= o might prevent security applications that rely on the TPM from functioning= as expected\n\n" +#string TPM_WARNING_CLEAR #language en-US "WARNING: Clearin= g erases information stored on the TPM. You will lose all created keys and = access to data encrypted by these keys. " +#string TPM_WARNING_CLEAR_CONT #language en-US "Take ownership a= s soon as possible after this step.\n\n" +#string TPM_NOTE_OFF #language en-US "NOTE: This actio= n will turn off the TPM\n\n" +#string TPM_NOTE_ON #language en-US "NOTE: This actio= n will turn on the TPM\n\n" +#string TPM_NOTE_CLEAR #language en-US "NOTE: This actio= n does not clear the TPM, but by approving this configuration change, futur= e actions to clear the TPM will not require user confirmation.\n\n" diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 340d83f794..85b563783e 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -86,6 +86,9 @@ # QemuLoadImageLib|Include/Library/QemuLoadImageLib.h =20 + ## @libraryclass QEMU Physical Presence Interface + TcgPhysicalPresenceLibQemu|Include/Library/QemuPPI.h + ## @libraryclass Serialize (and deserialize) variables # SerializeVariablesLib|Include/Library/SerializeVariablesLib.h diff --git a/OvmfPkg/OvmfTpmLibs.dsc.inc b/OvmfPkg/OvmfTpmLibs.dsc.inc index 418747b134..24b54861ed 100644 --- a/OvmfPkg/OvmfTpmLibs.dsc.inc +++ b/OvmfPkg/OvmfTpmLibs.dsc.inc @@ -5,6 +5,9 @@ !if $(TPM2_ENABLE) =3D=3D TRUE !if $(TPM1_ENABLE) =3D=3D TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf + TcgPhysicalPresenceLib|OvmfPkg/Library/TcgPhysicalPresenceLibQemu/DxeTcg= PhysicalPresenceLib.inf +!else + TcgPhysicalPresenceLib|OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcg= PhysicalPresenceLib.inf !endif Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeT= cg2PhysicalPresenceLib.inf @@ -13,4 +16,5 @@ !else Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeT= cg2PhysicalPresenceLib.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf + TcgPhysicalPresenceLib|OvmfPkg/Library/TcgPhysicalPresenceLibNull/DxeTcg= PhysicalPresenceLib.inf !endif diff --git a/SecurityPkg/Include/Library/TcgPhysicalPresenceLib.h b/Securit= yPkg/Include/Library/TcgPhysicalPresenceLib.h index 9826a79742..6877c08e74 100644 --- a/SecurityPkg/Include/Library/TcgPhysicalPresenceLib.h +++ b/SecurityPkg/Include/Library/TcgPhysicalPresenceLib.h @@ -45,4 +45,43 @@ TcgPhysicalPresenceLibNeedUserConfirm( VOID ); =20 +/** + The handler for TPM physical presence function: + Return TPM Operation Response to OS Environment. + + This API should be invoked in OS runtime phase to interface with ACPI me= thod. + + @param[out] MostRecentRequest Most recent operation request. + @param[out] Response Response to the most recent operation = request. + + @return Return Code for Return TPM Operation Response to OS Environment. +**/ +UINT32 +EFIAPI +Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction ( + OUT UINT32 *MostRecentRequest, + OUT UINT32 *Response + ); + +/** + The handler for TPM physical presence function: + Submit TPM Operation Request to Pre-OS Environment and + Submit TPM Operation Request to Pre-OS Environment 2. + + This API should be invoked in OS runtime phase to interface with ACPI me= thod. + + Caution: This function may receive untrusted input. + + @param[in] OperationRequest TPM physical presence operation request. + @param[in] RequestParameter TPM physical presence operation request= parameter. + + @return Return Code for Submit TPM Operation Request to Pre-OS Environme= nt and + Submit TPM Operation Request to Pre-OS Environment 2. +**/ +UINT32 +EFIAPI +TcgPhysicalPresenceLibSubmitRequestToPreOSFunction ( + IN UINT32 OperationRequest + ); + #endif diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf b/SecurityPkg/Tc= g/TcgConfigDxe/TcgConfigDxe.inf index 24428e050c..b2f36fdbb2 100644 --- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf +++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf @@ -47,6 +47,7 @@ HiiLib PcdLib PrintLib + TcgPhysicalPresenceLib Tpm12DeviceLib =20 [Guids] --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#82716): https://edk2.groups.io/g/devel/message/82716 Mute This Topic: https://groups.io/mt/86608983/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-