From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 44A27AC0CA9 for ; Fri, 26 Jan 2024 06:02:52 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=K34gedjD+MbP/PvMNGpXRrkWS4JW39lsLMPRFMO7vMI=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1706248971; v=1; b=wjB5LPUc8BoIenvuAAlkOeKxYBAnCFVJ0wLoZ18AwP4dP4cu/Qy+AHfq8oAP+hKkNLhhSzVr UveSdkKbrCrRvHRlmkwla7WcZIwKF0kZQiUIpzjOU8dF7hPWvhXQU0uAfiONFlo2HxCIn/KEL1W k+nCjtSkklJAWym6s3ggAPYU= X-Received: by 127.0.0.2 with SMTP id jKGzYY7687511x8ckbgtKIeQ; Thu, 25 Jan 2024 22:02:51 -0800 X-Received: from NAM02-BN1-obe.outbound.protection.outlook.com (NAM02-BN1-obe.outbound.protection.outlook.com [40.107.212.82]) by mx.groups.io with SMTP id smtpd.web11.9701.1706248969794411221 for ; Thu, 25 Jan 2024 22:02:50 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=esF5iM+CgIucbwhtwAUxmtqFmOzxakEatX6WhK2VUrM4hCAm1Alkxk92s7yiyvg0xkb12ShiYzu55aDvmuWJ4tPr3OeRENZXggWQGNctrE+WeEc5iTYfDL4WD+UbFCCBOw9GAdZxiq838OfeotEoyFmrPiB+VA1fPwq5GsD63s1+3IrG6SzgsRCWf7Ht3rm1B6vHj3jMm4nW+vERaxGs7QfObyHwJw+usNPI6sq1db3u/N66sDjnV2oR7HnnhZr2tR4b9pmqpursmd0n++ddvCk/DdNdqXcOHKDWI+1ZQPyiFSlQKCJ58S9OCJ3zfkbPunY/tEbuveGF9EY38P2P+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OooHtyOYv8sMAojjRgL2eSjbxjwf8p88GhqiLcaGgE0=; b=DxBJ+FeYOtCkSzvkZal+eHQ3FLWPz8cMKSSyNQrSh4/nyClHtnvQDNh0X7BBAGfST8laFgC5eO7dvOWrDfk6vZUBbBNitKlnhDiNQ6oKrDWlPP6ZLbEUuP91Ap5lWtvVrwN+4sL7ENaz/V/el3rpa7p2kt7TBEj+oM8v+MUpYDtg304yf3xyjxlFNe93+5/LsRPiAu1TWTCLKBjbNUD0y3tzCTvcT/SXmx0uWo8yA3DpyBSIKx5hRy3nIWXj2uZQv6/bKGPXzbQAlMMuaW1UfUWz7FNPraNJF4SVGbbhKCnS7GSIZyW8nd3GM0/63dor2/AYFJMNab/e+SNLEcwTJg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) X-Received: from DS7PR03CA0350.namprd03.prod.outlook.com (2603:10b6:8:55::27) by BY5PR12MB5510.namprd12.prod.outlook.com (2603:10b6:a03:1d2::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.27; Fri, 26 Jan 2024 06:02:42 +0000 X-Received: from DS2PEPF00003440.namprd02.prod.outlook.com (2603:10b6:8:55:cafe::a8) by DS7PR03CA0350.outlook.office365.com (2603:10b6:8:55::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.27 via Frontend Transport; Fri, 26 Jan 2024 06:02:42 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by DS2PEPF00003440.mail.protection.outlook.com (10.167.18.43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7228.16 via Frontend Transport; Fri, 26 Jan 2024 06:02:41 +0000 X-Received: from SHA-LX-MINGXZHA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Fri, 26 Jan 2024 00:02:38 -0600 From: "Zhai, MingXin (Duke) via groups.io" To: CC: Eric Xing , Duke Zhai , Igniculus Fu , Abner Chang Subject: [edk2-devel] [PATCH V2 20/32] AMD/VanGoghBoard: Check in FTPM module Date: Fri, 26 Jan 2024 14:00:38 +0800 Message-ID: <20240126060050.1725-21-duke.zhai@amd.com> In-Reply-To: <20240126060050.1725-1-duke.zhai@amd.com> References: <20240126060050.1725-1-duke.zhai@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS2PEPF00003440:EE_|BY5PR12MB5510:EE_ X-MS-Office365-Filtering-Correlation-Id: f4eb8be0-6896-437f-329c-08dc1e346886 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: Zp/HnvXtYZP9aa6F1dQ6G0/bjyF2c/zA4Ulp0aNVQOM/74vF3QlnnCWVbrEQhUQL8xUQWcprH9G/SHZ+EWHd9ZrTh4co6WwkPo3BLNW8R2YV5oFbFPSCXYp6Qn9lOpBbf/NytSlHURPJR1WBpxbg992ZtgSe11xSsZstMP4kzpOfiiO3n91ZxgaulSMpONLrE6lL9VlyADQYZyHtY4knbSKGZ0GKJWCapRE+Tn21z7QobsCaXwxyw64CqpVFt4Oz8p6QaJaqQcD6ydnyODU2KRKrAamLohlLrMrte3Uh9SlU5AOO8sOmDfQ8qvToGcAOanUFVkWI5oTmBGrNibeVmxSCtfkVCGQcc5F5NiVRPHHaUwx8EODOmJDtwiyb8bW3iPDEduDA3mpEAJWNGYAzsGWZxAGQmJ/50f0VVCVwXI8/YRQpRbeAlg6L1W2q8EufLvvb0ifx7mZyoVU/HcmpuHAscz5OlttxGs3zbpiRyESBaMc35NBlMfL5wn41F3RtlrlQbCUA0TGw3hzREpOiHhO6lyeE9l3hHumqHFtRCLlKBXZJiLr7bC+vHVRKcX/EhJd04gFI75I4wpu+S8+soNhVsyKMV4+DCDctZuR+SCMwb1KzuulqEGZ6x914N71+bfHy1QaytMx5GT1DcjGPcLTZ72c0dJONom2JB2u4Prur5wlTTgeC6CCcHYu4I8MZ7hFJjbA3O3PHIUQ2UJh0v/Xu5bWn2lSHB2bA8q6MhaOTeMMVvbhvg1vVvpaWwNmXfPO5fKJYnEsn2PGYT+mdO2qTdz9JtdS4YVZwZw0VOfU= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2024 06:02:41.9588 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f4eb8be0-6896-437f-329c-08dc1e346886 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS2PEPF00003440.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR12MB5510 Precedence: Bulk 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,duke.zhai@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: KQOb71c4Na7ZfcQidvKgMcFXx7686176AA= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=wjB5LPUc; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}"); dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io From: Duke Zhai BZ #:4640 In V2: Improve coding style. 1.Remove the leading underscore and use double underscore at trailing in = C header files. 2.Remove old tianocore licenses and redundant license description. 3.Improve coding style. For example: remove space between @param. In V1: This driver implements TPM 2.0 definition block in ACPI table and registers SMI callback functions for Tcg2 physical presence and MemoryClear to handle the requests from ACPI method. Signed-off-by: Ken Yao Cc: Eric Xing Cc: Duke Zhai Cc: Igniculus Fu Cc: Abner Chang --- .../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c | 113 ++ .../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf | 48 + .../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c | 141 ++ .../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf | 47 + .../AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c | 108 ++ .../Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf | 43 + .../Tpm2InstanceLibAmdFTpm.inf | 53 + .../Tpm2InstanceLibAmdFTpmDxe.c | 109 ++ .../Tpm2InstanceLibAmdFTpmPei.c | 153 ++ .../DxeTcg2PhysicalPresenceLib.c | 1269 +++++++++++++++++ .../DxeTcg2PhysicalPresenceLib.inf | 68 + .../DxeTcg2PhysicalPresenceLib.uni | 22 + .../PhysicalPresenceStrings.uni | 57 + .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c | 854 +++++++++++ .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h | 123 ++ .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf | 92 ++ .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni | 35 + .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni | 15 + .../Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl | 408 ++++++ .../Tcg/Tcg2Config/Tcg2ConfigNvData.h | 124 ++ .../Tcg/Tcg2Config/Tcg2ConfigPei.inf | 77 + .../Tcg/Tcg2Config/Tcg2ConfigPei.uni | 14 + .../Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni | 15 + .../Tcg/Tcg2Config/Tcg2ConfigPeim.c | 148 ++ .../SecurityPkg/Tcg/Tcg2Config/TpmDetection.c | 99 ++ 25 files changed, 4235 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Lib= rary/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /AmdFtpm/FtpmTcg2Smm/Tpm.asl create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/Tcg2ConfigNvData.h create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/Tcg2ConfigPei.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/Tcg2ConfigPei.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/Tcg2ConfigPeiExtra.uni create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/Tcg2ConfigPeim.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg= /Tcg2Config/TpmDetection.c diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/O= verride/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibF= tpm.c new file mode 100644 index 0000000000..fe359cdc28 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/D= xeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c @@ -0,0 +1,113 @@ +/** @file + This library is TPM2 device router. Platform can register multi TPM2 ins= tance to it + via PcdTpmInstanceGuid. Platform need make choice that which one will be= final one. + At most one TPM2 instance can be finally registered, and other will retu= rn unsupported. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +PSP_FTPM_PROTOCOL *PspFtpmProtocol; +extern EFI_GUID gAmdPspFtpmProtocolGuid; + +/** + The constructor function for this library. + + @param None + + @retval EFI_SUCCESS This library is ready for use. + +**/ +EFI_STATUS +EFIAPI +Tpm2DeviceLibConstructor ( + VOID + ) +{ + return gBS->LocateProtocol (&gAmdPspFtpmProtocolGuid, NULL, (VOID **)&Ps= pFtpmProtocol); +} + +/** + This service enables the sending of commands to the TPM2. + + @param[in] InputParameterBlockSize Size of the TPM2 input parameter bl= ock. + @param[in] InputParameterBlock Pointer to the TPM2 input parameter= block. + @param[in] OutputParameterBlockSize Size of the TPM2 output parameter b= lock. + @param[in] OutputParameterBlock Pointer to the TPM2 output paramete= r block. + + @retval EFI_SUCCESS The command byte stream was successfully = sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +Tpm2SubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if ((NULL =3D=3D InputParameterBlock) || (NULL =3D=3D OutputParameterBlo= ck) || (0 =3D=3D InputParameterBlockSize)) { + DEBUG ((DEBUG_ERROR, "Buffer =3D=3D NULL or InputParameterBlockSize = =3D=3D 0\n")); + Status =3D EFI_INVALID_PARAMETER; + return Status; + } + + Status =3D PspFtpmProtocol->Execute ( + PspFtpmProtocol, + (VOID *)InputParameterBlock, + InputParameterBlockSize, + (VOID *)OutputParameterBlock, + OutputParameterBlockSize + ); + + return Status; +} + +/** + This service requests use TPM2. + + @retval EFI_SUCCESS Get the control of TPM2 chip. + @retval EFI_NOT_FOUND TPM2 not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2RequestUseTpm ( + VOID + ) +{ + FTPM_INFO FtpmStatus; + + return PspFtpmProtocol->GetInfo (PspFtpmProtocol, &FtpmStatus); +} + +/** + This service register TPM2 device. + + @Param Tpm2Device TPM2 device + + @retval EFI_SUCCESS This TPM2 device is registered successfully= . + @retval EFI_UNSUPPORTED System does not support register this TPM2 = device. + @retval EFI_ALREADY_STARTED System already register this TPM2 device. +**/ +EFI_STATUS +EFIAPI +Tpm2RegisterTpm2DeviceLib ( + IN TPM2_DEVICE_INTERFACE *Tpm2Device + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard= /Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLi= bFtpm.inf new file mode 100644 index 0000000000..6708abdfce --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/D= xeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf @@ -0,0 +1,48 @@ +## @file +# Provides TPM 2.0 TIS functions +# +# This library is TPM 2.0 device router. Platform can register multi TPM = 2.0 instance to +# it via PcdTpmInstanceGuid. Platform need make choice that which one wil= l be final one. +# At most one TPM 2.0 instance can be finally registered, and other will = return unsupported. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tpm2DeviceLibFtpm + FILE_GUID =3D E98C81D3-B90D-4D28-AB48-A207C89D44C0 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Tpm2DeviceLib | DXE_DRIVER DXE_RUNTIM= E_DRIVER + CONSTRUCTOR =3D Tpm2DeviceLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources.common] + Tpm2DeviceLibFtpm.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + ChachaniBoardPkg/Project.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses] + BaseLib + DebugLib + +[Protocols] + gAmdPspFtpmProtocolGuid + +[Depex] + gAmdPspFtpmProtocolGuid \ No newline at end of file diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/O= verride/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibF= tpm.c new file mode 100644 index 0000000000..9e8cb5588d --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/P= eiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c @@ -0,0 +1,141 @@ +/** @file + This library is TPM2 device router. Platform can register multi TPM2 ins= tance to it + via PcdTpmInstanceGuid. Platform need make choice that which one will be= final one. + At most one TPM2 instance can be finally registered, and other will retu= rn unsupported. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** + The constructor function for this library. + + @param None + + @retval EFI_SUCCESS This library is ready for use. + +**/ + +extern EFI_GUID gAmdPspFtpmPpiGuid; + +EFI_STATUS +EFIAPI +Tpm2DeviceLibConstructor ( + VOID + ) +{ + PSP_FTPM_PPI *PspFtpmPpi; + + return (*GetPeiServicesTablePointer ())->LocatePpi ( + GetPeiServicesTablePointer ()= , + &gAmdPspFtpmPpiGuid, + 0, + NULL, + (VOID **)&PspFtpmPpi + ); +} + +/** + This service enables the sending of commands to the TPM2. + + @param[in] InputParameterBlockSize Size of the TPM2 input parameter bl= ock. + @param[in] InputParameterBlock Pointer to the TPM2 input parameter= block. + @param[in] OutputParameterBlockSize Size of the TPM2 output parameter b= lock. + @param[in] OutputParameterBlock Pointer to the TPM2 output paramete= r block. + + @retval EFI_SUCCESS The command byte stream was successfully = sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +Tpm2SubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if ((NULL =3D=3D InputParameterBlock) || (NULL =3D=3D OutputParameterBlo= ck) || (0 =3D=3D InputParameterBlockSize)) { + DEBUG ((DEBUG_ERROR, "Buffer =3D=3D NULL or InputParameterBlockSize = =3D=3D 0\n")); + Status =3D EFI_INVALID_PARAMETER; + return Status; + } + + PSP_FTPM_PPI *PspFtpmPpi; + + Status =3D (*GetPeiServicesTablePointer ())->LocatePpi ( + GetPeiServicesTablePointer = (), + &gAmdPspFtpmPpiGuid, + 0, + NULL, + (VOID **)&PspFtpmPpi + ); + if (!EFI_ERROR (Status)) { + Status =3D PspFtpmPpi->Execute ( + PspFtpmPpi, + (VOID *)InputParameterBlock, + InputParameterBlockSize, + (VOID *)OutputParameterBlock, + OutputParameterBlockSize + ); + } + + return Status; +} + +/** + This service requests use TPM2. + + @retval EFI_SUCCESS Get the control of TPM2 chip. + @retval EFI_NOT_FOUND TPM2 not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2RequestUseTpm ( + VOID + ) +{ + UINTN FtpmStatus; + PSP_FTPM_PPI *PspFtpmPpi; + EFI_STATUS Status =3D (*GetPeiServicesTablePointer ())->LocatePpi ( + GetPeiService= sTablePointer (), + &gAmdPspFtpmP= piGuid, + 0, + NULL, + (VOID **)&Psp= FtpmPpi + ); + + return Status || PspFtpmPpi->CheckStatus (PspFtpmPpi, &FtpmStatus); +} + +/** + This service register TPM2 device. + + @Param Tpm2Device TPM2 device + + @retval EFI_SUCCESS This TPM2 device is registered successfully= . + @retval EFI_UNSUPPORTED System does not support register this TPM2 = device. + @retval EFI_ALREADY_STARTED System already register this TPM2 device. +**/ +EFI_STATUS +EFIAPI +Tpm2RegisterTpm2DeviceLib ( + IN TPM2_DEVICE_INTERFACE *Tpm2Device + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard= /Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLi= bFtpm.inf new file mode 100644 index 0000000000..a38ada3efd --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/P= eiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf @@ -0,0 +1,47 @@ +## @file +# Provides TPM 2.0 TIS functions +# +# This library is TPM 2.0 device router. Platform can register multi TPM = 2.0 instance to +# it via PcdTpmInstanceGuid. Platform need make choice that which one wil= l be final one. +# At most one TPM 2.0 instance can be finally registered, and other will = return unsupported. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tpm2DeviceLibFtpm + FILE_GUID =3D 2E230843-274F-4C14-A4B5-46B6167E7A5C + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Tpm2DeviceLib | PEIM + CONSTRUCTOR =3D Tpm2DeviceLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources.common] + Tpm2DeviceLibFtpm.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + ChachaniBoardPkg/Project.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses] + BaseLib + DebugLib + +[Ppis] + gAmdPspFtpmPpiGuid + +[Depex] + gAmdPspFtpmPpiGuid \ No newline at end of file diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Overrid= e/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c new file mode 100644 index 0000000000..713c87a1ca --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/T= pm2DeviceLib/Tpm2DeviceLibFtpm.c @@ -0,0 +1,108 @@ +/** @file + This library is TPM2 TCG2 protocol lib. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +/** + The constructor function for this library. + + @param None + + @retval EFI_SUCCESS This library is ready for use. + +**/ +EFI_STATUS +EFIAPI +Tpm2DeviceLibConstructor ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + This service enables the sending of commands to the TPM2. + + @param[in] InputParameterBlockSize Size of the TPM2 input parameter bl= ock. + @param[in] InputParameterBlock Pointer to the TPM2 input parameter= block. + @param[in] OutputParameterBlockSize Size of the TPM2 output parameter b= lock. + @param[in] OutputParameterBlock Pointer to the TPM2 output paramete= r block. + + @retval EFI_SUCCESS The command byte stream was successfully = sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +Tpm2SubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + + if ((NULL =3D=3D InputParameterBlock) || (NULL =3D=3D OutputParameterBlo= ck) || (0 =3D=3D InputParameterBlockSize)) { + DEBUG ((DEBUG_ERROR, "Buffer =3D=3D NULL or InputParameterBlockSize = =3D=3D 0\n")); + Status =3D EFI_INVALID_PARAMETER; + return Status; + } + + Status =3D FtpmExecuteCommand ( + (VOID *)InputParameterBlock, + InputParameterBlockSize, + (VOID *)OutputParameterBlock, + OutputParameterBlockSize + ); + + return Status; +} + +/** + This service requests use TPM2. + + @retval EFI_SUCCESS Get the control of TPM2 chip. + @retval EFI_NOT_FOUND TPM2 not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +Tpm2RequestUseTpm ( + VOID + ) +{ + EFI_STATUS Status; + UINTN FtpmStatus; + + Status =3D FtpmGetInfo (&FtpmStatus); + return Status; +} + +/** + This service register TPM2 device. + + @Param Tpm2Device TPM2 device + + @retval EFI_SUCCESS This TPM2 device is registered successfully= . + @retval EFI_UNSUPPORTED System does not support register this TPM2 = device. + @retval EFI_ALREADY_STARTED System already register this TPM2 device. +**/ +EFI_STATUS +EFIAPI +Tpm2RegisterTpm2DeviceLib ( + IN TPM2_DEVICE_INTERFACE *Tpm2Device + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Overr= ide/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf new file mode 100644 index 0000000000..7e42703347 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/T= pm2DeviceLib/Tpm2DeviceLibFtpm.inf @@ -0,0 +1,43 @@ +## @file +# Provides function interfaces to communicate with TPM 2.0 device +# +# This library helps to use TPM 2.0 device in library function API +# based on TPM2 protocol. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tpm2DeviceLibFtpm + FILE_GUID =3D 1E0C813B-46F5-4578-AA2D-E0AFFD89F2F9 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Tpm2DeviceLib + CONSTRUCTOR =3D Tpm2DeviceLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources.common] + Tpm2DeviceLibFtpm.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + ChachaniBoardPkg/Project.dec + +[LibraryClasses] + BaseLib + DebugLib + AmdPspFtpmLib + +[Depex] + TRUE \ No newline at end of file diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf b/Platform/AMD/VanG= oghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/T= pm2InstanceLibAmdFTpm.inf new file mode 100644 index 0000000000..2b957fd942 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/T= pm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf @@ -0,0 +1,53 @@ +## @file +# AMD Ftpm 2.0 Instance Library Module INF file +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tpm2InstanceLibAmdFtpm + FILE_GUID =3D F1FA6737-93AC-4B72-8906-3EAE247CFF8D + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NULL + CONSTRUCTOR =3D Tpm2InstanceLibAmdFTpmConstructor + +[Sources.IA32] + Tpm2InstanceLibAmdFTpmPei.c + +[Sources.X64] + Tpm2InstanceLibAmdFTpmDxe.c + +[Packages] + MdePkg/MdePkg.dec + SecurityPkg/SecurityPkg.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses.X64] + UefiBootServicesTableLib + +[LibraryClasses.IA32] + PeiServicesLib + +[Protocols.X64] + gAmdPspFtpmProtocolGuid + +[Ppis.IA32] + gAmdPspFtpmPpiGuid + gAmdPspFtpmFactoryResetPpiGuid + +[Guids] + gEfiTpmDeviceInstanceNoneGuid + +[Pcd] + gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdPspSystemTpmConfig + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid + +[Depex.IA32] + TRUE + +[Depex.X64] + TRUE diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c b/Platform/AMD/Van= GoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/= Tpm2InstanceLibAmdFTpmDxe.c new file mode 100644 index 0000000000..af9bf81c18 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/T= pm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c @@ -0,0 +1,109 @@ +/** @file + Implements Tpm2InstanceLibAmdFTpmDxe.C + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +// gEfiTpmDeviceInstanceTpm20AmdFtpmGuid +#define TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM \ + {0x286bf25a, 0xc2c3, 0x408c, {0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, = 0x17}} + +PSP_FTPM_PROTOCOL *mfTpmProtocol =3D NULL; + +/** + This service enables the sending of commands to the FTPM. + + @param[in] InputParameterBlockSize Size of the FTPM input paramete= r block. + @param[in] InputParameterBlock Pointer to the FTPM input param= eter block. + @param[in,out] OutputParameterBlockSize Size of the FTPM output paramet= er block. + @param[in] OutputParameterBlock Pointer to the FTPM output para= meter block. + + @retval EFI_SUCCESS The command byte stream was successfully = sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +FTpmSubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ) +{ + return mfTpmProtocol->Execute (mfTpmProtocol, InputParameterBlock, Input= ParameterBlockSize, OutputParameterBlock, OutputParameterBlockSize); +} + +/** + This service requests use FTPM. + + @retval EFI_SUCCESS Get the control of FTPM chip. + @retval EFI_NOT_FOUND FTPM not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +FTpmRequestUseTpm ( + VOID + ) +{ + EFI_STATUS Status; + UINTN fTpmStatus; + + if ((PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_PSP_FTP= M) || + (PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_HSP_FTP= M)) + { + Status =3D mfTpmProtocol->CheckStatus (mfTpmProtocol, &fTpmStatus); + DEBUG ((DEBUG_INFO, "fTPM Status =3D %r\n", Status)); + return Status; + } + + return EFI_NOT_FOUND; +} + +TPM2_DEVICE_INTERFACE mFTpmInternalTpm2Device =3D { + TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM, + FTpmSubmitCommand, + FTpmRequestUseTpm, +}; + +/** + The function register FTPM instance. + + @retval EFI_SUCCESS FTPM instance is registered, or system dose not su= rpport registr FTPM instance +**/ +EFI_STATUS +EFIAPI +Tpm2InstanceLibAmdFTpmConstructor ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D gBS->LocateProtocol ( + &gAmdPspFtpmProtocolGuid, + NULL, + (VOID **)&mfTpmProtocol + ); + if (Status =3D=3D EFI_SUCCESS) { + Status =3D Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device); + if (Status =3D=3D EFI_UNSUPPORTED) { + // + // Unsupported means platform policy does not need this instance ena= bled. + // + return EFI_SUCCESS; + } + } + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Am= dFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c b/Platform/AMD/Van= GoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/= Tpm2InstanceLibAmdFTpmPei.c new file mode 100644 index 0000000000..35671644e2 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/T= pm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c @@ -0,0 +1,153 @@ +/** @file + Implements Tpm2InstanceLibAmdFTpmPei.C + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +// gEfiTpmDeviceInstanceTpm20AmdFtpmGuid +#define TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM \ + {0x286bf25a, 0xc2c3, 0x408c, {0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, = 0x17}} + +/** + * @brief gAmdFtpmFactoryResetPpiGuid callback, disable TPM + * + * @param PeiServices + * @param NotifyDesc + * @param InvokePpi + * @return EFI_STATUS + */ +EFI_STATUS +EFIAPI +AmdFtpmFactoryResetCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi + ) +{ + UINTN Size; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "AmdFtpmFactoryResetCallback\n")); + // gEfiTpmDeviceInstanceNoneGuid GUID value used for PcdTpmInstanceGuid = to indicate TPM is disabled. + Size =3D sizeof (gEfiTpmDeviceInstanceNoneGuid); + Status =3D PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstance= NoneGuid); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mAmdFtpmFactoryResetPpiCallback =3D { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINAT= E_LIST, + &gAmdPspFtpmFactoryResetPpiGuid, + AmdFtpmFactoryResetCallback +}; + +/** + This service enables the sending of commands to the FTPM. + + @param[in] InputParameterBlockSize Size of the FTPM input paramete= r block. + @param[in] InputParameterBlock Pointer to the FTPM input param= eter block. + @param[in,out] OutputParameterBlockSize Size of the FTPM output paramet= er block. + @param[in] OutputParameterBlock Pointer to the FTPM output para= meter block. + + @retval EFI_SUCCESS The command byte stream was successfully = sent to the device and a response was successfully received. + @retval EFI_DEVICE_ERROR The command was not successfully sent to = the device or a response was not successfully received from the device. + @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. +**/ +EFI_STATUS +EFIAPI +FTpmSubmitCommand ( + IN UINT32 InputParameterBlockSize, + IN UINT8 *InputParameterBlock, + IN OUT UINT32 *OutputParameterBlockSize, + IN UINT8 *OutputParameterBlock + ) +{ + PSP_FTPM_PPI *AmdFtpmPpi; + EFI_STATUS Status; + + Status =3D PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID **)= &AmdFtpmPpi); + if (Status =3D=3D EFI_SUCCESS) { + return AmdFtpmPpi->Execute (AmdFtpmPpi, InputParameterBlock, InputPara= meterBlockSize, OutputParameterBlock, OutputParameterBlockSize); + } + + return Status; +} + +/** + This service requests use FTPM. + + @retval EFI_SUCCESS Get the control of FTPM chip. + @retval EFI_NOT_FOUND FTPM not found. + @retval EFI_DEVICE_ERROR Unexpected device behavior. +**/ +EFI_STATUS +EFIAPI +FTpmRequestUseTpm ( + VOID + ) +{ + if ((PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_PSP_FTP= M) || + (PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_HSP_FTP= M)) + { + // @todo Test fTPM functionality + DEBUG ((DEBUG_INFO, "fTPM is used\n")); + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +TPM2_DEVICE_INTERFACE mFTpmInternalTpm2Device =3D { + TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM, + FTpmSubmitCommand, + FTpmRequestUseTpm, +}; + +/** + The function register FTPM instance. + + @retval EFI_SUCCESS FTPM instance is registered, or system dose not su= rpport registr FTPM instance +**/ +EFI_STATUS +EFIAPI +Tpm2InstanceLibAmdFTpmConstructor ( + VOID + ) +{ + EFI_STATUS Status; + PSP_FTPM_PPI *AmdFtpmPpi; + + if ((PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_PSP_FTP= M) || + (PcdGet8 (PcdAmdPspSystemTpmConfig) =3D=3D SYSTEM_TPM_CONFIG_HSP_FTP= M)) + { + // + // AMD HSP f-TPM for EDK2 Core Base, Get the HSP PSP TcgEvetLog before= BIOS + // + Status =3D PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID *= *)&AmdFtpmPpi); + if (Status =3D=3D EFI_SUCCESS) { + Status =3D Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device); + if (Status =3D=3D EFI_UNSUPPORTED) { + // + // Unsupported means platform policy does not need this instance e= nabled. + // + return EFI_SUCCESS; + } + } + + PeiServicesNotifyPpi (&mAmdFtpmFactoryResetPpiCallback); + } + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Dx= eTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c b/Platform/AMD/VanGog= hBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2= PhysicalPresenceLib.c new file mode 100644 index 0000000000..28b945fbba --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2Ph= ysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c @@ -0,0 +1,1269 @@ +/** @file + Execute pending TPM2 requests from OS or BIOS. + + 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. + + Tpm2ExecutePendingTpmRequest() will receive untrusted input and do valid= ation. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2013 - 2016, 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 mTcg2PpStringPackHandle; + +/** + Get string by string id from HII Interface. + + @param[in] Id String ID. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +Tcg2PhysicalPresenceGetStringById ( + IN EFI_STRING_ID Id + ) +{ + return HiiGetString (mTcg2PpStringPackHandle, Id, NULL); +} + +/** + Send ClearControl and Clear command to TPM. + + @param[in] PlatformAuth platform auth value. NULL means no platfor= m auth change. + + @retval EFI_SUCCESS Operation completed successfully. + @retval EFI_TIMEOUT The register can't run into the expected s= tatus in time. + @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small. + @retval EFI_DEVICE_ERROR Unexpected device behavior. + +**/ +EFI_STATUS +EFIAPI +Tpm2CommandClear ( + IN TPM2B_AUTH *PlatformAuth OPTIONAL + ) +{ + EFI_STATUS Status; + TPMS_AUTH_COMMAND *AuthSession; + TPMS_AUTH_COMMAND LocalAuthSession; + + if (PlatformAuth =3D=3D NULL) { + AuthSession =3D NULL; + } else { + AuthSession =3D &LocalAuthSession; + ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession)); + LocalAuthSession.sessionHandle =3D TPM_RS_PW; + LocalAuthSession.hmac.size =3D PlatformAuth->size; + CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformA= uth->size); + } + + DEBUG ((DEBUG_INFO, "Tpm2ClearControl ... \n")); + Status =3D Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO); + DEBUG ((DEBUG_INFO, "Tpm2ClearControl - %r\n", Status)); + if (EFI_ERROR (Status)) { + goto Done; + } + + DEBUG ((DEBUG_INFO, "Tpm2Clear ... \n")); + Status =3D Tpm2Clear (TPM_RH_PLATFORM, AuthSession); + DEBUG ((DEBUG_INFO, "Tpm2Clear - %r\n", Status)); + +Done: + ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac)); + return Status; +} + +/** + Change EPS. + + @param[in] PlatformAuth platform auth value. NULL means no platfor= m auth change. + + @retval EFI_SUCCESS Operation completed successfully. +**/ +EFI_STATUS +Tpm2CommandChangeEps ( + IN TPM2B_AUTH *PlatformAuth OPTIONAL + ) +{ + EFI_STATUS Status; + TPMS_AUTH_COMMAND *AuthSession; + TPMS_AUTH_COMMAND LocalAuthSession; + + if (PlatformAuth =3D=3D NULL) { + AuthSession =3D NULL; + } else { + AuthSession =3D &LocalAuthSession; + ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession)); + LocalAuthSession.sessionHandle =3D TPM_RS_PW; + LocalAuthSession.hmac.size =3D PlatformAuth->size; + CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformA= uth->size); + } + + Status =3D Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession); + DEBUG ((DEBUG_INFO, "Tpm2ChangeEPS - %r\n", Status)); + + ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac)); + return Status; +} + +/** + Execute physical presence operation requested by the OS. + + @param[in] PlatformAuth platform auth value. NULL means no p= latform auth change. + @param[in] CommandCode Physical presence operation value. + @param[in] CommandParameter Physical presence operation paramete= r. + @param[in, out] PpiFlags The physical presence interface flag= s. + + @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presen= ce operation. + @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during s= ending command to TPM or + receiving response from= TPM. + @retval Others Return code from the TP= M device after command execution. +**/ +UINT32 +Tcg2ExecutePhysicalPresence ( + IN TPM2B_AUTH *PlatformAuth, OPTIONAL + IN UINT32 CommandCode, + IN UINT32 CommandParameter, + IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags + ) +{ + EFI_STATUS Status; + EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; + UINT32 ActivePcrBanks; + + switch (CommandCode) { + case TCG2_PHYSICAL_PRESENCE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: + Status =3D Tpm2CommandClear (PlatformAuth); + if (EFI_ERROR (Status)) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } else { + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + } + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE: + PpiFlags->PPFlags |=3D TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR= _CLEAR; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: + PpiFlags->PPFlags &=3D ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FO= R_CLEAR; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: + Status =3D Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorith= mBitmap, &ActivePcrBanks); + ASSERT_EFI_ERROR (Status); + + // + // PP spec requirements: + // Firmware should check that all requested (set) hashing algorit= hms are supported with respective PCR banks. + // Firmware has to ensure that at least one PCR banks is active. + // If not, an error is returned and no action is taken. + // + if ((CommandParameter =3D=3D 0) || ((CommandParameter & (~TpmHashAlg= orithmBitmap)) !=3D 0)) { + DEBUG ((DEBUG_ERROR, "PCR banks %x to allocate are not supported b= y TPM. Skip operation\n", CommandParameter)); + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } + + Status =3D Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitma= p, CommandParameter); + if (EFI_ERROR (Status)) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } else { + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + } + + case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: + Status =3D Tpm2CommandChangeEps (PlatformAuth); + if (EFI_ERROR (Status)) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } else { + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + } + + case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: + Status =3D Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorith= mBitmap, &ActivePcrBanks); + ASSERT_EFI_ERROR (Status); + Status =3D Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitma= p, TpmHashAlgorithmBitmap); + if (EFI_ERROR (Status)) { + return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } else { + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + } + + case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: + PpiFlags->PPFlags |=3D TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOC= K_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: + PpiFlags->PPFlags &=3D ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLO= CK_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= TRUE: + PpiFlags->PPFlags |=3D TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED= _FOR_ENABLE_BLOCK_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= FALSE: + PpiFlags->PPFlags &=3D ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRE= D_FOR_ENABLE_BLOCK_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _TRUE: + PpiFlags->PPFlags |=3D TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED= _FOR_DISABLE_BLOCK_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _FALSE: + PpiFlags->PPFlags &=3D ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRE= D_FOR_DISABLE_BLOCK_SID; + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + + default: + if (CommandCode <=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { + return TCG_PP_OPERATION_RESPONSE_SUCCESS; + } else { + 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. +**/ +BOOLEAN +Tcg2ReadUserKey ( + IN BOOLEAN CautionKey + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + UINT16 InputKey; + + InputKey =3D 0; + do { + Status =3D gBS->CheckEvent (gST->ConIn->WaitForKey); + if (!EFI_ERROR (Status)) { + Status =3D gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + 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; +} + +/** + Fill Buffer With BootHashAlg. + + @param[in] Buffer Buffer to be filled. + @param[in] BufferSize Size of buffer. + @param[in] BootHashAlg BootHashAlg. + +**/ +VOID +Tcg2FillBufferWithBootHashAlg ( + IN UINT16 *Buffer, + IN UINTN BufferSize, + IN UINT32 BootHashAlg + ) +{ + Buffer[0] =3D 0; + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) !=3D 0) { + if (Buffer[0] !=3D 0) { + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) !=3D 0) { + if (Buffer[0] !=3D 0) { + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize= / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) !=3D 0) { + if (Buffer[0] !=3D 0) { + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize= / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) !=3D 0) { + if (Buffer[0] !=3D 0) { + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize= / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) !=3D 0) { + if (Buffer[0] !=3D 0) { + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize /= sizeof (CHAR16)) - StrLen (Buffer) - 1); + } + + StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSiz= e / sizeof (CHAR16)) - StrLen (Buffer) - 1); + } +} + +/** + Display the confirm text and get user confirmation. + + @param[in] TpmPpCommand The requested TPM physical presence = command. + @param[in] TpmPpCommandParameter The requested TPM physical presence = command parameter. + + @retval TRUE The user has confirmed the changes. + @retval FALSE The user doesn't confirm the changes. +**/ +BOOLEAN +Tcg2UserConfirm ( + IN UINT32 TpmPpCommand, + IN UINT32 TpmPpCommandParameter + ) +{ + CHAR16 *ConfirmText; + CHAR16 *TmpStr1; + CHAR16 *TmpStr2; + UINTN BufSize; + BOOLEAN CautionKey; + BOOLEAN NoPpiInfo; + UINT16 Index; + CHAR16 DstStr[81]; + CHAR16 TempBuffer[1024]; + CHAR16 TempBuffer2[1024]; + EFI_TCG2_PROTOCOL *Tcg2Protocol; + EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability; + UINT32 CurrentPCRBanks; + EFI_STATUS Status; + + TmpStr2 =3D NULL; + CautionKey =3D FALSE; + NoPpiInfo =3D FALSE; + BufSize =3D CONFIRM_BUFFER_SIZE; + ConfirmText =3D AllocateZeroPool (BufSize); + ASSERT (ConfirmText !=3D NULL); + + mTcg2PpStringPackHandle =3D HiiAddPackages (&gEfiTcg2PhysicalPresenceGui= d, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL); + ASSERT (mTcg2PpStringPackHandle !=3D NULL); + + switch (TpmPpCommand) { + case TCG2_PHYSICAL_PRESENCE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: + CautionKey =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_= CLEAR)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_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); + + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: + CautionKey =3D TRUE; + NoPpiInfo =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_= CLEAR)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI= _HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOT= E_CLEAR)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_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); + + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: + Status =3D gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID *= *)&Tcg2Protocol); + ASSERT_EFI_ERROR (Status); + + ProtocolCapability.Size =3D sizeof (ProtocolCapability); + Status =3D Tcg2Protocol->GetCapability ( + Tcg2Protocol, + &ProtocolCapability + ); + ASSERT_EFI_ERROR (Status); + + Status =3D Tcg2Protocol->GetActivePcrBanks ( + Tcg2Protocol, + &CurrentPCRBanks + ); + ASSERT_EFI_ERROR (Status); + + CautionKey =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_= SET_PCR_BANKS)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_SET_PCR_BANKS_1)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_SET_PCR_BANKS_2)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof (TempBuffer), TpmP= pCommandParameter); + Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof (TempBuffer2), Cu= rrentPCRBanks); + + TmpStr1 =3D AllocateZeroPool (BufSize); + ASSERT (TmpStr1 !=3D NULL); + UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nN= ew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandPar= ameter, TempBuffer); + + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize /= sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + break; + + case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: + CautionKey =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_= CHANGE_EPS)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEA= D_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_CHANGE_EPS_1)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WAR= NING_CHANGE_EPS_2)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + break; + + case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_ENABLE_BLOCK_SID)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + break; + + case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_DISABLE_BLOCK_SID)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= FALSE: + NoPpiInfo =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_S= TORAGE_PP_ENABLE_BLOCK_SID)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_PPI_HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _FALSE: + NoPpiInfo =3D TRUE; + TmpStr2 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_S= TORAGE_PP_DISABLE_BLOCK_SID)); + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_PPI_HEAD_STR)); + UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); + FreePool (TmpStr1); + break; + + default: + ; + } + + if (TmpStr2 =3D=3D NULL) { + FreePool (ConfirmText); + return FALSE; + } + + if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) { + if (CautionKey) { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAU= TION_KEY)); + } else { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACC= EPT_KEY)); + } + + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / = sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + if (NoPpiInfo) { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_= PPI_INFO)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + } + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJEC= T_KEY)); + } else { + if (CautionKey) { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_CAUTION_KEY)); + } else { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_ACCEPT_KEY)); + } + + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / = sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + + if (NoPpiInfo) { + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STO= RAGE_NO_PPI_INFO)); + StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize = / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); + FreePool (TmpStr1); + } + + TmpStr1 =3D Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORA= GE_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 + Ind= ex, sizeof (DstStr) / sizeof (CHAR16) - 1); + Print (DstStr); + } + + FreePool (TmpStr1); + FreePool (TmpStr2); + FreePool (ConfirmText); + HiiRemovePackages (mTcg2PpStringPackHandle); + + if (Tcg2ReadUserKey (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 Tcg2 Physical Presence reques= t data. + @param[in] Flags The physical presence interface f= lags. + @param[out] RequestConfirmed If the physical presence operatio= n command required user confirm from UI. + True, it indicates the command = doesn't require user confirm, or already confirmed + in last boot cycle by use= r. + False, it indicates the command= need user confirm from UI. + + @retval TRUE Physical Presence operation command is valid. + @retval FALSE Physical Presence operation command is invalid. + +**/ +BOOLEAN +Tcg2HaveValidTpmRequest ( + IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData, + IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags, + OUT BOOLEAN *RequestConfirmed + ) +{ + EFI_TCG2_PROTOCOL *Tcg2Protocol; + EFI_STATUS Status; + BOOLEAN IsRequestValid; + + *RequestConfirmed =3D FALSE; + + if (TcgPpData->PPRequest <=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { + // + // Need TCG2 protocol. + // + Status =3D gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)= &Tcg2Protocol); + if (EFI_ERROR (Status)) { + return FALSE; + } + } + + switch (TcgPpData->PPRequest) { + case TCG2_PHYSICAL_PRESENCE_NO_ACTION: + *RequestConfirmed =3D TRUE; + return TRUE; + + case TCG2_PHYSICAL_PRESENCE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: + if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_C= LEAR) =3D=3D 0) { + *RequestConfirmed =3D TRUE; + } + + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE: + *RequestConfirmed =3D TRUE; + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE: + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: + if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_C= HANGE_PCRS) =3D=3D 0) { + *RequestConfirmed =3D TRUE; + } + + break; + + case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: + if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_C= HANGE_EPS) =3D=3D 0) { + *RequestConfirmed =3D TRUE; + } + + break; + + case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: + *RequestConfirmed =3D TRUE; + break; + + case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: + if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_F= OR_ENABLE_BLOCK_SID) =3D=3D 0) { + *RequestConfirmed =3D TRUE; + } + + break; + + case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: + if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_F= OR_DISABLE_BLOCK_SID) =3D=3D 0) { + *RequestConfirmed =3D TRUE; + } + + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= TRUE: + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _TRUE: + *RequestConfirmed =3D TRUE; + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= FALSE: + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _FALSE: + break; + + default: + if (TcgPpData->PPRequest >=3D TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC= _OPERATION) { + IsRequestValid =3D Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRe= quest, Flags.PPFlags, RequestConfirmed); + if (!IsRequestValid) { + return FALSE; + } else { + break; + } + } else { + // + // Wrong Physical Presence command + // + return FALSE; + } + } + + if ((Flags.PPFlags & TCG2_LIB_PP_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] PlatformAuth platform auth value. NULL means no pla= tform auth change. + @param[in, out] TcgPpData Pointer to the physical presence NV va= riable. + @param[in, out] Flags Pointer to the physical presence inter= face flags. +**/ +VOID +Tcg2ExecutePendingTpmRequest ( + IN TPM2B_AUTH *PlatformAuth, OPTIONAL + IN OUT EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData, + IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *Flags + ) +{ + EFI_STATUS Status; + UINTN DataSize; + BOOLEAN RequestConfirmed; + EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags; + BOOLEAN ResetRequired; + UINT32 NewPPFlags; + + if (TcgPpData->PPRequest =3D=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION) { + // + // No operation request + // + return; + } + + if (!Tcg2HaveValidTpmRequest (TcgPpData, *Flags, &RequestConfirmed)) { + // + // Invalid operation request. + // + if (TcgPpData->PPRequest <=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) { + TcgPpData->PPResponse =3D TCG_PP_OPERATION_RESPONSE_SUCCESS; + } else { + TcgPpData->PPResponse =3D TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; + } + + TcgPpData->LastPPRequest =3D TcgPpData->PPRequest; + TcgPpData->PPRequest =3D TCG2_PHYSICAL_PRESENCE_NO_ACTION; + TcgPpData->PPRequestParameter =3D 0; + + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE= _ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + TcgPpData + ); + return; + } + + ResetRequired =3D FALSE; + if (TcgPpData->PPRequest >=3D TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPE= RATION) { + NewFlags =3D *Flags; + NewPPFlags =3D NewFlags.PPFlags; + TcgPpData->PPResponse =3D Tcg2PpVendorLibExecutePendingRequest (Platfo= rmAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired); + NewFlags.PPFlags =3D NewPPFlags; + } else { + if (!RequestConfirmed) { + // + // Print confirm text and wait for approval. + // + DEBUG ((DEBUG_INFO, "Print confirm text and wait for approval.\n")); + RequestConfirmed =3D TRUE; + // RequestConfirmed =3D Tcg2UserConfirm (TcgPpData->PPRequest, TcgPp= Data->PPRequestParameter); + } + + // + // Execute requested physical presence command + // + TcgPpData->PPResponse =3D TCG_PP_OPERATION_RESPONSE_USER_ABORT; + NewFlags =3D *Flags; + if (RequestConfirmed) { + TcgPpData->PPResponse =3D Tcg2ExecutePhysicalPresence ( + PlatformAuth, + TcgPpData->PPRequest, + TcgPpData->PPRequestParameter, + &NewFlags + ); + } + } + + // + // Save the flags if it is updated. + // + if (CompareMem (Flags, &NewFlags, sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLA= GS)) !=3D 0) { + *Flags =3D NewFlags; + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_A= CCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS), + &NewFlags + ); + } + + // + // Clear request + // + if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) =3D=3D 0) { + TcgPpData->LastPPRequest =3D TcgPpData->PPRequest; + TcgPpData->PPRequest =3D TCG2_PHYSICAL_PRESENCE_NO_ACTION; + TcgPpData->PPRequestParameter =3D 0; + } + + // + // Save changes + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_A= CCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + TcgPpData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to set variable %S, %r\n", TCG2_PHYSICAL_PR= ESENCE_VARIABLE, Status)); + return; + } + + if (TcgPpData->PPResponse =3D=3D TCG_PP_OPERATION_RESPONSE_USER_ABORT) { + DEBUG ((DEBUG_INFO, "User abort the TPM action \n")); + return; + } + + // + // Reset system to make new TPM settings in effect + // + switch (TcgPpData->LastPPRequest) { + case TCG2_PHYSICAL_PRESENCE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2: + case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3: + case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS: + case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS: + case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS: + break; + + case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID: + case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID: + break; + + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= TRUE: + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _TRUE: + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_= FALSE: + case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC= _FALSE: + return; + + default: + if (TcgPpData->LastPPRequest >=3D TCG2_PHYSICAL_PRESENCE_VENDOR_SPEC= IFIC_OPERATION) { + if (ResetRequired) { + break; + } else { + return; + } + } + + if (TcgPpData->PPRequest !=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION) { + break; + } + + return; + } + + // Print (L"Rebooting system to make TPM2 settings in effect\n"); + DEBUG ((DEBUG_INFO, "Rebooting system to make TPM2 settings in effect\n"= )); + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + ASSERT (FALSE); +} + +/** + Check and execute the pending TPM request. + + 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. + + 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= . + + @param[in] PlatformAuth platform auth value. NULL mea= ns no platform auth change. +**/ +VOID +EFIAPI +Tcg2PhysicalPresenceLibProcessRequest ( + IN TPM2B_AUTH *PlatformAuth OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_TCG2_PHYSICAL_PRESENCE TcgPpData; + EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; + EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; + + // + // 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. + // + Status =3D gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (= VOID **)&VariableLockProtocol); + if (!EFI_ERROR (Status)) { + Status =3D VariableLockProtocol->RequestToLock ( + VariableLockProtocol, + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE= , + &gEfiTcg2PhysicalPresenceGuid + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] Error when lock variable %s, Status =3D= %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status)); + ASSERT_EFI_ERROR (Status); + } + } + + // On AMD FCH, always do S4 for shutdown. + // Todo: Chang to PCD method for this + // + // Check S4 resume + // + // if (GetBootModeHob () =3D=3D BOOT_ON_S4_RESUME) { + // DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n")); + // return ; + // } + + // + // Initialize physical presence flags. + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + PpiFlags.PPFlags =3D PcdGet32 (PcdTcg2PhysicalPresenceFlags); + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOO= TSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS), + &PpiFlags + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence flag failed, Stat= us =3D %r\n", Status)); + return; + } + + DEBUG ((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0= x%x\n", PpiFlags.PPFlags)); + } + + // + // Initialize physical presence variable. + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &TcgPpData + ); + if (EFI_ERROR (Status)) { + ZeroMem ((VOID *)&TcgPpData, sizeof (TcgPpData)); + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE= _ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &TcgPpData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence variable failed, = Status =3D %r\n", Status)); + return; + } + } + + DEBUG ((DEBUG_INFO, "[TPM2] Flags=3D%x, PPRequest=3D%x (LastPPRequest=3D= %x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest)); + + // + // Execute pending TPM request. + // + Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags); + DEBUG ((DEBUG_INFO, "[TPM2] PPResponse =3D %x (LastPPRequest=3D%x, Flags= =3D%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags)= ); +} + +/** + Check if the pending TPM request needs user input to confirm. + + The TPM request may come from OS. This API will check if TPM request exi= sts and need user + input to confirmation. + + @retval TRUE TPM needs input to confirm user physical presence= . + @retval FALSE TPM doesn't need input to confirm user physical p= resence. + +**/ +BOOLEAN +EFIAPI +Tcg2PhysicalPresenceLibNeedUserConfirm ( + VOID + ) +{ + EFI_STATUS Status; + EFI_TCG2_PHYSICAL_PRESENCE TcgPpData; + UINTN DataSize; + BOOLEAN RequestConfirmed; + EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; + + // In AMD FCH, always do S4 for Shutdown. + // Todo: Chang to PCD method for this + // + // Check S4 resume + // + // if (GetBootModeHob () =3D=3D BOOT_ON_S4_RESUME) { + // DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n")); + // return FALSE; + // } + + // + // Check Tpm requests + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &TcgPpData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRES= ENCE_VARIABLE, Status)); + return FALSE; + } + + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRES= ENCE_FLAGS_VARIABLE, Status)); + return FALSE; + } + + if (TcgPpData.PPRequest =3D=3D TCG2_PHYSICAL_PRESENCE_NO_ACTION) { + // + // No operation request + // + return FALSE; + } + + if (!Tcg2HaveValidTpmRequest (&TcgPpData, PpiFlags, &RequestConfirmed)) = { + // + // Invalid operation request. + // + return FALSE; + } + + if (!RequestConfirmed) { + // + // Need UI to confirm + // + return TRUE; + } + + return FALSE; +} + +/** + The handler for TPM physical presence function: + Return TPM Operation Response to OS Environment. + + @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 + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_TCG2_PHYSICAL_PRESENCE PpData; + + DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n")); + + // + // Get the Physical Presence variable + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &PpData + ); + if (EFI_ERROR (Status)) { + *MostRecentRequest =3D 0; + *Response =3D 0; + DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status =3D %r\n"= , Status)); + return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE; + } + + *MostRecentRequest =3D PpData.LastPPRequest; + *Response =3D PpData.PPResponse; + + return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS; +} + +/** + 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= . + @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 +Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction ( + IN UINT32 OperationRequest, + IN UINT32 RequestParameter + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_TCG2_PHYSICAL_PRESENCE PpData; + EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags; + + DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request =3D %x= , %x\n", OperationRequest, RequestParameter)); + + // + // Get the Physical Presence variable + // + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &PpData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status =3D %r\n"= , Status)); + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE; + } + + if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) && + (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN)= ) + { + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED; + } + + if ((PpData.PPRequest !=3D OperationRequest) || + (PpData.PPRequestParameter !=3D RequestParameter)) + { + PpData.PPRequest =3D (UINT8)OperationRequest; + PpData.PPRequestParameter =3D RequestParameter; + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE); + Status =3D gRT->SetVariable ( + TCG2_PHYSICAL_PRESENCE_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VAR= IABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &PpData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status =3D %r\= n", Status)); + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE; + } + } + + if (OperationRequest >=3D TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATI= ON) { + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &Flags + ); + if (EFI_ERROR (Status)) { + Flags.PPFlags =3D PcdGet32 (PcdTcg2PhysicalPresenceFlags); + } + + return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, = Flags.PPFlags, RequestParameter); + } + + return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS; +} + +/** + Return TPM2 ManagementFlags set by PP interface. + + @retval ManagementFlags TPM2 Management Flags. +**/ +UINT32 +EFIAPI +Tcg2PhysicalPresenceLibGetManagementFlags ( + VOID + ) +{ + EFI_STATUS Status; + EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags; + UINTN DataSize; + + DEBUG ((DEBUG_INFO, "[TPM2] GetManagementFlags\n")); + + DataSize =3D sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS); + Status =3D gRT->GetVariable ( + TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, + &gEfiTcg2PhysicalPresenceGuid, + NULL, + &DataSize, + &PpiFlags + ); + if (EFI_ERROR (Status)) { + PpiFlags.PPFlags =3D PcdGet32 (PcdTcg2PhysicalPresenceFlags); + } + + return PpiFlags.PPFlags; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Dx= eTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf b/Platform/AMD/VanG= oghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTc= g2PhysicalPresenceLib.inf new file mode 100644 index 0000000000..2ce1133596 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2Ph= ysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf @@ -0,0 +1,68 @@ +## @file +# Executes TPM 2.0 requests from OS or BIOS +# +# This library will check and execute TPM 2.0 request from OS or BIOS. Th= e request may +# ask for user confirmation before execution. +# +# 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) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeTcg2PhysicalPresenceLib + MODULE_UNI_FILE =3D DxeTcg2PhysicalPresenceLib.uni + FILE_GUID =3D 7E507A86-DE8B-4AD3-BC4C-0498389098D3 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D Tcg2PhysicalPresenceLib|DXE_DRIVER DX= E_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + +[Sources] + DxeTcg2PhysicalPresenceLib.c + PhysicalPresenceStrings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + PrintLib + HiiLib + HobLib + Tpm2CommandLib + Tcg2PpVendorLib + +[Protocols] + gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiVariableLockProtocolGuid ## SOMETIMES_CONSUMES + +[Pcd] + gEfiSecurityPkgTokenSpaceGuid.PcdTcg2PhysicalPresenceFlags ## SOME= TIMES_CONSUMES + +[Guids] + ## SOMETIMES_CONSUMES ## HII + ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresence" + ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresence" + ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresenceFlags" + ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresenceFlags" + gEfiTcg2PhysicalPresenceGuid diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Dx= eTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni b/Platform/AMD/VanG= oghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTc= g2PhysicalPresenceLib.uni new file mode 100644 index 0000000000..d7e4af732b --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2Ph= ysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni @@ -0,0 +1,22 @@ +// /** @file +// Executes TPM 2.0 requests from OS or BIOS +// +// This library will check and execute TPM 2.0 request from OS or BIOS. Th= e request may +// ask for user confirmation before execution. +// +// 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) 2024 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Executes TPM 2.0 = requests from OS or BIOS" + +#string STR_MODULE_DESCRIPTION #language en-US "This library will= check and execute TPM 2.0 request from OS or BIOS. The request may ask for= user confirmation before execution.\n" + "Caution: This mod= ule requires additional review when modified. This driver will have externa= l input - variable. This external input must be validated carefully to avoi= d security issue." + diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/Dx= eTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni b/Platform/AMD/VanGogh= Board/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/Physical= PresenceStrings.uni new file mode 100644 index 0000000000..70fa651455 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2Ph= ysicalPresenceLib/PhysicalPresenceStrings.uni @@ -0,0 +1,57 @@ +// /** @file +// String definitions for TPM 2.0 physical presence confirm text. +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// 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_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_CLEAR #language en-US "clear" +#string TPM_SET_PCR_BANKS #language en-US "change= the boot measurements to use PCR bank(s) of" +#string TPM_CHANGE_EPS #language en-US "clear = and change identity of" +#string TPM_DISABLE_ENDORSEMENT_ENABLE_STORAGE #language en-US "disabl= e access to some secrets stored in" + +#string TPM_NO_PPI_MAINTAIN #language en-US "maintain" +#string TPM_NO_PPI_TURN_ON #language en-US "turn on" +#string TPM_NO_PPI_TURN_OFF #language en-US "turn off" +#string TPM_NO_PPI_INFO #language en-US "to approve futur= e Operating System requests " + +#string TPM_WARNING_DISABLE #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_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" +#string TPM_WARNING_SET_PCR_BANKS_1 #language en-US = "WARNING: Changing the PCR bank(s) of the boot measurements may prevent th= e Operating System from properly processing the measurements. Please check = if your Operating System supports the new PCR bank(s).\n\n" +#string TPM_WARNING_SET_PCR_BANKS_2 #language en-US = "WARNING: Secrets in the TPM that are bound to the boot state of your mach= ine may become unusable.\n\n" +#string TPM_WARNING_CHANGE_EPS_1 #language en-US = "WARNING: Clearing erases information stored on the TPM. You will lose all= created keys and access to data encrypted with these keys.\n\n" +#string TPM_WARNING_CHANGE_EPS_2 #language en-US = "WARNING: Changing the identity of the TPM may require additional steps to= establish trust into the new identity.\n\n" +#string TPM_WARNING_PP_CHANGE_PCRS_FALSE #language en-US = "WARNING: Allowing future changes to format of the boot measurement log ma= y affect the Operating System.\n\n" +#string TPM_WARNING_PP_CHANGE_EPS_FALSE_1 #language en-US = "WARNING: Allowing future changes to the TPM's firmware may affect the ope= ration of the TPM and may erase information stored on the TPM.\n\n" +#string TPM_WARNING_PP_CHANGE_EPS_FALSE_2 #language en-US = "You may lose all created keys and access to data encrypted by these keys.= \n\n" +#string TPM_WARNING_DISABLE_ENDORSEMENT_ENABLE_STORAGE #language en-US = "WARNING: Doing so might prevent security applications that rely on the TP= M from functioning as expected.\n\n" + +#string TCG_STORAGE_HEAD_STR #language en-US "A config= uration change was requested to %s on subsequent boots\n\n" +#string TCG_STORAGE_PPI_HEAD_STR #language en-US "A config= uration change was requested to allow the Operating System to %s without as= king for user confirmation in the future.\n\n" + +#string TCG_STORAGE_ACCEPT_KEY #language en-US "Press F1= 0 " +#string TCG_STORAGE_CAUTION_KEY #language en-US "Press F1= 2 " +#string TCG_STORAGE_REJECT_KEY #language en-US "to %s\nP= ress ESC to reject this change request and continue\n" + +#string TCG_STORAGE_NO_PPI_INFO #language en-US "to appro= ve future Operating System requests " + +#string TCG_STORAGE_ENABLE_BLOCK_SID #language en-US "issue a = Block SID authentication command" +#string TCG_STORAGE_DISABLE_BLOCK_SID #language en-US "disable = issuing a Block SID authentication command" + +#string TCG_STORAGE_PP_ENABLE_BLOCK_SID #language en-US "enable b= locking SID authentication" +#string TCG_STORAGE_PP_DISABLE_BLOCK_SID #language en-US "disable = blocking SID authentication" diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tcg2Smm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityP= kg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c new file mode 100644 index 0000000000..62317165cb --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tcg2Smm.c @@ -0,0 +1,854 @@ +/** @file + It updates fTPM2 items in ACPI table and registers SMI2 callback + functions for Tcg2 physical presence, ClearMemory, and sample + for dTPM StartMethod. + + Caution: This module requires additional review when modified. + This driver will have external input - variable and ACPINvs data in SMM = mode. + This external input must be validated carefully to avoid security issue. + + PhysicalPresenceCallback() and MemoryClearCallback() will receive untrus= ted input and do some check. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Tcg2Smm.h" + +TPM2_CONTROL_AREA *mFtpmControlArea =3D NULL; + +EFI_TPM2_ACPI_TABLE mTpm2AcpiTemplate =3D { + { + EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE, + sizeof (mTpm2AcpiTemplate), + EFI_TPM2_ACPI_TABLE_REVISION, + // + // Compiler initializes the remaining bytes to 0 + // These fields should be filled in in production + // + }, + 0, // BIT0~15: PlatformClass + // BIT16~31: Reserved + 0, // Control Area + EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod +}; + +EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; +TCG_NVS *mTcgNvs; + +/** + Software SMI callback for TPM physical presence which is called from ACP= I method. + + Caution: This function may receive untrusted input. + Variable and ACPINvs are external input, so this function will validate + its data structure to be valid value. + + @param[in] DispatchHandle The unique handle assigned to this handl= er by SmiHandlerRegister(). + @param[in] Context Points to an optional handler context wh= ich was specified when the + handler was registered. + @param[in, out] CommBuffer A pointer to a collection of data in mem= ory that will + be conveyed from a non-SMM environment i= nto an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS The interrupt was handled successfully. + +**/ +EFI_STATUS +EFIAPI +PhysicalPresenceCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + UINT32 MostRecentRequest; + UINT32 Response; + UINT32 OperationRequest; + UINT32 RequestParameter; + + if (mTcgNvs->PhysicalPresence.Parameter =3D=3D TCG_ACPI_FUNCTION_RETURN_= REQUEST_RESPONSE_TO_OS) { + mTcgNvs->PhysicalPresence.ReturnCode =3D Tcg2PhysicalPresenceLibReturn= OperationResponseToOsFunction ( + &MostRecentRequest, + &Response + ); + mTcgNvs->PhysicalPresence.LastRequest =3D MostRecentRequest; + mTcgNvs->PhysicalPresence.Response =3D Response; + return EFI_SUCCESS; + } else if ( (mTcgNvs->PhysicalPresence.Parameter =3D=3D TCG_ACPI_FUNCTI= ON_SUBMIT_REQUEST_TO_BIOS) + || (mTcgNvs->PhysicalPresence.Parameter =3D=3D TCG_ACPI_FUNCTI= ON_SUBMIT_REQUEST_TO_BIOS_2)) + { + OperationRequest =3D mTcgNvs->PhysicalPresence.Req= uest; + RequestParameter =3D mTcgNvs->PhysicalPresence.Req= uestParameter; + mTcgNvs->PhysicalPresence.ReturnCode =3D Tcg2PhysicalPresenceLibSubmit= RequestToPreOSFunctionEx ( + &OperationRequest, + &RequestParameter + ); + mTcgNvs->PhysicalPresence.Request =3D OperationRequest; + mTcgNvs->PhysicalPresence.RequestParameter =3D RequestParameter; + } else if (mTcgNvs->PhysicalPresence.Parameter =3D=3D TCG_ACPI_FUNCTION_= GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) { + mTcgNvs->PhysicalPresence.ReturnCode =3D Tcg2PhysicalPresenceLibGetUse= rConfirmationStatusFunction (mTcgNvs->PPRequestUserConfirm); + } + + return EFI_SUCCESS; +} + +/** + Software SMI callback for MemoryClear which is called from ACPI method. + + Caution: This function may receive untrusted input. + Variable and ACPINvs are external input, so this function will validate + its data structure to be valid value. + + @param[in] DispatchHandle The unique handle assigned to this handl= er by SmiHandlerRegister(). + @param[in] Context Points to an optional handler context wh= ich was specified when the + handler was registered. + @param[in, out] CommBuffer A pointer to a collection of data in mem= ory that will + be conveyed from a non-SMM environment i= nto an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS The interrupt was handled successfully. + +**/ +EFI_STATUS +EFIAPI +MemoryClearCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + EFI_STATUS Status; + UINTN DataSize; + UINT8 MorControl; + + mTcgNvs->MemoryClear.ReturnCode =3D MOR_REQUEST_SUCCESS; + if (mTcgNvs->MemoryClear.Parameter =3D=3D ACPI_FUNCTION_DSM_MEMORY_CLEAR= _INTERFACE) { + MorControl =3D (UINT8)mTcgNvs->MemoryClear.Request; + } else if (mTcgNvs->MemoryClear.Parameter =3D=3D ACPI_FUNCTION_PTS_CLEAR= _MOR_BIT) { + DataSize =3D sizeof (UINT8); + Status =3D mSmmVariable->SmmGetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + NULL, + &DataSize, + &MorControl + ); + if (EFI_ERROR (Status)) { + mTcgNvs->MemoryClear.ReturnCode =3D MOR_REQUEST_GENERAL_FAILURE; + return EFI_SUCCESS; + } + + if (MOR_CLEAR_MEMORY_VALUE (MorControl) =3D=3D 0x0) { + return EFI_SUCCESS; + } + + MorControl &=3D ~MOR_CLEAR_MEMORY_BIT_MASK; + } + + DataSize =3D sizeof (UINT8); + Status =3D mSmmVariable->SmmSetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOT= SERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &MorControl + ); + if (EFI_ERROR (Status)) { + mTcgNvs->MemoryClear.ReturnCode =3D MOR_REQUEST_GENERAL_FAILURE; + } + + return EFI_SUCCESS; +} + +/** + Find the operation region in TCG ACPI table by given Name and Size, + and initialize it if the region is found. + + @param[in, out] Table The TPM item in ACPI table. + @param[in] Name The name string to find in TPM table. + @param[in] Size The size of the region to find. + + @return The allocated address for the found regio= n. + +**/ +VOID * +AssignOpRegion ( + EFI_ACPI_DESCRIPTION_HEADER *Table, + UINT32 Name, + UINT16 Size + ) +{ + EFI_STATUS Status; + AML_OP_REGION_32_8 *OpRegion; + EFI_PHYSICAL_ADDRESS MemoryAddress; + + MemoryAddress =3D SIZE_4GB - 1; + + // + // Patch some pointers for the ASL code before loading the SSDT. + // + for (OpRegion =3D (AML_OP_REGION_32_8 *)(Table + 1); + OpRegion <=3D (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length= ); + OpRegion =3D (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1)) + { + if ((OpRegion->OpRegionOp =3D=3D AML_EXT_REGION_OP) && + (OpRegion->NameString =3D=3D Name) && + (OpRegion->DWordPrefix =3D=3D AML_DWORD_PREFIX) && + (OpRegion->BytePrefix =3D=3D AML_BYTE_PREFIX)) + { + Status =3D gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS,= EFI_SIZE_TO_PAGES (Size), &MemoryAddress); + ASSERT_EFI_ERROR (Status); + ZeroMem ((VOID *)(UINTN)MemoryAddress, Size); + OpRegion->RegionOffset =3D (UINT32)(UINTN)MemoryAddress; + OpRegion->RegionLen =3D (UINT8)Size; + break; + } + } + + return (VOID *)(UINTN)MemoryAddress; +} + +/** + Find the fTPM Control Area operation region in TCG ACPI table by given N= ame and Size, + and initialize it if the region is found. + + @param[in, out] Table The TPM item in ACPI table. + @param[in] Name The name string to find in TPM table. + @param[in] ControlAreaAddr The Control Area address to set. + @param[in] ControlAreaSize The Control Area size to size. + + @return The allocated address for the found reg= ion. + +**/ +EFI_STATUS +PatchTpmControlAreaOpRegion ( + EFI_ACPI_DESCRIPTION_HEADER *Table, + UINT32 Name, + UINT32 ControlAreaAddr, + UINT8 ControlAreaSize + ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + AML_OP_REGION_32_8 *OpRegion =3D NULL; + + // + // Patch some pointers for the ASL code before loading the SSDT. + // + for (OpRegion =3D (AML_OP_REGION_32_8 *)(Table + 1); + OpRegion <=3D (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length= ); + OpRegion =3D (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1)) + { + if ((OpRegion->OpRegionOp =3D=3D AML_EXT_REGION_OP) && + (OpRegion->NameString =3D=3D Name) && + (OpRegion->DWordPrefix =3D=3D AML_DWORD_PREFIX) && + (OpRegion->BytePrefix =3D=3D AML_BYTE_PREFIX)) + { + OpRegion->RegionOffset =3D ControlAreaAddr; + OpRegion->RegionLen =3D ControlAreaSize; + Status =3D EFI_SUCCESS; + break; + } + } + + return Status; +} + +/** + Patch the Memory32Fixed definitions in TCG ACPI table, and initialize th= eir value for pre-defined signatures. + + @param[in, out] Table The TPM item in ACPI table. + @param[in] CommandAddr The Command Address to set for certain si= gnature in Memory32Fixed. + @param[in] ResponseAddr The Response Address to set for certain s= ignature in Memory32Fixed. + + @return The allocated address for the found regio= n. + +**/ +EFI_STATUS +AssignMemory32Fixed ( + EFI_ACPI_DESCRIPTION_HEADER *Table, + UINT32 CommandAddr, + UINT32 ResponseAddr + ) +{ + EFI_STATUS Status =3D EFI_NOT_FOUND; + UINT8 *TmpPtr =3D NULL; + BOOLEAN CommandAddrPatched =3D FALSE; + BOOLEAN ResponseAddrPatched =3D FALSE; + + // + // Patch some pointers for the ASL code before loading the SSDT. + // + for (TmpPtr =3D (UINT8 *)Table; TmpPtr <=3D (UINT8 *)Table + Table->Leng= th; ) { + if (*(UINT32 *)TmpPtr =3D=3D 0xA5A5A5A5) { + *(UINT32 *)TmpPtr =3D CommandAddr; + CommandAddrPatched =3D TRUE; + TmpPtr =3D TmpPtr + 4; + } else if (*(UINT32 *)TmpPtr =3D=3D 0xAAAAAAAA) { + *(UINT32 *)TmpPtr =3D ResponseAddr; + ResponseAddrPatched =3D TRUE; + TmpPtr =3D TmpPtr + 4; + } else if (CommandAddrPatched && ResponseAddrPatched) { + Status =3D EFI_SUCCESS; + break; + } + + ++TmpPtr; + } + + return Status; +} + +/** + Patch version string of Physical Presence interface supported by platfor= m. The initial string tag in TPM +ACPI table is "$PV". + + @param[in, out] Table The TPM item in ACPI table. + @param[in] PPVer Version string of Physical Presence inter= face supported by platform. + + @return The allocated address for the found regio= n. + +**/ +EFI_STATUS +UpdatePPVersion ( + EFI_ACPI_DESCRIPTION_HEADER *Table, + CHAR8 *PPVer + ) +{ + EFI_STATUS Status; + UINT8 *DataPtr; + + // + // Patch some pointers for the ASL code before loading the SSDT. + // + for (DataPtr =3D (UINT8 *)(Table + 1); + DataPtr <=3D (UINT8 *)((UINT8 *)Table + Table->Length - PHYSICAL_PR= ESENCE_VERSION_SIZE); + DataPtr +=3D 1) + { + if (AsciiStrCmp ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) =3D= =3D 0) { + Status =3D AsciiStrCpyS ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION= _SIZE, PPVer); + DEBUG ((DEBUG_INFO, "TPM2 Physical Presence Interface Version update= status 0x%x\n", Status)); + return Status; + } + } + + return EFI_NOT_FOUND; +} + +/** + Patch interrupt resources returned by TPM _PRS. ResourceTemplate to patc= h is determined by input + interrupt buffer size. BufferSize, PkgLength and interrupt descirptor in= ByteList need to be patched + + @param[in, out] Table The TPM item in ACPI table. + @param[in] IrqBuffer Input new IRQ buffer. + @param[in] IrqBuffserSize Input new IRQ buffer size. + @param[out] IsShortFormPkgLength If _PRS returns Short length Pack= age(ACPI spec 20.2.4). + + @return patch status. + +**/ +EFI_STATUS +UpdatePossibleResource ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table, + IN UINT32 *IrqBuffer, + IN UINT32 IrqBuffserSize, + OUT BOOLEAN *IsShortFormPkgLength + ) +{ + UINT8 *DataPtr; + UINT8 *DataEndPtr; + UINT32 NewPkgLength; + UINT32 OrignalPkgLength; + + NewPkgLength =3D 0; + OrignalPkgLength =3D 0; + DataEndPtr =3D NULL; + + // + // Follow ACPI spec + // 6.4.3 Extend Interrupt Descriptor. + // 19.3.3 ASL Resource Template + // 20 AML specification + // to patch TPM ACPI object _PRS returned ResourceTemplate() containing = 2 resource descriptors and an auto appended End Tag + // + // AML data is organized by following rule. + // Code need to patch BufferSize and PkgLength and interrupt descirptor= in ByteList + // + // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Buffer =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + // DefBuffer :=3D BufferOp PkgLength BufferSize ByteList + // BufferOp :=3D 0x11 + // + // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DPkgLength=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + // PkgLength :=3D PkgLeadByte | + // | + // | + // + // + // PkgLeadByte :=3D + // + // + // + // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DBufferSize=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + // BufferSize :=3D Integar + // Integar :=3D ByteConst|WordConst|DwordConst.... + // + // ByteConst :=3D BytePrefix ByteData + // + // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3DByteList=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + // ByteList :=3D ByteData ByteList + // + // =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + + // + // 1. Check TPM_PRS_RESS with PkgLength <=3D63 can hold the input interr= upt number buffer for patching + // + for (DataPtr =3D (UINT8 *)(Table + 1); + DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_N= AME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE)); + DataPtr +=3D 1) + { + if (CompareMem (DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) =3D=3D 0= ) { + // + // Jump over object name & BufferOp + // + DataPtr +=3D TPM_PRS_RES_NAME_SIZE + 1; + + if ((*DataPtr & (BIT7|BIT6)) =3D=3D 0) { + OrignalPkgLength =3D (UINT32)*DataPtr; + DataEndPtr =3D DataPtr + OrignalPkgLength; + + // + // Jump over PkgLength =3D PkgLeadByte only + // + NewPkgLength++; + + // + // Jump over BufferSize + // + if (*(DataPtr + 1) =3D=3D AML_BYTE_PREFIX) { + NewPkgLength +=3D 2; + } else if (*(DataPtr + 1) =3D=3D AML_WORD_PREFIX) { + NewPkgLength +=3D 3; + } else if (*(DataPtr + 1) =3D=3D AML_DWORD_PREFIX) { + NewPkgLength +=3D 5; + } else { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + } else { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + // + // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descriptor= header(5 Bytes) + End Tag(2 Bytes) + // + NewPkgLength +=3D 19 + IrqBuffserSize; + if (NewPkgLength > 63) { + break; + } + + if (NewPkgLength > OrignalPkgLength) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + // + // 1.1 Patch PkgLength + // + *DataPtr =3D (UINT8)NewPkgLength; + + // + // 1.2 Patch BufferSize =3D sizeof(Memory32Fixed Descritor + Interru= pt Descriptor + End Tag). + // It is Little endian. So only patch lowest byte of BufferSize= due to current interrupt number limit. + // + *(DataPtr + 2) =3D (UINT8)(IrqBuffserSize + 19); + + // + // Notify _PRS to report short formed ResourceTemplate + // + *IsShortFormPkgLength =3D TRUE; + + break; + } + } + + // + // 2. Use TPM_PRS_RESL with PkgLength > 63 to hold longer input interrup= t number buffer for patching + // + if (NewPkgLength > 63) { + NewPkgLength =3D 0; + OrignalPkgLength =3D 0; + for (DataPtr =3D (UINT8 *)(Table + 1); + DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES= _NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE)); + DataPtr +=3D 1) + { + if (CompareMem (DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) =3D=3D= 0) { + // + // Jump over object name & BufferOp + // + DataPtr +=3D TPM_PRS_RES_NAME_SIZE + 1; + + if ((*DataPtr & (BIT7|BIT6)) !=3D 0) { + OrignalPkgLength =3D (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr &= 0x0F); + DataEndPtr =3D DataPtr + OrignalPkgLength; + // + // Jump over PkgLength =3D PkgLeadByte + ByteData length + // + NewPkgLength +=3D 1 + ((*DataPtr & (BIT7|BIT6)) >> 6); + + // + // Jump over BufferSize + // + if (*(DataPtr + NewPkgLength) =3D=3D AML_BYTE_PREFIX) { + NewPkgLength +=3D 2; + } else if (*(DataPtr + NewPkgLength) =3D=3D AML_WORD_PREFIX) { + NewPkgLength +=3D 3; + } else if (*(DataPtr + NewPkgLength) =3D=3D AML_DWORD_PREFIX) { + NewPkgLength +=3D 5; + } else { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + } else { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + + // + // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descript= or header(5 Bytes) + End Tag(2 Bytes) + // + NewPkgLength +=3D 19 + IrqBuffserSize; + + if (NewPkgLength > OrignalPkgLength) { + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + + // + // 2.1 Patch PkgLength. Only patch PkgLeadByte and first ByteData + // + *DataPtr =3D (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x= 0F); + *(DataPtr + 1) =3D (UINT8)((NewPkgLength & 0xFF0) >> 4); + + // + // 2.2 Patch BufferSize =3D sizeof(Memory32Fixed Descritor + Inter= rupt Descriptor + End Tag). + // It is Little endian. Only patch lowest byte of BufferSize d= ue to current interrupt number limit. + // + *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) =3D (UINT8)(IrqBu= ffserSize + 19); + + // + // Notify _PRS to report long formed ResourceTemplate + // + *IsShortFormPkgLength =3D FALSE; + break; + } + } + } + + if (DataPtr >=3D (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES= _NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE))) { + return EFI_NOT_FOUND; + } + + // + // 3. Move DataPtr to Interrupt descriptor header and patch interrupt de= scriptor. + // 5 bytes for interrupt descriptor header, 2 bytes for End Tag + // + DataPtr +=3D NewPkgLength - (5 + IrqBuffserSize + 2); + // + // 3.1 Patch Length bit[7:0] of Interrupt descirptor patch interrupt d= escriptor + // + *(DataPtr + 1) =3D (UINT8)(2 + IrqBuffserSize); + // + // 3.2 Patch Interrupt Table Length + // + *(DataPtr + 4) =3D (UINT8)(IrqBuffserSize / sizeof (UINT32)); + // + // 3.3 Copy patched InterruptNumBuffer + // + CopyMem (DataPtr + 5, IrqBuffer, IrqBuffserSize); + + // + // 4. Jump over Interrupt descirptor and Patch END Tag, set Checksum fie= ld to 0 + // + DataPtr +=3D 5 + IrqBuffserSize; + *DataPtr =3D ACPI_END_TAG_DESCRIPTOR; + *(DataPtr + 1) =3D 0; + + // + // 5. Jump over new ResourceTemplate. Stuff rest bytes to NOOP + // + DataPtr +=3D 2; + if (DataPtr < DataEndPtr) { + SetMem (DataPtr, (UINTN)DataEndPtr - (UINTN)DataPtr, AML_NOOP_OP); + } + + return EFI_SUCCESS; +} + +/** + Initialize and publish TPM items in ACPI table. + + @retval EFI_SUCCESS The TCG ACPI table is published successfully. + @retval Others The TCG ACPI table is not published. + +**/ +EFI_STATUS +PublishAcpiTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + UINTN TableKey; + EFI_ACPI_DESCRIPTION_HEADER *Table; + UINTN TableSize; + UINT32 *PossibleIrqNumBuf; + UINT32 PossibleIrqNumBufSize; + BOOLEAN IsShortFormPkgLength; + + IsShortFormPkgLength =3D FALSE; + + Status =3D GetSectionFromFv ( + &gEfiCallerIdGuid, + EFI_SECTION_RAW, + 0, + (VOID **)&Table, + &TableSize + ); + ASSERT_EFI_ERROR (Status); + + // + // Update Table version before measuring it to PCR + // + Status =3D UpdatePPVersion (Table, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPre= senceInterfaceVer)); + ASSERT_EFI_ERROR (Status); + + DEBUG (( + DEBUG_INFO, + "Current physical presence interface version - %a\n", + (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer) + )); + + // + + if (PcdGet32 (PcdTpm2CurrentIrqNum) !=3D 0) { + // + // Patch _PRS interrupt resource only when TPM interrupt is supported + // + PossibleIrqNumBuf =3D (UINT32 *)PcdGetPtr (PcdTpm2PossibleIrqNumBu= f); + PossibleIrqNumBufSize =3D (UINT32)PcdGetSize (PcdTpm2PossibleIrqNumBuf= ); + + if ((PossibleIrqNumBufSize <=3D MAX_PRS_INT_BUF_SIZE) && ((PossibleIrq= NumBufSize % sizeof (UINT32)) =3D=3D 0)) { + Status =3D UpdatePossibleResource (Table, PossibleIrqNumBuf, Possibl= eIrqNumBufSize, &IsShortFormPkgLength); + DEBUG (( + DEBUG_INFO, + "UpdatePossibleResource status - %x. TPM2 service may not ready in= OS.\n", + Status + )); + } else { + DEBUG (( + DEBUG_INFO, + "PcdTpm2PossibleIrqNumBuf size %x is not correct. TPM2 service may= not ready in OS.\n", + PossibleIrqNumBufSize + )); + } + } + + // + // Measure to PCR[0] with event EV_POST_CODE ACPI DATA + // + TpmMeasureAndLogData ( + 0, + EV_POST_CODE, + EV_POSTCODE_INFO_ACPI_DATA, + ACPI_DATA_LEN, + Table, + TableSize + ); + + ASSERT (Table->OemTableId =3D=3D SIGNATURE_64 ('T', 'p', 'm', '2', 'T', = 'a', 'b', 'l')); + CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->O= emId)); + + DEBUG ((DEBUG_INFO, "FtpmControlArea: 0x%lX\n", (UINTN)(VOID *)mFtpmCont= rolArea)); + DEBUG ((DEBUG_INFO, "CommandSize: 0x%lX, ResponseSize: 0x%lX \n", mFtpmC= ontrolArea->CommandSize, mFtpmControlArea->ResponseSize)); + + Status =3D AssignMemory32Fixed (Table, (UINT32)mFtpmControlArea->Command= Address, (UINT32)mFtpmControlArea->ResponseAddress); + ASSERT_EFI_ERROR (Status); + + Status =3D PatchTpmControlAreaOpRegion (Table, SIGNATURE_32 ('T', 'P', '= M', 'C'), (UINT32)(UINTN)(VOID *)mFtpmControlArea + 0x10, sizeof (EFI_TPM2_= ACPI_CONTROL_AREA)); + ASSERT_EFI_ERROR (Status); + + mTcgNvs =3D AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (U= INT16)sizeof (TCG_NVS)); + ASSERT (mTcgNvs !=3D NULL); + mTcgNvs->TpmIrqNum =3D PcdGet32 (PcdTpm2CurrentIrqNum); + mTcgNvs->IsShortFormPkgLength =3D IsShortFormPkgLength; + + // + // Publish the TPM ACPI table. Table is re-checksumed. + // + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID = **)&AcpiTable); + ASSERT_EFI_ERROR (Status); + + TableKey =3D 0; + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + Table, + TableSize, + &TableKey + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Publish TPM2 ACPI table + + @retval EFI_SUCCESS The TPM2 ACPI table is published successfully. + @retval Others The TPM2 ACPI table is not published. + +**/ +EFI_STATUS +PublishTpm2 ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + UINTN TableKey; + UINT64 OemTableId; + + mTpm2AcpiTemplate.Header.Revision =3D PcdGet8 (PcdTpm2AcpiTableRev); + DEBUG ((DEBUG_INFO, "Tpm2 ACPI table revision is %d\n", mTpm2AcpiTemplat= e.Header.Revision)); + + // + // PlatformClass is only valid for version 4 and above + // BIT0~15: PlatformClass + // BIT16~31: Reserved + // + if (mTpm2AcpiTemplate.Header.Revision >=3D EFI_TPM2_ACPI_TABLE_REVISION_= 4) { + mTpm2AcpiTemplate.Flags =3D (mTpm2AcpiTemplate.Flags & 0xFFFF0000) | P= cdGet8 (PcdTpmPlatformClass); + DEBUG ((DEBUG_INFO, "Tpm2 ACPI table PlatformClass is %d\n", (mTpm2Acp= iTemplate.Flags & 0x0000FFFF))); + } + + // + // Measure to PCR[0] with event EV_POST_CODE ACPI DATA + // + TpmMeasureAndLogData ( + 0, + EV_POST_CODE, + EV_POSTCODE_INFO_ACPI_DATA, + ACPI_DATA_LEN, + &mTpm2AcpiTemplate, + sizeof (mTpm2AcpiTemplate) + ); + + mTpm2AcpiTemplate.StartMethod =3D EFI_TPM2_ACPI_TABLE_START_MET= HOD_ACPI; + mTpm2AcpiTemplate.AddressOfControlArea =3D ((UINT64)(UINTN)(VOID *)mFtpm= ControlArea + 0x10); + + CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId)= , sizeof (mTpm2AcpiTemplate.Header.OemId)); + OemTableId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT= 64)); + mTpm2AcpiTemplate.Header.OemRevision =3D PcdGet32 (PcdAcpiDefaultOem= Revision); + mTpm2AcpiTemplate.Header.CreatorId =3D PcdGet32 (PcdAcpiDefaultCre= atorId); + mTpm2AcpiTemplate.Header.CreatorRevision =3D PcdGet32 (PcdAcpiDefaultCre= atorRevision); + + // + // Construct ACPI table + // + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID = **)&AcpiTable); + ASSERT_EFI_ERROR (Status); + + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + &mTpm2AcpiTemplate, + sizeof (mTpm2AcpiTemplate), + &TableKey + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + The driver's entry point. + + It install callbacks for TPM physical presence and MemoryClear, and loca= te + SMM variable to be used in the callback function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Others Some error occurs when executing this entry poin= t. + +**/ +EFI_STATUS +EFIAPI +InitializeTcgSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch; + EFI_SMM_SW_REGISTER_CONTEXT SwContext; + EFI_HANDLE SwHandle; + + DEBUG ((DEBUG_INFO, "InitializeTcgSmm Entry \n")); + if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstance= Tpm20DtpmGuid)) { + DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required!\n")); + return EFI_UNSUPPORTED; + } + + // if (!GetFtpmControlArea(&mFtpmControlArea)) { + // DEBUG ((DEBUG_ERROR, "Get fTPM Control Area failed!\n")); + // return EFI_UNSUPPORTED; + // } + mFtpmControlArea =3D (VOID *)(UINTN)PcdGet64 (PcdTpmBaseAddress); + DEBUG ((DEBUG_INFO, "Get PcdTpmBaseAddress:%x\n", mFtpmControlArea)); + Status =3D PublishAcpiTable (); + ASSERT_EFI_ERROR (Status); + + // + // Get the Sw dispatch protocol and register SMI callback functions. + // + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NU= LL, (VOID **)&SwDispatch); + ASSERT_EFI_ERROR (Status); + SwContext.SwSmiInputValue =3D (UINTN)-1; + Status =3D SwDispatch->Register (SwDispatch, Physical= PresenceCallback, &SwContext, &SwHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + mTcgNvs->PhysicalPresence.SoftwareSmi =3D (UINT8)SwContext.SwSmiInputVal= ue; + DEBUG ((DEBUG_INFO, "PhysicalPresence SoftwareSmi: 0x%X\n", (UINT8)SwCon= text.SwSmiInputValue)); + + SwContext.SwSmiInputValue =3D (UINTN)-1; + Status =3D SwDispatch->Register (SwDispatch, MemoryCl= earCallback, &SwContext, &SwHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + mTcgNvs->MemoryClear.SoftwareSmi =3D (UINT8)SwContext.SwSmiInputValue; + DEBUG ((DEBUG_INFO, "MemoryClear SoftwareSmi: 0x%X\n", (UINT8)SwContext.= SwSmiInputValue)); + + // + // Locate SmmVariableProtocol. + // + Status =3D gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL,= (VOID **)&mSmmVariable); + ASSERT_EFI_ERROR (Status); + + // + // Set TPM2 ACPI table + // + Status =3D PublishTpm2 (); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tcg2Smm.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityP= kg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h new file mode 100644 index 0000000000..b1fda8c6b4 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tcg2Smm.h @@ -0,0 +1,123 @@ +/** @file + The header file for Tcg2 SMM driver. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef TCG2_SMM_H____ +#define TCG2_SMM_H____ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(1) +typedef struct { + UINT8 SoftwareSmi; + UINT32 Parameter; + UINT32 Response; + UINT32 Request; + UINT32 RequestParameter; + UINT32 LastRequest; + UINT32 ReturnCode; +} PHYSICAL_PRESENCE_NVS; + +typedef struct { + UINT8 SoftwareSmi; + UINT32 Parameter; + UINT32 Request; + UINT32 ReturnCode; +} MEMORY_CLEAR_NVS; + +typedef struct { + PHYSICAL_PRESENCE_NVS PhysicalPresence; + MEMORY_CLEAR_NVS MemoryClear; + UINT32 PPRequestUserConfirm; + UINT32 TpmIrqNum; + BOOLEAN IsShortFormPkgLength; +} TCG_NVS; + +typedef struct { + UINT8 OpRegionOp; + UINT32 NameString; + UINT8 RegionSpace; + UINT8 DWordPrefix; + UINT32 RegionOffset; + UINT8 BytePrefix; + UINT8 RegionLen; +} AML_OP_REGION_32_8; +#pragma pack() + +// +// The definition for TCG MOR +// +#define ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE 1 +#define ACPI_FUNCTION_PTS_CLEAR_MOR_BIT 2 + +// +// The return code for Memory Clear Interface Functions +// +#define MOR_REQUEST_SUCCESS 0 +#define MOR_REQUEST_GENERAL_FAILURE 1 + +// +// Physical Presence Interface Version supported by Platform +// +#define PHYSICAL_PRESENCE_VERSION_TAG "$PV" +#define PHYSICAL_PRESENCE_VERSION_SIZE 4 + +// +// PNP _HID for TPM2 device +// +#define TPM_HID_TAG "NNNN0000" +#define TPM_HID_PNP_SIZE 8 +#define TPM_HID_ACPI_SIZE 9 + +#define TPM_PRS_RESL "RESL" +#define TPM_PRS_RESS "RESS" +#define TPM_PRS_RES_NAME_SIZE 4 +// +// Minimum PRS resource template size +// 1 byte for BufferOp +// 1 byte for PkgLength +// 2 bytes for BufferSize +// 12 bytes for Memory32Fixed descriptor +// 5 bytes for Interrupt descriptor +// 2 bytes for END Tag +// +#define TPM_POS_RES_TEMPLATE_MIN_SIZE (1 + 1 + 2 + 12 + 5 + 2) + +// +// Max Interrupt buffer size for PRS interrupt resource +// Now support 15 interrupts in maxmum +// +#define MAX_PRS_INT_BUF_SIZE (15*4) +#endif // __TCG_SMM_H__ diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tcg2Smm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Securit= yPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf new file mode 100644 index 0000000000..52419f55ea --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tcg2Smm.inf @@ -0,0 +1,92 @@ +## @file +# Provides ACPI methods for fTPM 2.0 support +# +# Spec Compliance Info: +# "TCG ACPI Specification Level 00 Revision 00.37" +# "Physical Presence Interface Specification Version 1.30 Revision 00.= 52" +# "Platform Reset Attack Mitigation Specification Version 1.00" +# TPM2.0 ACPI device object +# "TCG PC Client Platform Firmware Profile Specification for TPM Famil= y 2.0 Level 00 Revision 00.21" +# +# This driver implements TPM 2.0 definition block in ACPI table and +# registers SMI callback functions for Tcg2 physical presence and +# MemoryClear to handle the requests from ACPI method. +# +# Caution: This module requires additional review when modified. +# This driver will have external input - variable and ACPINvs data in SMM= mode. +# This external input must be validated carefully to avoid security issue= . +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tcg2Smm + MODULE_UNI_FILE =3D Tcg2Smm.uni + FILE_GUID =3D 44A20657-10B8-4049-A148-ACD8812AF257 + MODULE_TYPE =3D DXE_SMM_DRIVER + PI_SPECIFICATION_VERSION =3D 0x0001000A + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InitializeTcgSmm + +[Sources] + Tcg2Smm.h + Tcg2Smm.c + Tpm.asl + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + ChachaniBoardPkg/Project.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + UefiDriverEntryPoint + SmmServicesTableLib + UefiBootServicesTableLib + DebugLib + DxeServicesLib + TpmMeasurementLib + Tcg2PhysicalPresenceLib + PcdLib + # AmdPspCommonLib + +[Guids] + ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl" + ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl" + gEfiMemoryOverwriteControlDataGuid + gEfiTpmDeviceInstanceTpm20DtpmGuid ## CONSUME= S ## GUID # TPM device identifier + +[Protocols] + gEfiSmmSwDispatch2ProtocolGuid ## CONSUME= S + gEfiSmmVariableProtocolGuid ## CONSUME= S + gEfiAcpiTableProtocolGuid ## CONSUME= S + +[Pcd] + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## SOMETIM= ES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## SOMETIM= ES_CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer ## CON= SUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev ## CON= SUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass ## SOM= ETIMES_CONSUMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum ## CONSUME= S + gEfiSecurityPkgTokenSpaceGuid.PcdTpm2PossibleIrqNumBuf ## CONSUME= S + gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress + +[Depex] + gEfiAcpiTableProtocolGuid AND + gEfiSmmSwDispatch2ProtocolGuid AND + gEfiSmmVariableProtocolGuid AND + gEfiTcg2ProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + Tcg2SmmExtra.uni diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tcg2Smm.uni b/Platform/AMD/VanGoghBoard/Override/edk2/Securit= yPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni new file mode 100644 index 0000000000..17618d7fe5 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tcg2Smm.uni @@ -0,0 +1,35 @@ +// ***********************************************************************= ****** +// +// * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<= BR> +// * SPDX-License-Identifier: BSD-2-Clause-Patent +// ***********************************************************************= ****** +// */ + +// /** @file +// Provides ACPI metholds for fTPM 2.0 support +// +// This driver implements TPM 2.0 definition block in ACPI table and +// registers SMI callback functions for TCG2 physical presence and +// MemoryClear to handle the requests from ACPI method. +// +// Caution: This module requires additional review when modified. +// This driver will have external input - variable and ACPINvs data in SMM= mode. +// This external input must be validated carefully to avoid security issue= . +// +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the B= SD License +// which accompanies this distribution. The full text of the license may b= e found at +// http://opensource.org/licenses/bsd-license.php +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides ACPI met= holds for TPM 2.0 support" + +#string STR_MODULE_DESCRIPTION #language en-US "This driver imple= ments TPM 2.0 definition block in ACPI table and registers SMI callback fun= ctions for TCG2 physical presence and MemoryClear to handle the requests fr= om ACPI method.\n" + "Caution: This mod= ule requires additional review when modified. This driver will have externa= l input - variable and ACPINvs data in SMM mode. This external input must b= e validated carefully to avoid security issues." + diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tcg2SmmExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/Se= curityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni new file mode 100644 index 0000000000..b85ec10eba --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tcg2SmmExtra.uni @@ -0,0 +1,15 @@ +// /** @file +// Tcg2Smm Localized Strings and Content +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"TCG2 (Trusted Computing Group) SMM" + + diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtp= m/FtpmTcg2Smm/Tpm.asl b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg= /Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl new file mode 100644 index 0000000000..297805b840 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmT= cg2Smm/Tpm.asl @@ -0,0 +1,408 @@ +/*************************************************************************= **** + * + * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + * SPDX-License-Identifier: BSD-2-Clause-Patent + *************************************************************************= ***** + */ + +/** @file + The TPM2 definition block in ACPI table for TCG2 physical presence + and MemoryClear. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+(c)Copyright 2016 HP Development Company, L.P.
+Copyright (c) 2017, Microsoft Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD = License +which accompanies this distribution. The full text of the license may be = found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLI= ED. + +**/ + +DefinitionBlock ( + "Tpm.aml", + "SSDT", + 2, + "AMD ", + "Tpm2Tabl", + 0x1000 + ) +{ + Scope (\_SB) + { + Device (TPM) + { + // + // TCG2 + // + + // + // TAG for patching TPM2.0 _HID + // + Name (_HID, "MSFT0101") + + Name (_CID, "MSFT0101") + + // + // Readable name of this device, don't know if this way is correct y= et + // + Name (_STR, Unicode ("TPM 2.0 Device")) + + // + // Return the resource consumed by TPM device + // + Name (_CRS, ResourceTemplate () { + Memory32Fixed (ReadWrite, 0xA5A5A5A5, 0x4000) // Command Address + Memory32Fixed (ReadWrite, 0xAAAAAAAA, 0x4000) // Response Address + }) + + // + // Operational region for Smi port access, FixedPcdGet16 (PcdAmdFchC= fgSmiCmdPortAddr) + // + OperationRegion (SMIP, SystemIO, 0xB0, 1) + Field (SMIP, ByteAcc, NoLock, Preserve) + { + IOB0, 8 + } + + // + // Operational region for fTPM control area. + // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code. + // + OperationRegion (TPMC, SystemMemory, 0xFFFF0000, 0xF0) + Field (TPMC, DWordAcc, NoLock, Preserve) + { + REQS, 32, + STAS, 32, + CANC, 32, + STAR, 32, + AccessAs (QWordAcc, 0), + INTC, 64, + AccessAs (DWordAcc, 0), + CMDS, 32, + AccessAs (QWordAcc, 0), + CMDA, 64, + AccessAs (DWordAcc, 0), + RSPS, 32, + AccessAs (QWordAcc, 0), + RSPA, 64 + } + + // + // Operational region for TPM support, TPM Physical Presence and TPM= Memory Clear + // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code. + // + OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0) + Field (TNVS, AnyAcc, NoLock, Preserve) + { + PPIN, 8, // Software SMI for Physical Presence Interface + PPIP, 32, // Used for save physical presence paramter + PPRP, 32, // Physical Presence request operation response + PPRQ, 32, // Physical Presence request operation + PPRM, 32, // Physical Presence request operation parameter + LPPR, 32, // Last Physical Presence request operation + FRET, 32, // Physical Presence function return code + MCIN, 8, // Software SMI for Memory Clear Interface + MCIP, 32, // Used for save the Mor paramter + MORD, 32, // Memory Overwrite Request Data + MRET, 32, // Memory Overwrite function return code + UCRQ, 32 // Phyical Presence request operation to Get User Co= nfirmation Status + } + + Method (PTS, 1, Serialized) + { + // + // Detect Sx state for MOR, only S4, S5 need to handle + // + If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3))) + { + // + // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect. + // + If (LNot (And (MORD, 0x10))) + { + // + // Trigger the SMI through ACPI _PTS method. + // + Store (0x02, MCIP) + + // + // Trigger the SMI interrupt + // + Store (MCIN, IOB0) + } + } + Return (0) + } + + Method (_STA, 0) + { + Return (0x0f) + } + + // + // TCG Hardware Information + // + Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, Unkn= ownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger(Arg1)) + { + Case (0) + { + // + // Standard query + // + Return (Buffer () {0x03}) + } + Case (1) + { + // + // Return failure if no TPM present + // + Name(TPMV, Package () {0x01, Package () {0x2, 0x0}}) + if (LEqual (_STA (), 0x00)) + { + Return (Package () {0x00}) + } + + // + // Return TPM version + // + Return (TPMV) + } + Default {BreakPoint} + } + Return (Buffer () {0}) + } + + Name(TPM2, Package (0x02){ + Zero, + Zero + }) + + Name(TPM3, Package (0x03){ + Zero, + Zero, + Zero + }) + + // + // TCG Physical Presence Interface + // + Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {= UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger(Arg1)) + { + Case (0) + { + // + // Standard query, supports function 1-8 + // + Return (Buffer () {0xFF, 0x01}) + } + Case (1) + { + // + // a) Get Physical Presence Interface Version + // + Return ("$PV") + } + Case (2) + { + // + // b) Submit TPM Operation Request to Pre-OS Environment + // + Store (DerefOf (Index (Arg2, 0x00)), PPRQ) + Store (0, PPRM) + Store (0x02, PPIP) + // + // Trigger the SMI interrupt + // + Store (PPIN, IOB0) + Return (FRET) + + + } + Case (3) + { + // + // c) Get Pending TPM Operation Requested By the OS + // + Store (PPRQ, Index (TPM2, 0x01)) + Return (TPM2) + } + Case (4) + { + // + // d) Get Platform-Specific Action to Transition to Pre-OS Env= ironment + // + Return (2) + } + Case (5) + { + // + // e) Return TPM Operation Response to OS Environment + // + Store (0x05, PPIP) + // + // Trigger the SMI interrupt + // + Store (PPIN, IOB0) + Store (LPPR, Index (TPM3, 0x01)) + Store (PPRP, Index (TPM3, 0x02)) + + Return (TPM3) + } + Case (6) + { + + // + // f) Submit preferred user language (Not implemented) + // + + Return (3) + + } + Case (7) + { + // + // g) Submit TPM Operation Request to Pre-OS Environment 2 + // + Store (7, PPIP) + Store (DerefOf (Index (Arg2, 0x00)), PPRQ) + Store (0, PPRM) + If (LEqual (PPRQ, 23)) { + Store (DerefOf (Index (Arg2, 0x01)), PPRM) + } + // + // Trigger the SMI interrupt + // + Store (PPIN, IOB0) + Return (FRET) + } + Case (8) + { + // + // e) Get User Confirmation Status for Operation + // + Store (8, PPIP) + Store (DerefOf (Index (Arg2, 0x00)), UCRQ) + // + // Trigger the SMI interrupt + // + Store (PPIN, IOB0) + Return (FRET) + } + + Default {BreakPoint} + } + Return (1) + } + + Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, Unk= nownObj}) // IntObj, IntObj, PkgObj + { + // + // Switch by function index + // + Switch (ToInteger (Arg1)) + { + Case (0) + { + // + // Standard query, supports function 1-1 + // + Return (Buffer () {0x03}) + } + Case (1) + { + // + // Save the Operation Value of the Request to MORD (reserved m= emory) + // + Store (DerefOf (Index (Arg2, 0x00)), MORD) + // + // Trigger the SMI through ACPI _DSM method. + // + Store (0x01, MCIP) + // + // Trigger the SMI interrupt + // + Store (MCIN, IOB0) + Return (MRET) + } + Default {BreakPoint} + } + Return (1) + } + + // ACPI Start Method to permit the OS to request the firmware to exe= cute or cancel a TPM 2.0 command. + Method (TPMS, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {= UnknownObj, UnknownObj, UnknownObj}) + { + // + // Switch by function index + // + Switch (ToInteger(Arg1)) { + + Case (0) { + // + // Standard query, supports function 1 + // + Return (Buffer () {0x03}) + } + + Case (1) { + // + // Start + // + Return (0) + } + + Default {BreakPoint} + } + Return (1) + } + + Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj= , PkgObj}) + { + // + // TCG Hardware Information + // + If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8"))) + { + Return (HINF (Arg1, Arg2, Arg3)) + } + // + // TCG Physical Presence Interface + // + If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653"))) + { + Return (TPPI (Arg1, Arg2, Arg3)) + } + // + // TCG Memory Clear Interface + // + If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d"))) + { + Return (TMCI (Arg1, Arg2, Arg3)) + } + // + // ACPI Start Method + // + If(LEqual (Arg0, ToUUID ("6bbf6cab-5463-4714-b7cd-f0203c0368d4"))) + { + Return (TPMS (Arg1, Arg2, Arg3)) + } + + Return (Buffer () {0}) + } + } + } +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/Tcg2ConfigNvData.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityP= kg/Tcg/Tcg2Config/Tcg2ConfigNvData.h new file mode 100644 index 0000000000..86b9362d9f --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tc= g2ConfigNvData.h @@ -0,0 +1,124 @@ +/** @file + Header file for NV data structure definition. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef TCG2_CONFIG_NV_DATA_H____ +#define TCG2_CONFIG_NV_DATA_H____ + +#include +#include +#include + +// +// BUGBUG: In order to pass VfrCompiler, we have to redefine below MACRO, = which already in . +// +#ifndef TCG2_H____ +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001 +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002 +#endif +#define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 = | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + +#define TCG2_CONFIGURATION_VARSTORE_ID 0x0001 +#define TCG2_CONFIGURATION_INFO_VARSTORE_ID 0x0002 +#define TCG2_VERSION_VARSTORE_ID 0x0003 +#define TCG2_CONFIGURATION_FORM_ID 0x0001 + +#define KEY_TPM_DEVICE 0x2000 +#define KEY_TPM2_OPERATION 0x2001 +#define KEY_TPM2_OPERATION_PARAMETER 0x2002 +#define KEY_TPM2_PCR_BANKS_REQUEST_0 0x2003 +#define KEY_TPM2_PCR_BANKS_REQUEST_1 0x2004 +#define KEY_TPM2_PCR_BANKS_REQUEST_2 0x2005 +#define KEY_TPM2_PCR_BANKS_REQUEST_3 0x2006 +#define KEY_TPM2_PCR_BANKS_REQUEST_4 0x2007 +#define KEY_TPM_DEVICE_INTERFACE 0x2008 +#define KEY_TCG2_PPI_VERSION 0x2009 +#define KEY_TPM2_ACPI_REVISION 0x200A + +#define TPM_DEVICE_NULL 0 +#define TPM_DEVICE_1_2 1 +#define TPM_DEVICE_2_0_DTPM 2 +#define TPM_DEVICE_MIN TPM_DEVICE_1_2 +#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM +#define TPM_DEVICE_DEFAULT TPM_DEVICE_2_0_DTPM + +#define TPM2_ACPI_REVISION_3 3 +#define TPM2_ACPI_REVISION_4 4 + +#define TPM_DEVICE_INTERFACE_TIS 0 +#define TPM_DEVICE_INTERFACE_PTP_FIFO 1 +#define TPM_DEVICE_INTERFACE_PTP_CRB 2 +#define TPM_DEVICE_INTERFACE_MAX TPM_DEVICE_INTERFACE_PTP_FIFO +#define TPM_DEVICE_INTERFACE_DEFAULT TPM_DEVICE_INTERFACE_PTP_CRB + +#define TCG2_PROTOCOL_VERSION_DEFAULT 0x0001 +#define EFI_TCG2_EVENT_LOG_FORMAT_DEFAULT EFI_TCG2_EVENT_LOG_FORMAT_TCG_1= _2 + +#define TCG2_PPI_VERSION_1_2 0x322E31 // "1.2" +#define TCG2_PPI_VERSION_1_3 0x332E31 // "1.3" + +// +// Nv Data structure referenced by IFR, TPM device user desired +// +typedef struct { + UINT8 TpmDevice; +} TCG2_CONFIGURATION; + +typedef struct { + UINT64 PpiVersion; + UINT8 Tpm2AcpiTableRev; +} TCG2_VERSION; + +typedef struct { + BOOLEAN Sha1Supported; + BOOLEAN Sha256Supported; + BOOLEAN Sha384Supported; + BOOLEAN Sha512Supported; + BOOLEAN Sm3Supported; + UINT8 TpmDeviceInterfaceAttempt; + BOOLEAN TpmDeviceInterfacePtpFifoSupported; + BOOLEAN TpmDeviceInterfacePtpCrbSupported; +} TCG2_CONFIGURATION_INFO; + +// +// Variable saved for S3, TPM detected, only valid in S3 path. +// This variable is ReadOnly. +// +typedef struct { + UINT8 TpmDeviceDetected; +} TCG2_DEVICE_DETECTION; + +#define TCG2_STORAGE_NAME L"TCG2_CONFIGURATION" +#define TCG2_STORAGE_INFO_NAME L"TCG2_CONFIGURATION_INFO" +#define TCG2_DEVICE_DETECTION_NAME L"TCG2_DEVICE_DETECTION" +#define TCG2_VERSION_NAME L"TCG2_VERSION" + +#define TPM_INSTANCE_ID_LIST { \ + {TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \ + {TPM_DEVICE_INTERFACE_TPM12, TPM_DEVICE_1_2}, \ + {TPM_DEVICE_INTERFACE_TPM20_DTPM, TPM_DEVICE_2_0_DTPM}, \ +} + +// +// BUGBUG: In order to pass VfrCompiler, we have to redefine GUID here. +// +#ifndef __BASE_H__ +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} GUID; +#endif + +typedef struct { + GUID TpmInstanceGuid; + UINT8 TpmDevice; +} TPM_INSTANCE_ID; + +#endif diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/Tcg2ConfigPei.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPk= g/Tcg/Tcg2Config/Tcg2ConfigPei.inf new file mode 100644 index 0000000000..e1530fb874 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tc= g2ConfigPei.inf @@ -0,0 +1,77 @@ +## @file +# Set TPM device type +# +# This module initializes TPM device type based on variable and detection= . +# NOTE: This module is only for reference only, each platform should have= its own setup page. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D Tcg2ConfigPei + MODULE_UNI_FILE =3D Tcg2ConfigPei.uni + FILE_GUID =3D EADD5061-93EF-4CCC-8450-F78A7F0820F0 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D Tcg2ConfigPeimEntryPoint + +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# +# [BootMode] +# S3_RESUME ## SOMETIMES_CONSUMES +# + +[Sources] + Tcg2ConfigPeim.c + Tcg2ConfigNvData.h + TpmDetection.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + ChachaniBoardPkg/Project.dec + AgesaPublic/AgesaPublic.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + PeiServicesLib + PeimEntryPoint + DebugLib + PcdLib + Tpm2CommandLib + Tpm2DeviceLib + IoLib + PciExpressLib + +[Guids] + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION" + ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION" + gTcg2ConfigFormSetGuid + gEfiTpmDeviceSelectedGuid ## PRODUCES ## GUID #= Used as a PPI GUID + gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_CONSUMES ## GUID #= TPM device identifier + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES + gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES + +[Pcd] + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PROD= UCES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy ## PROD= UCES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection ## CONS= UMES + gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOME= TIMES_CONSUMES + gPlatformPkgTokenSpaceGuid.PcdSpiDtpmEnabled + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid AND + gEfiPeiMasterBootModePpiGuid AND + gEfiPeiReadOnlyVariable2PpiGuid + +[UserExtensions.TianoCore."ExtraFiles"] + Tcg2ConfigPeiExtra.uni diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/Tcg2ConfigPei.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPk= g/Tcg/Tcg2Config/Tcg2ConfigPei.uni new file mode 100644 index 0000000000..4d1e7ae6ac --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tc= g2ConfigPei.uni @@ -0,0 +1,14 @@ +// /** @file +// Set TPM device type +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +#string STR_MODULE_ABSTRACT #language en-US "Set TPM device ty= pe" + +#string STR_MODULE_DESCRIPTION #language en-US "This module initi= alizes TPM device type based on variable and detection.\n" + "NOTE: This module= is only for reference only, each platform should have its own setup page." + diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/Tcg2ConfigPeiExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/Secur= ityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni new file mode 100644 index 0000000000..0e79ee614a --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tc= g2ConfigPeiExtra.uni @@ -0,0 +1,15 @@ +// /** @file +// Tcg2ConfigDxe Localized Strings and Content +// +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2015, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"TCG2 (Trusted Computing Group) Configuration DXE" + + diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/Tcg2ConfigPeim.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg= /Tcg/Tcg2Config/Tcg2ConfigPeim.c new file mode 100644 index 0000000000..9d90581388 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tc= g2ConfigPeim.c @@ -0,0 +1,148 @@ +/** @file + The module entry point for Tcg2 configuration module. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Tcg2ConfigNvData.h" + +TPM_INSTANCE_ID mTpmInstanceId[] =3D TPM_INSTANCE_ID_LIST; + +CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi =3D { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTpmDeviceSelectedGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList =3D { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gPeiTpmInitializationDonePpiGuid, + NULL +}; + +/** + This routine check both SetupVariable and real TPM device, and return fi= nal TpmDevice configuration. + + @param SetupTpmDevice TpmDevice configuration in setup driver + + @return TpmDevice configuration +**/ +UINT8 +DetectTpmDevice ( + IN UINT8 SetupTpmDevice + ); + +/** + The entry point for Tcg2 configuration driver. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCES Convert variable to PCD successfully. + @retval Others Fail to convert variable to PCD. +**/ +EFI_STATUS +EFIAPI +Tcg2ConfigPeimEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINTN Size; + EFI_STATUS Status; + EFI_STATUS Status2; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; + TCG2_CONFIGURATION Tcg2Configuration; + UINTN Index; + UINT8 TpmDevice; + + Status =3D PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NU= LL, (VOID **)&VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size =3D sizeof (Tcg2Configuration); + Status =3D VariablePpi->GetVariable ( + VariablePpi, + TCG2_STORAGE_NAME, + &gTcg2ConfigFormSetGuid, + NULL, + &Size, + &Tcg2Configuration + ); + if (EFI_ERROR (Status)) { + // + // Variable not ready, set default value + // + Tcg2Configuration.TpmDevice =3D TPM_DEVICE_DEFAULT; + } + + // + // Validation + // + if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration= .TpmDevice < TPM_DEVICE_MIN)) { + Tcg2Configuration.TpmDevice =3D TPM_DEVICE_DEFAULT; + } + + // + // Although we have SetupVariable info, we still need detect TPM device = manually. + // + DEBUG ((DEBUG_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2= Configuration.TpmDevice)); + + if (PcdGetBool (PcdTpmAutoDetection)) { + TpmDevice =3D DetectTpmDevice (Tcg2Configuration.TpmDevice); + DEBUG ((DEBUG_INFO, "TpmDevice final: %x\n", TpmDevice)); + if (TpmDevice !=3D TPM_DEVICE_NULL) { + Tcg2Configuration.TpmDevice =3D TpmDevice; + } + } else { + TpmDevice =3D Tcg2Configuration.TpmDevice; + } + + // + // Convert variable to PCD. + // This is work-around because there is no gurantee DynamicHiiPcd can re= turn correct value in DXE phase. + // Using DynamicPcd instead. + // + // NOTE: Tcg2Configuration variable contains the desired TpmDevice type, + // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice typ= e + // + for (Index =3D 0; Index < sizeof (mTpmInstanceId)/sizeof (mTpmInstanceId= [0]); Index++) { + if (TpmDevice =3D=3D mTpmInstanceId[Index].TpmDevice) { + Size =3D sizeof (mTpmInstanceId[Index].TpmInstanceGuid); + Status =3D PcdSetPtrS (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[In= dex].TpmInstanceGuid); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].Tp= mInstanceGuid)); + break; + } + } + + // + // Selection done + // + Status =3D PeiServicesInstallPpi (&gTpmSelectedPpi); + ASSERT_EFI_ERROR (Status); + + // + // Even if no TPM is selected or detected, we still need intall TpmIniti= alizationDonePpi. + // Because TcgPei or Tcg2Pei will not run, but we still need a way to no= tify other driver. + // Other driver can know TPM initialization state by TpmInitializedPpi. + // + if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceN= oneGuid)) { + Status2 =3D PeiServicesInstallPpi (&mTpmInitializationDonePpiList); + ASSERT_EFI_ERROR (Status2); + } + + return Status; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Co= nfig/TpmDetection.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/T= cg/Tcg2Config/TpmDetection.c new file mode 100644 index 0000000000..4a31738b13 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tp= mDetection.c @@ -0,0 +1,99 @@ +/** @file + fTPM2.0/dTPM2.0 auto detection. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2015 - 2016, 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 "Tcg2ConfigNvData.h" + +EFI_STATUS +InitDtpmInterface ( + IN VOID + ) +{ + return EFI_SUCCESS; +} + +/** + This routine check both SetupVariable and real TPM device, and return fi= nal TpmDevice configuration. + + @param SetupTpmDevice TpmDevice configuration in setup driver + + @return TpmDevice configuration +**/ +UINT8 +DetectTpmDevice ( + IN UINT8 SetupTpmDevice + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + TCG2_DEVICE_DETECTION Tcg2DeviceDetection; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; + UINTN Size; + + Status =3D PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + // + // In S3, we rely on normal boot Detection, because we save to ReadOnly = Variable in normal boot. + // + if (BootMode =3D=3D BOOT_ON_S3_RESUME) { + DEBUG ((DEBUG_INFO, "DetectTpmDevice: S3 mode\n")); + + Status =3D PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, = NULL, (VOID **)&VariablePpi); + ASSERT_EFI_ERROR (Status); + + Size =3D sizeof (TCG2_DEVICE_DETECTION); + ZeroMem (&Tcg2DeviceDetection, sizeof (Tcg2DeviceDetection)); + Status =3D VariablePpi->GetVariable ( + VariablePpi, + TCG2_DEVICE_DETECTION_NAME, + &gTcg2ConfigFormSetGuid, + NULL, + &Size, + &Tcg2DeviceDetection + ); + if (!EFI_ERROR (Status) && + (Tcg2DeviceDetection.TpmDeviceDetected >=3D TPM_DEVICE_MIN) && + (Tcg2DeviceDetection.TpmDeviceDetected <=3D TPM_DEVICE_MAX)) + { + DEBUG ((DEBUG_INFO, "TpmDevice from DeviceDetection: %x\n", Tcg2Devi= ceDetection.TpmDeviceDetected)); + Status =3D Tpm2Startup (TPM_SU_STATE); + return Tcg2DeviceDetection.TpmDeviceDetected; + } + } + + DEBUG ((DEBUG_INFO, "DetectTpmDevice:\n")); + + Status =3D Tpm2RequestUseTpm (); + if (EFI_ERROR (Status)) { + // + // TPM 2.0 not available + // + return TPM_DEVICE_NULL; + } + + Status =3D Tpm2Startup (TPM_SU_CLEAR); + DEBUG ((DEBUG_INFO, "Tpm2Startup: %r\n", Status)); + if (EFI_ERROR (Status)) { + return TPM_DEVICE_NULL; + } + + return TPM_DEVICE_2_0_DTPM; +} -- 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 (#114513): https://edk2.groups.io/g/devel/message/114513 Mute This Topic: https://groups.io/mt/103971410/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-