[edk2-devel] [PATCH 20/33] AMD/VanGoghBoard: Check in FTPM module.

duke.zhai via groups.io posted 33 patches 7 months, 3 weeks ago
There is a newer version of this series
[edk2-devel] [PATCH 20/33] AMD/VanGoghBoard: Check in FTPM module.
Posted by duke.zhai via groups.io 7 months, 3 weeks ago
From: Duke Zhai <Duke.Zhai@amd.com>


BZ #:4640

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 <ken.yao@amd.com>

Cc: Eric Xing <eric.xing@amd.com>

Cc: Duke Zhai <duke.zhai@amd.com>

Cc: Igniculus Fu <igniculus.fu@amd.com>

Cc: Abner Chang <abner.chang@amd.com>

---

 .../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c   |  128 ++

 .../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf |   62 +

 .../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c   |  156 ++

 .../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf |   62 +

 .../AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c |  123 ++

 .../Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf       |   58 +

 .../Tpm2InstanceLibAmdFTpm.inf                |   53 +

 .../Tpm2InstanceLibAmdFTpmDxe.c               |  109 ++

 .../Tpm2InstanceLibAmdFTpmPei.c               |  153 ++

 .../DxeTcg2PhysicalPresenceLib.c              | 1284 +++++++++++++++++

 .../DxeTcg2PhysicalPresenceLib.inf            |   82 ++

 .../DxeTcg2PhysicalPresenceLib.uni            |   38 +

 .../PhysicalPresenceStrings.uni               |   72 +

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c         |  869 +++++++++++

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h         |  138 ++

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf       |  106 ++

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni       |   35 +

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni  |   30 +

 .../Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl           |  408 ++++++

 .../Tcg/Tcg2Config/Tcg2ConfigNvData.h         |  139 ++

 .../Tcg/Tcg2Config/Tcg2ConfigPei.inf          |   91 ++

 .../Tcg/Tcg2Config/Tcg2ConfigPei.uni          |   34 +

 .../Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni     |   30 +

 .../Tcg/Tcg2Config/Tcg2ConfigPeim.c           |  163 +++

 .../SecurityPkg/Tcg/Tcg2Config/TpmDetection.c |  115 ++

 25 files changed, 4538 insertions(+)

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni

 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/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/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

new file mode 100644

index 0000000000..9ea87fafd4

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

@@ -0,0 +1,128 @@

+/** @file

+  Implements Tpm2DeviceLibFtpm.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  This library is TPM2 device router. Platform can register multi TPM2 instance 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 return unsupported.

+

+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved. <BR>

+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 IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Protocol/AmdPspFtpmProtocol.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+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 **)&PspFtpmProtocol);

+}

+

+/**

+  This service enables the sending of commands to the TPM2.

+

+  @param[in]  InputParameterBlockSize  Size of the TPM2 input parameter block.

+  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter block.

+  @param[in]  OutputParameterBlockSize Size of the TPM2 output parameter block.

+  @param[in]  OutputParameterBlock     Pointer to the TPM2 output parameter 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 = EFI_SUCCESS;

+

+  if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {

+    DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));

+    Status = EFI_INVALID_PARAMETER;

+    return Status;

+  }

+

+  Status = 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/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

new file mode 100644

index 0000000000..27f8673668

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

@@ -0,0 +1,62 @@

+## @file

+#  Ftpm TPM 2.0 Device Library DXE Module INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @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 will be final one.

+#  At most one TPM 2.0 instance can be finally registered, and other will return unsupported.

+#

+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tpm2DeviceLibFtpm

+  FILE_GUID                      = E98C81D3-B90D-4D28-AB48-A207C89D44C0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = Tpm2DeviceLib | DXE_DRIVER DXE_RUNTIME_DRIVER

+  CONSTRUCTOR                    = Tpm2DeviceLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = 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/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

new file mode 100644

index 0000000000..32f63b78ee

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c

@@ -0,0 +1,156 @@

+/** @file

+  Implements Tpm2DeviceLibFtpm.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  This library is TPM2 device router. Platform can register multi TPM2 instance 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 return unsupported.

+

+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved. <BR>

+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 IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Pi/PiPeiCis.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Ppi/AmdPspFtpmPpi.h>

+

+/**

+  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 block.

+  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter block.

+  @param[in]  OutputParameterBlockSize Size of the TPM2 output parameter block.

+  @param[in]  OutputParameterBlock     Pointer to the TPM2 output parameter 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 = EFI_SUCCESS;

+

+  if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {

+    DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));

+    Status = EFI_INVALID_PARAMETER;

+    return Status;

+  }

+

+  PSP_FTPM_PPI  *PspFtpmPpi;

+

+  Status = (*GetPeiServicesTablePointer ())->LocatePpi (

+                                               GetPeiServicesTablePointer (),

+                                               &gAmdPspFtpmPpiGuid,

+                                               0,

+                                               NULL,

+                                               (VOID **)&PspFtpmPpi

+                                               );

+  if (!EFI_ERROR (Status)) {

+    Status = 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 = (*GetPeiServicesTablePointer ())->LocatePpi (

+                                                             GetPeiServicesTablePointer (),

+                                                             &gAmdPspFtpmPpiGuid,

+                                                             0,

+                                                             NULL,

+                                                             (VOID **)&PspFtpmPpi

+                                                             );

+

+  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/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

new file mode 100644

index 0000000000..a28c76332a

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf

@@ -0,0 +1,62 @@

+## @file

+#  Ftpm TPM 2.0 Device Library PEI Module INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @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 will be final one.

+#  At most one TPM 2.0 instance can be finally registered, and other will return unsupported.

+#

+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tpm2DeviceLibFtpm

+  FILE_GUID                      = 2E230843-274F-4C14-A4B5-46B6167E7A5C

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = Tpm2DeviceLib | PEIM

+  CONSTRUCTOR                    = Tpm2DeviceLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = 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/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c

new file mode 100644

index 0000000000..daf75fa1b3

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c

@@ -0,0 +1,123 @@

+/** @file

+  Implements Tpm2DeviceLibFtpm.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  This library is TPM2 TCG2 protocol lib.

+

+Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>

+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 IMPLIED.

+

+**/

+

+#include <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Library/AmdPspFtpmLib.h>

+

+/**

+  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 block.

+  @param[in]  InputParameterBlock      Pointer to the TPM2 input parameter block.

+  @param[in]  OutputParameterBlockSize Size of the TPM2 output parameter block.

+  @param[in]  OutputParameterBlock     Pointer to the TPM2 output parameter 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 = EFI_SUCCESS;

+

+  if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {

+    DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));

+    Status = EFI_INVALID_PARAMETER;

+    return Status;

+  }

+

+  Status = 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 = 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/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf

new file mode 100644

index 0000000000..ce3a7c53f1

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf

@@ -0,0 +1,58 @@

+## @file

+#  Ftpm TPM 2.0 Device Library INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @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) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tpm2DeviceLibFtpm

+  FILE_GUID                      = 1E0C813B-46F5-4578-AA2D-E0AFFD89F2F9

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = Tpm2DeviceLib

+  CONSTRUCTOR                    = Tpm2DeviceLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = 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/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf

new file mode 100644

index 0000000000..2b957fd942

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/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.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tpm2InstanceLibAmdFtpm

+  FILE_GUID                      = F1FA6737-93AC-4B72-8906-3EAE247CFF8D

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = NULL

+  CONSTRUCTOR                    = 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/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c b/Platform/AMD/VanGoghBoard/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/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c

@@ -0,0 +1,109 @@

+/** @file

+  Implements Tpm2InstanceLibAmdFTpmDxe.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include <PiDxe.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Library/PcdLib.h>

+#include <Protocol/AmdPspFtpmProtocol.h>

+#include <Library/AmdPspFtpmLib.h>

+

+// gEfiTpmDeviceInstanceTpm20AmdFtpmGuid

+#define TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM  \

+  {0x286bf25a, 0xc2c3, 0x408c, {0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17}}

+

+PSP_FTPM_PROTOCOL  *mfTpmProtocol = NULL;

+

+/**

+  This service enables the sending of commands to the FTPM.

+

+  @param[in]      InputParameterBlockSize  Size of the FTPM input parameter block.

+  @param[in]      InputParameterBlock      Pointer to the FTPM input parameter block.

+  @param[in,out]  OutputParameterBlockSize Size of the FTPM output parameter block.

+  @param[in]      OutputParameterBlock     Pointer to the FTPM output parameter 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, InputParameterBlockSize, 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) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||

+      (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))

+  {

+    Status = mfTpmProtocol->CheckStatus (mfTpmProtocol, &fTpmStatus);

+    DEBUG ((DEBUG_INFO, "fTPM Status = %r\n", Status));

+    return Status;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+TPM2_DEVICE_INTERFACE  mFTpmInternalTpm2Device = {

+  TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM,

+  FTpmSubmitCommand,

+  FTpmRequestUseTpm,

+};

+

+/**

+  The function register FTPM instance.

+

+  @retval EFI_SUCCESS   FTPM instance is registered, or system dose not surpport registr FTPM instance

+**/

+EFI_STATUS

+EFIAPI

+Tpm2InstanceLibAmdFTpmConstructor (

+  VOID

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (

+                  &gAmdPspFtpmProtocolGuid,

+                  NULL,

+                  (VOID **)&mfTpmProtocol

+                  );

+  if (Status == EFI_SUCCESS) {

+    Status = Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device);

+    if (Status == EFI_UNSUPPORTED) {

+      //

+      // Unsupported means platform policy does not need this instance enabled.

+      //

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c b/Platform/AMD/VanGoghBoard/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/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c

@@ -0,0 +1,153 @@

+/** @file

+  Implements Tpm2InstanceLibAmdFTpmPei.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+#include <PiPei.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/DebugLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Library/PcdLib.h>

+#include <Ppi/AmdPspFtpmPpi.h>

+#include <Library/AmdPspFtpmLib.h>

+#include <Guid/TpmInstance.h>

+

+// 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   = sizeof (gEfiTpmDeviceInstanceNoneGuid);

+  Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+EFI_PEI_NOTIFY_DESCRIPTOR  mAmdFtpmFactoryResetPpiCallback = {

+  EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,

+  &gAmdPspFtpmFactoryResetPpiGuid,

+  AmdFtpmFactoryResetCallback

+};

+

+/**

+  This service enables the sending of commands to the FTPM.

+

+  @param[in]      InputParameterBlockSize  Size of the FTPM input parameter block.

+  @param[in]      InputParameterBlock      Pointer to the FTPM input parameter block.

+  @param[in,out]  OutputParameterBlockSize Size of the FTPM output parameter block.

+  @param[in]      OutputParameterBlock     Pointer to the FTPM output parameter 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 = PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID **)&AmdFtpmPpi);

+  if (Status == EFI_SUCCESS) {

+    return AmdFtpmPpi->Execute (AmdFtpmPpi, InputParameterBlock, InputParameterBlockSize, 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) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||

+      (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))

+  {

+    // @todo Test fTPM functionality

+    DEBUG ((DEBUG_INFO, "fTPM is used\n"));

+    return EFI_SUCCESS;

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+TPM2_DEVICE_INTERFACE  mFTpmInternalTpm2Device = {

+  TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM,

+  FTpmSubmitCommand,

+  FTpmRequestUseTpm,

+};

+

+/**

+  The function register FTPM instance.

+

+  @retval EFI_SUCCESS   FTPM instance is registered, or system dose not surpport registr FTPM instance

+**/

+EFI_STATUS

+EFIAPI

+Tpm2InstanceLibAmdFTpmConstructor (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+  PSP_FTPM_PPI  *AmdFtpmPpi;

+

+  if ((PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||

+      (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))

+  {

+    //

+    // AMD HSP f-TPM for EDK2 Core Base, Get the HSP PSP TcgEvetLog before BIOS

+    //

+    Status = PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID **)&AmdFtpmPpi);

+    if (Status == EFI_SUCCESS) {

+      Status = Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device);

+      if (Status == EFI_UNSUPPORTED) {

+        //

+        // Unsupported means platform policy does not need this instance enabled.

+        //

+        return EFI_SUCCESS;

+      }

+    }

+

+    PeiServicesNotifyPpi (&mAmdFtpmFactoryResetPpiCallback);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c

new file mode 100644

index 0000000000..053f565562

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c

@@ -0,0 +1,1284 @@

+/** @file

+  Implements DxeTcg2PhysicalPresenceLib.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @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 validation.

+

+Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/Tcg2Protocol.h>

+#include <Protocol/VariableLock.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PrintLib.h>

+#include <Library/HiiLib.h>

+#include <Library/HobLib.h>

+#include <Guid/EventGroup.h>

+#include <Guid/Tcg2PhysicalPresenceData.h>

+#include <Library/Tpm2CommandLib.h>

+#include <Library/Tcg2PhysicalPresenceLib.h>

+#include <Library/Tcg2PpVendorLib.h>

+

+#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 platform auth change.

+

+  @retval EFI_SUCCESS           Operation completed successfully.

+  @retval EFI_TIMEOUT           The register can't run into the expected status 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 == NULL) {

+    AuthSession = NULL;

+  } else {

+    AuthSession = &LocalAuthSession;

+    ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));

+    LocalAuthSession.sessionHandle = TPM_RS_PW;

+    LocalAuthSession.hmac.size     = PlatformAuth->size;

+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);

+  }

+

+  DEBUG ((EFI_D_INFO, "Tpm2ClearControl ... \n"));

+  Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);

+  DEBUG ((EFI_D_INFO, "Tpm2ClearControl - %r\n", Status));

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  DEBUG ((EFI_D_INFO, "Tpm2Clear ... \n"));

+  Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);

+  DEBUG ((EFI_D_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 platform 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 == NULL) {

+    AuthSession = NULL;

+  } else {

+    AuthSession = &LocalAuthSession;

+    ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));

+    LocalAuthSession.sessionHandle = TPM_RS_PW;

+    LocalAuthSession.hmac.size     = PlatformAuth->size;

+    CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);

+  }

+

+  Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession);

+  DEBUG ((EFI_D_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 platform auth change.

+  @param[in]      CommandCode         Physical presence operation value.

+  @param[in]      CommandParameter    Physical presence operation parameter.

+  @param[in, out] PpiFlags            The physical presence interface flags.

+

+  @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE   Unknown physical presence operation.

+  @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE   Error occurred during sending command to TPM or

+                                                   receiving response from TPM.

+  @retval Others                                   Return code from the TPM 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 = 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 |= 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 &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;

+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:

+      Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);

+      ASSERT_EFI_ERROR (Status);

+

+      //

+      // PP spec requirements:

+      //    Firmware should check that all requested (set) hashing algorithms 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 == 0) || ((CommandParameter & (~TpmHashAlgorithmBitmap)) != 0)) {

+        DEBUG ((DEBUG_ERROR, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter));

+        return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;

+      }

+

+      Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, 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 = 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 = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);

+      ASSERT_EFI_ERROR (Status);

+      Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, 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 |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;

+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;

+

+    case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:

+      PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;

+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:

+      PpiFlags->PPFlags |= 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 &= ~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_DISABLE_BLOCK_SID_FUNC_TRUE:

+      PpiFlags->PPFlags |= 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 &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID;

+      return TCG_PP_OPERATION_RESPONSE_SUCCESS;

+

+    default:

+      if (CommandCode <= 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 = 0;

+  do {

+    Status = gBS->CheckEvent (gST->ConIn->WaitForKey);

+    if (!EFI_ERROR (Status)) {

+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

+      if (Key.ScanCode == SCAN_ESC) {

+        InputKey = Key.ScanCode;

+      }

+

+      if ((Key.ScanCode == SCAN_F10) && !CautionKey) {

+        InputKey = Key.ScanCode;

+      }

+

+      if ((Key.ScanCode == SCAN_F12) && CautionKey) {

+        InputKey = Key.ScanCode;

+      }

+    }

+  } while (InputKey == 0);

+

+  if (InputKey != 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] = 0;

+  if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {

+    if (Buffer[0] != 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) != 0) {

+    if (Buffer[0] != 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) != 0) {

+    if (Buffer[0] != 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) != 0) {

+    if (Buffer[0] != 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) != 0) {

+    if (Buffer[0] != 0) {

+      StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);

+    }

+

+    StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / 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     = NULL;

+  CautionKey  = FALSE;

+  NoPpiInfo   = FALSE;

+  BufSize     = CONFIRM_BUFFER_SIZE;

+  ConfirmText = AllocateZeroPool (BufSize);

+  ASSERT (ConfirmText != NULL);

+

+  mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);

+  ASSERT (mTcg2PpStringPackHandle != 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 = TRUE;

+      TmpStr2    = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:

+      CautionKey = TRUE;

+      NoPpiInfo  = TRUE;

+      TmpStr2    = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:

+      Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);

+      ASSERT_EFI_ERROR (Status);

+

+      ProtocolCapability.Size = sizeof (ProtocolCapability);

+      Status                  = Tcg2Protocol->GetCapability (

+                                                Tcg2Protocol,

+                                                &ProtocolCapability

+                                                );

+      ASSERT_EFI_ERROR (Status);

+

+      Status = Tcg2Protocol->GetActivePcrBanks (

+                               Tcg2Protocol,

+                               &CurrentPCRBanks

+                               );

+      ASSERT_EFI_ERROR (Status);

+

+      CautionKey = TRUE;

+      TmpStr2    = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof (TempBuffer), TpmPpCommandParameter);

+      Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof (TempBuffer2), CurrentPCRBanks);

+

+      TmpStr1 = AllocateZeroPool (BufSize);

+      ASSERT (TmpStr1 != NULL);

+      UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, 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 = TRUE;

+      TmpStr2    = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_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 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:

+      TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:

+      NoPpiInfo = TRUE;

+      TmpStr2   = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_ENABLE_BLOCK_SID));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_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 = TRUE;

+      TmpStr2   = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_DISABLE_BLOCK_SID));

+

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR));

+      UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);

+      FreePool (TmpStr1);

+      break;

+

+    default:

+      ;

+  }

+

+  if (TmpStr2 == NULL) {

+    FreePool (ConfirmText);

+    return FALSE;

+  }

+

+  if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {

+    if (CautionKey) {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));

+    } else {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));

+    }

+

+    StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+    FreePool (TmpStr1);

+

+    if (NoPpiInfo) {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+    }

+

+    TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));

+  } else {

+    if (CautionKey) {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));

+    } else {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));

+    }

+

+    StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+    FreePool (TmpStr1);

+

+    if (NoPpiInfo) {

+      TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));

+      StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);

+      FreePool (TmpStr1);

+    }

+

+    TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));

+  }

+

+  BufSize -= StrSize (ConfirmText);

+  UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);

+

+  DstStr[80] = L'\0';

+  for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {

+    StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, 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 updates parameter value

+  to whether the requested physical presence command already confirmed by user

+

+   @param[in]  TcgPpData                 EFI Tcg2 Physical Presence request data.

+   @param[in]  Flags                     The physical presence interface flags.

+   @param[out] RequestConfirmed          If the physical presence operation command required user confirm from UI.

+                                           True, it indicates the command doesn't require user confirm, or already confirmed

+                                                 in last boot cycle by user.

+                                           False, it indicates the command need 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 = FALSE;

+

+  if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {

+    //

+    // Need TCG2 protocol.

+    //

+    Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);

+    if (EFI_ERROR (Status)) {

+      return FALSE;

+    }

+  }

+

+  switch (TcgPpData->PPRequest) {

+    case TCG2_PHYSICAL_PRESENCE_NO_ACTION:

+      *RequestConfirmed = 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_CLEAR) == 0) {

+        *RequestConfirmed = TRUE;

+      }

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:

+      *RequestConfirmed = 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_CHANGE_PCRS) == 0) {

+        *RequestConfirmed = TRUE;

+      }

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:

+      if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {

+        *RequestConfirmed = TRUE;

+      }

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:

+      *RequestConfirmed = TRUE;

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:

+      if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {

+        *RequestConfirmed = TRUE;

+      }

+

+      break;

+

+    case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:

+      if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {

+        *RequestConfirmed = 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 = 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 >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {

+        IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, 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) != 0) {

+    //

+    // It had been confirmed in last boot, it doesn't need confirm again.

+    //

+    *RequestConfirmed = 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 platform auth change.

+  @param[in, out] TcgPpData         Pointer to the physical presence NV variable.

+  @param[in, out] Flags             Pointer to the physical presence interface 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 == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {

+    //

+    // No operation request

+    //

+    return;

+  }

+

+  if (!Tcg2HaveValidTpmRequest (TcgPpData, *Flags, &RequestConfirmed)) {

+    //

+    // Invalid operation request.

+    //

+    if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {

+      TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;

+    } else {

+      TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;

+    }

+

+    TcgPpData->LastPPRequest      = TcgPpData->PPRequest;

+    TcgPpData->PPRequest          = TCG2_PHYSICAL_PRESENCE_NO_ACTION;

+    TcgPpData->PPRequestParameter = 0;

+

+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+    Status   = gRT->SetVariable (

+                      TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                      &gEfiTcg2PhysicalPresenceGuid,

+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                      DataSize,

+                      TcgPpData

+                      );

+    return;

+  }

+

+  ResetRequired = FALSE;

+  if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {

+    NewFlags              = *Flags;

+    NewPPFlags            = NewFlags.PPFlags;

+    TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);

+    NewFlags.PPFlags      = NewPPFlags;

+  } else {

+    if (!RequestConfirmed) {

+      //

+      // Print confirm text and wait for approval.

+      //

+      DEBUG ((EFI_D_INFO, "Print confirm text and wait for approval.\n"));

+      RequestConfirmed = TRUE;

+      // RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);

+    }

+

+    //

+    // Execute requested physical presence command

+    //

+    TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;

+    NewFlags              = *Flags;

+    if (RequestConfirmed) {

+      TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (

+                                PlatformAuth,

+                                TcgPpData->PPRequest,

+                                TcgPpData->PPRequestParameter,

+                                &NewFlags

+                                );

+    }

+  }

+

+  //

+  // Save the flags if it is updated.

+  //

+  if (CompareMem (Flags, &NewFlags, sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {

+    *Flags = NewFlags;

+    Status = gRT->SetVariable (

+                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                    sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),

+                    &NewFlags

+                    );

+  }

+

+  //

+  // Clear request

+  //

+  if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {

+    TcgPpData->LastPPRequest      = TcgPpData->PPRequest;

+    TcgPpData->PPRequest          = TCG2_PHYSICAL_PRESENCE_NO_ACTION;

+    TcgPpData->PPRequestParameter = 0;

+  }

+

+  //

+  // Save changes

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+  Status   = 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 ((EFI_D_ERROR, "Fail to set variable %S, %r\n", TCG2_PHYSICAL_PRESENCE_VARIABLE, Status));

+    return;

+  }

+

+  if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {

+    DEBUG ((EFI_D_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 >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {

+        if (ResetRequired) {

+          break;

+        } else {

+          return;

+        }

+      }

+

+      if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {

+        break;

+      }

+

+      return;

+  }

+

+  // Print (L"Rebooting system to make TPM2 settings in effect\n");

+  DEBUG ((EFI_D_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 sent to TPM device after

+  the TPM request is confirmed, and one or more reset may be required to make TPM request to

+  take effect.

+

+  This API should be invoked after console in and console out are all ready as they are required

+  to display request information and get user input to confirm the request.

+

+  @param[in]  PlatformAuth                   platform auth value. NULL means 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 for TPM command.

+  // It should be protected from malicious software. We set it as read-only variable here.

+  //

+  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);

+  if (!EFI_ERROR (Status)) {

+    Status = VariableLockProtocol->RequestToLock (

+                                     VariableLockProtocol,

+                                     TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                                     &gEfiTcg2PhysicalPresenceGuid

+                                     );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "[TPM2] Error when lock variable %s, Status = %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 () == BOOT_ON_S4_RESUME) {

+  //    DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));

+  //    return ;

+  //  }

+

+  //

+  // Initialize physical presence flags.

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &PpiFlags

+                    );

+  if (EFI_ERROR (Status)) {

+    PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);

+    Status           = gRT->SetVariable (

+                              TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                              &gEfiTcg2PhysicalPresenceGuid,

+                              EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                              sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),

+                              &PpiFlags

+                              );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));

+      return;

+    }

+

+    DEBUG ((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0x%x\n", PpiFlags.PPFlags));

+  }

+

+  //

+  // Initialize physical presence variable.

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &TcgPpData

+                    );

+  if (EFI_ERROR (Status)) {

+    ZeroMem ((VOID *)&TcgPpData, sizeof (TcgPpData));

+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+    Status   = 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 ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));

+      return;

+    }

+  }

+

+  DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));

+

+  //

+  // Execute pending TPM request.

+  //

+  Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags);

+  DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%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 exists 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 presence.

+

+**/

+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 () == BOOT_ON_S4_RESUME) {

+  //    DEBUG ((EFI_D_INFO, "S4 Resume, Skip TPM PP process!\n"));

+  //    return FALSE;

+  //  }

+

+  //

+  // Check Tpm requests

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &TcgPpData

+                    );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRESENCE_VARIABLE, Status));

+    return FALSE;

+  }

+

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &PpiFlags

+                    );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));

+    return FALSE;

+  }

+

+  if (TcgPpData.PPRequest == 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 ((EFI_D_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));

+

+  //

+  // Get the Physical Presence variable

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &PpData

+                    );

+  if (EFI_ERROR (Status)) {

+    *MostRecentRequest = 0;

+    *Response          = 0;

+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));

+    return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;

+  }

+

+  *MostRecentRequest = PpData.LastPPRequest;

+  *Response          = 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 Environment 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 ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));

+

+  //

+  // Get the Physical Presence variable

+  //

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &PpData

+                    );

+  if (EFI_ERROR (Status)) {

+    DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %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 != OperationRequest) ||

+      (PpData.PPRequestParameter != RequestParameter))

+  {

+    PpData.PPRequest          = (UINT8)OperationRequest;

+    PpData.PPRequestParameter = RequestParameter;

+    DataSize                  = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);

+    Status                    = gRT->SetVariable (

+                                       TCG2_PHYSICAL_PRESENCE_VARIABLE,

+                                       &gEfiTcg2PhysicalPresenceGuid,

+                                       EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                                       DataSize,

+                                       &PpData

+                                       );

+    if (EFI_ERROR (Status)) {

+      DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));

+      return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;

+    }

+  }

+

+  if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {

+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);

+    Status   = gRT->GetVariable (

+                      TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                      &gEfiTcg2PhysicalPresenceGuid,

+                      NULL,

+                      &DataSize,

+                      &Flags

+                      );

+    if (EFI_ERROR (Status)) {

+      Flags.PPFlags = 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 ((EFI_D_INFO, "[TPM2] GetManagementFlags\n"));

+

+  DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);

+  Status   = gRT->GetVariable (

+                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,

+                    &gEfiTcg2PhysicalPresenceGuid,

+                    NULL,

+                    &DataSize,

+                    &PpiFlags

+                    );

+  if (EFI_ERROR (Status)) {

+    PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);

+  }

+

+  return PpiFlags.PPFlags;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf

new file mode 100644

index 0000000000..b0ee10240e

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf

@@ -0,0 +1,82 @@

+## @file

+#  TCG 2.0 Physical Presence DXE Module INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @file

+#  Executes TPM 2.0 requests from OS or BIOS

+#

+#  This library will check and execute TPM 2.0 request from OS or BIOS. The 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) 2013 - 2016, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeTcg2PhysicalPresenceLib

+  MODULE_UNI_FILE                = DxeTcg2PhysicalPresenceLib.uni

+  FILE_GUID                      = 7E507A86-DE8B-4AD3-BC4C-0498389098D3

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = Tcg2PhysicalPresenceLib|DXE_DRIVER DXE_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           = 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       ## SOMETIMES_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/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni

new file mode 100644

index 0000000000..ac2e78d735

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni

@@ -0,0 +1,38 @@

+// /** @file

+// TCG 2.0 Physical Presence Library uni file

+//

+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+//

+// SPDX-License-Identifier: BSD-2-Clause-Patent

+//

+// **/

+// This file includes code originally published under the following license.

+// */

+

+// /** @file

+// Executes TPM 2.0 requests from OS or BIOS

+//

+// This library will check and execute TPM 2.0 request from OS or BIOS. The 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) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+//

+// 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 IMPLIED.

+//

+// **/

+

+

+#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 module requires additional review when modified. This driver will have external input - variable. This external input must be validated carefully to avoid security issue."

+

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni

new file mode 100644

index 0000000000..7cf9901046

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni

@@ -0,0 +1,72 @@

+// /** @file

+// Physical Presence String uni file

+//

+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+//

+// SPDX-License-Identifier: BSD-2-Clause-Patent

+//

+// **/

+// This file includes code originally published under the following license.

+// */

+

+/** @file

+  String definitions for TPM 2.0 physical presence confirm text.

+

+Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#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 future.\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 \nPress 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    "disable 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 future Operating System requests "

+

+#string TPM_WARNING_DISABLE           #language en-US    "WARNING: Doing so might prevent security applications that rely on the TPM from functioning as expected.\n\n"

+#string TPM_WARNING_CLEAR             #language en-US    "WARNING: Clearing 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 action does not clear the TPM, but by approving this configuration change, future 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 the 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 machine 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 may 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 operation 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 TPM from functioning as expected.\n\n"

+

+#string TCG_STORAGE_HEAD_STR                  #language en-US    "A configuration change was requested to %s on subsequent boots\n\n"

+#string TCG_STORAGE_PPI_HEAD_STR              #language en-US    "A configuration change was requested to allow the Operating System to %s without asking for user confirmation in the future.\n\n"

+

+#string TCG_STORAGE_ACCEPT_KEY                #language en-US    "Press F10 "

+#string TCG_STORAGE_CAUTION_KEY               #language en-US    "Press F12 "

+#string TCG_STORAGE_REJECT_KEY                #language en-US    "to %s\nPress ESC to reject this change request and continue\n"

+

+#string TCG_STORAGE_NO_PPI_INFO               #language en-US    "to approve 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 blocking 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/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c

new file mode 100644

index 0000000000..f38749298a

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c

@@ -0,0 +1,869 @@

+/** @file

+  Implements Tcg2Smm.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @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 untrusted input and do some check.

+

+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#include "Tcg2Smm.h"

+

+TPM2_CONTROL_AREA  *mFtpmControlArea = NULL;

+

+EFI_TPM2_ACPI_TABLE  mTpm2AcpiTemplate = {

+  {

+    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 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 handler by SmiHandlerRegister().

+  @param[in]      Context         Points to an optional handler context which was specified when the

+                                  handler was registered.

+  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will

+                                  be conveyed from a non-SMM environment into 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 == TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {

+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (

+                                             &MostRecentRequest,

+                                             &Response

+                                             );

+    mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest;

+    mTcgNvs->PhysicalPresence.Response    = Response;

+    return EFI_SUCCESS;

+  } else if (  (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)

+            || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2))

+  {

+    OperationRequest                     = mTcgNvs->PhysicalPresence.Request;

+    RequestParameter                     = mTcgNvs->PhysicalPresence.RequestParameter;

+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (

+                                             &OperationRequest,

+                                             &RequestParameter

+                                             );

+    mTcgNvs->PhysicalPresence.Request          = OperationRequest;

+    mTcgNvs->PhysicalPresence.RequestParameter = RequestParameter;

+  } else if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {

+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (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 handler by SmiHandlerRegister().

+  @param[in]      Context         Points to an optional handler context which was specified when the

+                                  handler was registered.

+  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will

+                                  be conveyed from a non-SMM environment into 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 = MOR_REQUEST_SUCCESS;

+  if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {

+    MorControl = (UINT8)mTcgNvs->MemoryClear.Request;

+  } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {

+    DataSize = sizeof (UINT8);

+    Status   = mSmmVariable->SmmGetVariable (

+                               MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,

+                               &gEfiMemoryOverwriteControlDataGuid,

+                               NULL,

+                               &DataSize,

+                               &MorControl

+                               );

+    if (EFI_ERROR (Status)) {

+      mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;

+      return EFI_SUCCESS;

+    }

+

+    if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {

+      return EFI_SUCCESS;

+    }

+

+    MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;

+  }

+

+  DataSize = sizeof (UINT8);

+  Status   = mSmmVariable->SmmSetVariable (

+                             MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,

+                             &gEfiMemoryOverwriteControlDataGuid,

+                             EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,

+                             DataSize,

+                             &MorControl

+                             );

+  if (EFI_ERROR (Status)) {

+    mTcgNvs->MemoryClear.ReturnCode = 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 region.

+

+**/

+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 = SIZE_4GB - 1;

+

+  //

+  // Patch some pointers for the ASL code before loading the SSDT.

+  //

+  for (OpRegion  = (AML_OP_REGION_32_8 *)(Table + 1);

+       OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);

+       OpRegion  = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))

+  {

+    if ((OpRegion->OpRegionOp  == AML_EXT_REGION_OP) &&

+        (OpRegion->NameString  == Name) &&

+        (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&

+        (OpRegion->BytePrefix  == AML_BYTE_PREFIX))

+    {

+      Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);

+      ASSERT_EFI_ERROR (Status);

+      ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);

+      OpRegion->RegionOffset = (UINT32)(UINTN)MemoryAddress;

+      OpRegion->RegionLen    = (UINT8)Size;

+      break;

+    }

+  }

+

+  return (VOID *)(UINTN)MemoryAddress;

+}

+

+/**

+  Find the fTPM Control Area 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]      ControlAreaAddr  The Control Area address to set.

+  @param[in]      ControlAreaSize  The Control Area size to size.

+

+  @return                          The allocated address for the found region.

+

+**/

+EFI_STATUS

+PatchTpmControlAreaOpRegion (

+  EFI_ACPI_DESCRIPTION_HEADER  *Table,

+  UINT32                       Name,

+  UINT32                       ControlAreaAddr,

+  UINT8                        ControlAreaSize

+  )

+{

+  EFI_STATUS          Status    = EFI_NOT_FOUND;

+  AML_OP_REGION_32_8  *OpRegion = NULL;

+

+  //

+  // Patch some pointers for the ASL code before loading the SSDT.

+  //

+  for (OpRegion  = (AML_OP_REGION_32_8 *)(Table + 1);

+       OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);

+       OpRegion  = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))

+  {

+    if ((OpRegion->OpRegionOp  == AML_EXT_REGION_OP) &&

+        (OpRegion->NameString  == Name) &&

+        (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&

+        (OpRegion->BytePrefix  == AML_BYTE_PREFIX))

+    {

+      OpRegion->RegionOffset = ControlAreaAddr;

+      OpRegion->RegionLen    = ControlAreaSize;

+      Status                 = EFI_SUCCESS;

+      break;

+    }

+  }

+

+  return Status;

+}

+

+/**

+  Patch the Memory32Fixed definitions in TCG ACPI table, and initialize their 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 signature in Memory32Fixed.

+  @param[in]      ResponseAddr   The Response Address to set for certain signature in Memory32Fixed.

+

+  @return                        The allocated address for the found region.

+

+**/

+EFI_STATUS

+AssignMemory32Fixed (

+  EFI_ACPI_DESCRIPTION_HEADER  *Table,

+  UINT32                       CommandAddr,

+  UINT32                       ResponseAddr

+  )

+{

+  EFI_STATUS  Status              = EFI_NOT_FOUND;

+  UINT8       *TmpPtr             = NULL;

+  BOOLEAN     CommandAddrPatched  = FALSE;

+  BOOLEAN     ResponseAddrPatched = FALSE;

+

+  //

+  // Patch some pointers for the ASL code before loading the SSDT.

+  //

+  for (TmpPtr = (UINT8 *)Table; TmpPtr <= (UINT8 *)Table + Table->Length; ) {

+    if (*(UINT32 *)TmpPtr  == 0xA5A5A5A5) {

+      *(UINT32 *)TmpPtr  = CommandAddr;

+      CommandAddrPatched = TRUE;

+      TmpPtr             = TmpPtr + 4;

+    } else if (*(UINT32 *)TmpPtr  == 0xAAAAAAAA) {

+      *(UINT32 *)TmpPtr   = ResponseAddr;

+      ResponseAddrPatched = TRUE;

+      TmpPtr              = TmpPtr + 4;

+    } else if (CommandAddrPatched && ResponseAddrPatched) {

+      Status = EFI_SUCCESS;

+      break;

+    }

+

+    ++TmpPtr;

+  }

+

+  return Status;

+}

+

+/**

+  Patch version string of Physical Presence interface supported by platform. 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 interface supported by platform.

+

+  @return                        The allocated address for the found region.

+

+**/

+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  = (UINT8 *)(Table + 1);

+       DataPtr <= (UINT8 *)((UINT8 *)Table + Table->Length - PHYSICAL_PRESENCE_VERSION_SIZE);

+       DataPtr += 1)

+  {

+    if (AsciiStrCmp ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) == 0) {

+      Status = AsciiStrCpyS ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_SIZE, PPVer);

+      DEBUG ((EFI_D_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 patch 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 Package(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     = 0;

+  OrignalPkgLength = 0;

+  DataEndPtr       = 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

+  //

+  // =============  Buffer ====================

+  //           DefBuffer := BufferOp PkgLength BufferSize ByteList

+  //            BufferOp := 0x11

+  //

+  // ==============PkgLength==================

+  //          PkgLength := PkgLeadByte |

+  //                              <PkgLeadByte ByteData> |

+  //                              <PkgLeadByte ByteData ByteData> |

+  //                              <PkgLeadByte ByteData ByteData ByteData>

+  //

+  //       PkgLeadByte := <bit 7-6: ByteData count that follows (0-3)>

+  //                               <bit 5-4: Only used if PkgLength <= 63 >

+  //                               <bit 3-0: Least significant package length nybble>

+  //

+  // ==============BufferSize==================

+  //        BufferSize := Integar

+  //           Integar := ByteConst|WordConst|DwordConst....

+  //

+  //           ByteConst := BytePrefix ByteData

+  //

+  // ==============ByteList===================

+  //          ByteList := ByteData ByteList

+  //

+  // =========================================

+

+  //

+  // 1. Check TPM_PRS_RESS with PkgLength <=63 can hold the input interrupt number buffer for patching

+  //

+  for (DataPtr  = (UINT8 *)(Table + 1);

+       DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));

+       DataPtr += 1)

+  {

+    if (CompareMem (DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) == 0) {

+      //

+      // Jump over object name & BufferOp

+      //

+      DataPtr += TPM_PRS_RES_NAME_SIZE + 1;

+

+      if ((*DataPtr & (BIT7|BIT6)) == 0) {

+        OrignalPkgLength = (UINT32)*DataPtr;

+        DataEndPtr       = DataPtr + OrignalPkgLength;

+

+        //

+        // Jump over PkgLength = PkgLeadByte only

+        //

+        NewPkgLength++;

+

+        //

+        // Jump over BufferSize

+        //

+        if (*(DataPtr + 1) == AML_BYTE_PREFIX) {

+          NewPkgLength += 2;

+        } else if (*(DataPtr + 1) == AML_WORD_PREFIX) {

+          NewPkgLength += 3;

+        } else if (*(DataPtr + 1) == AML_DWORD_PREFIX) {

+          NewPkgLength += 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 += 19 + IrqBuffserSize;

+      if (NewPkgLength > 63) {

+        break;

+      }

+

+      if (NewPkgLength > OrignalPkgLength) {

+        ASSERT (FALSE);

+        return EFI_INVALID_PARAMETER;

+      }

+

+      //

+      // 1.1 Patch PkgLength

+      //

+      *DataPtr = (UINT8)NewPkgLength;

+

+      //

+      // 1.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).

+      //      It is Little endian. So only patch lowest byte of BufferSize due to current interrupt number limit.

+      //

+      *(DataPtr + 2) = (UINT8)(IrqBuffserSize + 19);

+

+      //

+      // Notify _PRS to report short formed ResourceTemplate

+      //

+      *IsShortFormPkgLength = TRUE;

+

+      break;

+    }

+  }

+

+  //

+  // 2. Use TPM_PRS_RESL with PkgLength > 63 to hold longer input interrupt number buffer for patching

+  //

+  if (NewPkgLength > 63) {

+    NewPkgLength     = 0;

+    OrignalPkgLength = 0;

+    for (DataPtr  = (UINT8 *)(Table + 1);

+         DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));

+         DataPtr += 1)

+    {

+      if (CompareMem (DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) == 0) {

+        //

+        // Jump over object name & BufferOp

+        //

+        DataPtr += TPM_PRS_RES_NAME_SIZE + 1;

+

+        if ((*DataPtr & (BIT7|BIT6)) != 0) {

+          OrignalPkgLength = (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr & 0x0F);

+          DataEndPtr       = DataPtr + OrignalPkgLength;

+          //

+          // Jump over PkgLength = PkgLeadByte + ByteData length

+          //

+          NewPkgLength += 1 + ((*DataPtr & (BIT7|BIT6)) >> 6);

+

+          //

+          // Jump over BufferSize

+          //

+          if (*(DataPtr + NewPkgLength) == AML_BYTE_PREFIX) {

+            NewPkgLength += 2;

+          } else if (*(DataPtr + NewPkgLength) == AML_WORD_PREFIX) {

+            NewPkgLength += 3;

+          } else if (*(DataPtr + NewPkgLength) == AML_DWORD_PREFIX) {

+            NewPkgLength += 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 += 19 + IrqBuffserSize;

+

+        if (NewPkgLength > OrignalPkgLength) {

+          ASSERT (FALSE);

+          return EFI_INVALID_PARAMETER;

+        }

+

+        //

+        // 2.1 Patch PkgLength. Only patch PkgLeadByte and first ByteData

+        //

+        *DataPtr       = (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x0F);

+        *(DataPtr + 1) = (UINT8)((NewPkgLength & 0xFF0) >> 4);

+

+        //

+        // 2.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).

+        //     It is Little endian. Only patch lowest byte of BufferSize due to current interrupt number limit.

+        //

+        *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) = (UINT8)(IrqBuffserSize + 19);

+

+        //

+        // Notify _PRS to report long formed ResourceTemplate

+        //

+        *IsShortFormPkgLength = FALSE;

+        break;

+      }

+    }

+  }

+

+  if (DataPtr >= (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 descriptor.

+  //     5 bytes for interrupt descriptor header, 2 bytes for End Tag

+  //

+  DataPtr += NewPkgLength - (5 + IrqBuffserSize + 2);

+  //

+  //   3.1 Patch Length bit[7:0] of Interrupt descirptor patch interrupt descriptor

+  //

+  *(DataPtr + 1) = (UINT8)(2 + IrqBuffserSize);

+  //

+  //   3.2 Patch Interrupt Table Length

+  //

+  *(DataPtr + 4) = (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 field to 0

+  //

+  DataPtr       += 5 + IrqBuffserSize;

+  *DataPtr       = ACPI_END_TAG_DESCRIPTOR;

+  *(DataPtr + 1) = 0;

+

+  //

+  // 5. Jump over new ResourceTemplate. Stuff rest bytes to NOOP

+  //

+  DataPtr += 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 = FALSE;

+

+  Status = GetSectionFromFv (

+             &gEfiCallerIdGuid,

+             EFI_SECTION_RAW,

+             0,

+             (VOID **)&Table,

+             &TableSize

+             );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Update Table version before measuring it to PCR

+  //

+  Status = UpdatePPVersion (Table, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer));

+  ASSERT_EFI_ERROR (Status);

+

+  DEBUG ((

+    DEBUG_INFO,

+    "Current physical presence interface version - %a\n",

+    (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer)

+    ));

+

+  //

+

+  if (PcdGet32 (PcdTpm2CurrentIrqNum) != 0) {

+    //

+    // Patch _PRS interrupt resource only when TPM interrupt is supported

+    //

+    PossibleIrqNumBuf     = (UINT32 *)PcdGetPtr (PcdTpm2PossibleIrqNumBuf);

+    PossibleIrqNumBufSize = (UINT32)PcdGetSize (PcdTpm2PossibleIrqNumBuf);

+

+    if ((PossibleIrqNumBufSize <= MAX_PRS_INT_BUF_SIZE) && ((PossibleIrqNumBufSize % sizeof (UINT32)) == 0)) {

+      Status = UpdatePossibleResource (Table, PossibleIrqNumBuf, PossibleIrqNumBufSize, &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 == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));

+  CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId));

+

+  DEBUG ((EFI_D_INFO, "FtpmControlArea: 0x%lX\n", (UINTN)(VOID *)mFtpmControlArea));

+  DEBUG ((EFI_D_INFO, "CommandSize: 0x%lX, ResponseSize: 0x%lX \n", mFtpmControlArea->CommandSize, mFtpmControlArea->ResponseSize));

+

+  Status = AssignMemory32Fixed (Table, (UINT32)mFtpmControlArea->CommandAddress, (UINT32)mFtpmControlArea->ResponseAddress);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = PatchTpmControlAreaOpRegion (Table, SIGNATURE_32 ('T', 'P', 'M', 'C'), (UINT32)(UINTN)(VOID *)mFtpmControlArea + 0x10, sizeof (EFI_TPM2_ACPI_CONTROL_AREA));

+  ASSERT_EFI_ERROR (Status);

+

+  mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16)sizeof (TCG_NVS));

+  ASSERT (mTcgNvs != NULL);

+  mTcgNvs->TpmIrqNum            = PcdGet32 (PcdTpm2CurrentIrqNum);

+  mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength;

+

+  //

+  // Publish the TPM ACPI table. Table is re-checksumed.

+  //

+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);

+  ASSERT_EFI_ERROR (Status);

+

+  TableKey = 0;

+  Status   = 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 = PcdGet8 (PcdTpm2AcpiTableRev);

+  DEBUG ((DEBUG_INFO, "Tpm2 ACPI table revision is %d\n", mTpm2AcpiTemplate.Header.Revision));

+

+  //

+  // PlatformClass is only valid for version 4 and above

+  //    BIT0~15:  PlatformClass

+  //    BIT16~31: Reserved

+  //

+  if (mTpm2AcpiTemplate.Header.Revision >= EFI_TPM2_ACPI_TABLE_REVISION_4) {

+    mTpm2AcpiTemplate.Flags = (mTpm2AcpiTemplate.Flags & 0xFFFF0000) | PcdGet8 (PcdTpmPlatformClass);

+    DEBUG ((DEBUG_INFO, "Tpm2 ACPI table PlatformClass is %d\n", (mTpm2AcpiTemplate.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          = EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI;

+  mTpm2AcpiTemplate.AddressOfControlArea = ((UINT64)(UINTN)(VOID *)mFtpmControlArea + 0x10);

+

+  CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));

+  OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);

+  CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));

+  mTpm2AcpiTemplate.Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);

+  mTpm2AcpiTemplate.Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);

+  mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);

+

+  //

+  // Construct ACPI table

+  //

+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = 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 locate

+  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 point.

+

+**/

+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 ((EFI_D_INFO, "InitializeTcgSmm Entry \n"));

+  if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)) {

+    DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n"));

+    return EFI_UNSUPPORTED;

+  }

+

+  // if (!GetFtpmControlArea(&mFtpmControlArea)) {

+  //   DEBUG ((EFI_D_ERROR, "Get fTPM Control Area failed!\n"));

+  //   return EFI_UNSUPPORTED;

+  // }

+  mFtpmControlArea = (VOID *)(UINTN)PcdGet64 (PcdTpmBaseAddress);

+  DEBUG ((EFI_D_INFO, "Get PcdTpmBaseAddress:%x\n", mFtpmControlArea));

+  Status = PublishAcpiTable ();

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get the Sw dispatch protocol and register SMI callback functions.

+  //

+  Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **)&SwDispatch);

+  ASSERT_EFI_ERROR (Status);

+  SwContext.SwSmiInputValue = (UINTN)-1;

+  Status                    = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;

+  DEBUG ((EFI_D_INFO, "PhysicalPresence SoftwareSmi: 0x%X\n", (UINT8)SwContext.SwSmiInputValue));

+

+  SwContext.SwSmiInputValue = (UINTN)-1;

+  Status                    = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);

+  ASSERT_EFI_ERROR (Status);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  mTcgNvs->MemoryClear.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;

+  DEBUG ((EFI_D_INFO, "MemoryClear SoftwareSmi: 0x%X\n", (UINT8)SwContext.SwSmiInputValue));

+

+  //

+  // Locate SmmVariableProtocol.

+  //

+  Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Set TPM2 ACPI table

+  //

+  Status = PublishTpm2 ();

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h

new file mode 100644

index 0000000000..4012942176

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h

@@ -0,0 +1,138 @@

+/** @file

+  Implements Tcg2Smm.h

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  The header file for Tcg2 SMM driver.

+

+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#ifndef __TCG2_SMM_H__

+#define __TCG2_SMM_H__

+

+#include <PiDxe.h>

+#include <IndustryStandard/Acpi.h>

+#include <IndustryStandard/Tpm2Acpi.h>

+

+#include <Guid/MemoryOverwriteControl.h>

+#include <Guid/TpmInstance.h>

+

+#include <Protocol/SmmSwDispatch2.h>

+#include <Protocol/AcpiTable.h>

+#include <Protocol/SmmVariable.h>

+#include <Protocol/Tcg2Protocol.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/SmmServicesTableLib.h>

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DxeServicesLib.h>

+#include <Library/TpmMeasurementLib.h>

+#include <Library/Tpm2CommandLib.h>

+#include <Library/Tcg2PhysicalPresenceLib.h>

+#include <Library/IoLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/AmdPspCommonLib.h>

+#include <Library/AmdPspFtpmLib.h>

+#include <IndustryStandard/TpmPtp.h>

+

+#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/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf

new file mode 100644

index 0000000000..fef93e632a

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf

@@ -0,0 +1,106 @@

+## @file

+#  TCG 2.0 SMM Module INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @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 Family 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) 2015 - 2018, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tcg2Smm

+  MODULE_UNI_FILE                = Tcg2Smm.uni

+  FILE_GUID                      = 44A20657-10B8-4049-A148-ACD8812AF257

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = 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                            ## CONSUMES           ## GUID       # TPM device identifier

+

+[Protocols]

+  gEfiSmmSwDispatch2ProtocolGuid                                ## CONSUMES

+  gEfiSmmVariableProtocolGuid                                   ## CONSUMES

+  gEfiAcpiTableProtocolGuid                                     ## CONSUMES

+

+[Pcd]

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid              ## CONSUMES

+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId            ## SOMETIMES_CONSUMES

+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId       ## SOMETIMES_CONSUMES

+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision      ## SOMETIMES_CONSUMES

+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId        ## SOMETIMES_CONSUMES

+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision  ## SOMETIMES_CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer  ## CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev                 ## CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass                 ## SOMETIMES_CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum            ## CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2PossibleIrqNumBuf        ## CONSUMES

+  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/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni

new file mode 100644

index 0000000000..17618d7fe5

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/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.<BR>

+//

+// 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 IMPLIED.

+//

+// **/

+

+

+#string STR_MODULE_ABSTRACT             #language en-US "Provides ACPI metholds for TPM 2.0 support"

+

+#string STR_MODULE_DESCRIPTION          #language en-US "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.\n"

+                                                        "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 issues."

+

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni

new file mode 100644

index 0000000000..62835b409f

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni

@@ -0,0 +1,30 @@

+// /** @file

+// TCG 2.0 SMM extra uni file

+//

+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+//

+// SPDX-License-Identifier: BSD-2-Clause-Patent

+//

+// **/

+// This file includes code originally published under the following license.

+// */

+

+// /** @file

+// Tcg2Smm Localized Strings and Content

+//

+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>

+//

+// 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 IMPLIED.

+//

+// **/

+

+#string STR_PROPERTIES_MODULE_NAME

+#language en-US

+"TCG2 (Trusted Computing Group) SMM"

+

+

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/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/FtpmTcg2Smm/Tpm.asl

@@ -0,0 +1,408 @@

+/*****************************************************************************

+ *

+ * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+ * 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.<BR>

+(c)Copyright 2016 HP Development Company, L.P.<BR>

+Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>

+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 IMPLIED.

+

+**/

+

+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 yet

+      //

+      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 (PcdAmdFchCfgSmiCmdPortAddr)

+      //

+      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 Confirmation 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, UnknownObj, 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 Environment

+            //

+            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, UnknownObj}) // 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 memory)

+            //

+            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 execute 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/Tcg2Config/Tcg2ConfigNvData.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h

new file mode 100644

index 0000000000..271c99613a

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h

@@ -0,0 +1,139 @@

+/** @file

+  Implements Tcg2ConfigNvData.h

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  Header file for NV data structure definition.

+

+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#ifndef __TCG2_CONFIG_NV_DATA_H__

+#define __TCG2_CONFIG_NV_DATA_H__

+

+#include <Guid/HiiPlatformSetupFormset.h>

+#include <Guid/Tcg2ConfigHii.h>

+#include <IndustryStandard/TcgPhysicalPresence.h>

+

+//

+// BUGBUG: In order to pass VfrCompiler, we have to redefine below MACRO, which already in <Protocol/Tcg2Protocol.h>.

+//

+#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/Tcg2Config/Tcg2ConfigPei.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf

new file mode 100644

index 0000000000..f34c5f7277

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf

@@ -0,0 +1,91 @@

+## @file

+#  TCG 2.0 Config PEI Module INF file

+#

+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+#

+##

+

+# This file includes code originally published under the following license.

+

+## @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) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+# 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 IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = Tcg2ConfigPei

+  MODULE_UNI_FILE                = Tcg2ConfigPei.uni

+  FILE_GUID                      = EADD5061-93EF-4CCC-8450-F78A7F0820F0

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  ENTRY_POINT                    = Tcg2ConfigPeimEntryPoint

+

+#

+#  VALID_ARCHITECTURES           = 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                 ## PRODUCES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy         ## PRODUCES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection                ## CONSUMES

+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress                  ## SOMETIMES_CONSUMES

+  gPlatformPkgTokenSpaceGuid.PcdSpiDtpmEnabled

+

+[Depex]

+  gEfiPeiMemoryDiscoveredPpiGuid AND

+  gEfiPeiMasterBootModePpiGuid AND

+  gEfiPeiReadOnlyVariable2PpiGuid

+

+[UserExtensions.TianoCore."ExtraFiles"]

+  Tcg2ConfigPeiExtra.uni

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni

new file mode 100644

index 0000000000..5c1a4b6e8f

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni

@@ -0,0 +1,34 @@

+// /** @file

+// TCG 2.0 Config PEI uni file

+//

+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+//

+// SPDX-License-Identifier: BSD-2-Clause-Patent

+//

+// **/

+// This file includes code originally published under the following license.

+// */

+

+// /** @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) 2015, Intel Corporation. All rights reserved.<BR>

+//

+// 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 IMPLIED.

+//

+// **/

+

+

+#string STR_MODULE_ABSTRACT             #language en-US "Set TPM device type"

+

+#string STR_MODULE_DESCRIPTION          #language en-US "This module initializes 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/Tcg2Config/Tcg2ConfigPeiExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni

new file mode 100644

index 0000000000..e8b036e061

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni

@@ -0,0 +1,30 @@

+// /** @file

+// TCG 2.0 Config PEI extra uni file

+//

+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+//

+// SPDX-License-Identifier: BSD-2-Clause-Patent

+//

+// **/

+// This file includes code originally published under the following license.

+// */

+

+// /** @file

+// Tcg2ConfigDxe Localized Strings and Content

+//

+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>

+//

+// 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 IMPLIED.

+//

+// **/

+

+#string STR_PROPERTIES_MODULE_NAME

+#language en-US

+"TCG2 (Trusted Computing Group) Configuration DXE"

+

+

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c

new file mode 100644

index 0000000000..bbbcba6e8b

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c

@@ -0,0 +1,163 @@

+/** @file

+  Implements Tcg2ConfigPeim.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  The module entry point for Tcg2 configuration module.

+

+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#include <PiPei.h>

+#include <Guid/TpmInstance.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/PcdLib.h>

+#include <Ppi/ReadOnlyVariable2.h>

+#include <Ppi/TpmInitialized.h>

+#include <Protocol/Tcg2Protocol.h>

+#include "Tcg2ConfigNvData.h"

+

+TPM_INSTANCE_ID  mTpmInstanceId[] = TPM_INSTANCE_ID_LIST;

+

+CONST EFI_PEI_PPI_DESCRIPTOR  gTpmSelectedPpi = {

+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

+  &gEfiTpmDeviceSelectedGuid,

+  NULL

+};

+

+EFI_PEI_PPI_DESCRIPTOR  mTpmInitializationDonePpiList = {

+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,

+  &gPeiTpmInitializationDonePpiGuid,

+  NULL

+};

+

+/**

+  This routine check both SetupVariable and real TPM device, and return final 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 = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);

+  ASSERT_EFI_ERROR (Status);

+

+  Size   = sizeof (Tcg2Configuration);

+  Status = VariablePpi->GetVariable (

+                          VariablePpi,

+                          TCG2_STORAGE_NAME,

+                          &gTcg2ConfigFormSetGuid,

+                          NULL,

+                          &Size,

+                          &Tcg2Configuration

+                          );

+  if (EFI_ERROR (Status)) {

+    //

+    // Variable not ready, set default value

+    //

+    Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;

+  }

+

+  //

+  // Validation

+  //

+  if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {

+    Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;

+  }

+

+  //

+  // Although we have SetupVariable info, we still need detect TPM device manually.

+  //

+  DEBUG ((EFI_D_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice));

+

+  if (PcdGetBool (PcdTpmAutoDetection)) {

+    TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice);

+    DEBUG ((EFI_D_INFO, "TpmDevice final: %x\n", TpmDevice));

+    if (TpmDevice != TPM_DEVICE_NULL) {

+      Tcg2Configuration.TpmDevice = TpmDevice;

+    }

+  } else {

+    TpmDevice = Tcg2Configuration.TpmDevice;

+  }

+

+  //

+  // Convert variable to PCD.

+  // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.

+  // Using DynamicPcd instead.

+  //

+  // NOTE: Tcg2Configuration variable contains the desired TpmDevice type,

+  // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type

+  //

+  for (Index = 0; Index < sizeof (mTpmInstanceId)/sizeof (mTpmInstanceId[0]); Index++) {

+    if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {

+      Size   = sizeof (mTpmInstanceId[Index].TpmInstanceGuid);

+      Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);

+      ASSERT_EFI_ERROR (Status);

+      DEBUG ((EFI_D_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));

+      break;

+    }

+  }

+

+  //

+  // Selection done

+  //

+  Status = PeiServicesInstallPpi (&gTpmSelectedPpi);

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi.

+  // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver.

+  // Other driver can know TPM initialization state by TpmInitializedPpi.

+  //

+  if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) {

+    Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);

+    ASSERT_EFI_ERROR (Status2);

+  }

+

+  return Status;

+}

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c

new file mode 100644

index 0000000000..e301295256

--- /dev/null

+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c

@@ -0,0 +1,115 @@

+/** @file

+  Implements TpmDetection.C

+

+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>

+  SPDX-License-Identifier: BSD-2-Clause-Patent

+

+**/

+

+/* This file includes code originally published under the following license. */

+

+/** @file

+  fTPM2.0/dTPM2.0 auto detection.

+

+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+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 IMPLIED.

+

+**/

+

+#include <PiPei.h>

+#include <Ppi/ReadOnlyVariable2.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/PcdLib.h>

+#include <Library/Tpm2DeviceLib.h>

+#include <Library/Tpm2CommandLib.h>

+#include <Library/PciExpressLib.h>

+#include <Library/IoLib.h>

+#include <IndustryStandard/Tpm20.h>

+#include "Tcg2ConfigNvData.h"

+

+EFI_STATUS

+InitDtpmInterface (

+  IN  VOID

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  This routine check both SetupVariable and real TPM device, and return final 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 = 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 == BOOT_ON_S3_RESUME) {

+    DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n"));

+

+    Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);

+    ASSERT_EFI_ERROR (Status);

+

+    Size = sizeof (TCG2_DEVICE_DETECTION);

+    ZeroMem (&Tcg2DeviceDetection, sizeof (Tcg2DeviceDetection));

+    Status = VariablePpi->GetVariable (

+                            VariablePpi,

+                            TCG2_DEVICE_DETECTION_NAME,

+                            &gTcg2ConfigFormSetGuid,

+                            NULL,

+                            &Size,

+                            &Tcg2DeviceDetection

+                            );

+    if (!EFI_ERROR (Status) &&

+        (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&

+        (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX))

+    {

+      DEBUG ((EFI_D_INFO, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected));

+      Status = Tpm2Startup (TPM_SU_STATE);

+      return Tcg2DeviceDetection.TpmDeviceDetected;

+    }

+  }

+

+  DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n"));

+

+  Status = Tpm2RequestUseTpm ();

+  if (EFI_ERROR (Status)) {

+    //

+    // TPM 2.0 not available

+    //

+    return TPM_DEVICE_NULL;

+  }

+

+  Status = Tpm2Startup (TPM_SU_CLEAR);

+  DEBUG ((EFI_D_INFO, "Tpm2Startup: %r\n", Status));

+  if (EFI_ERROR (Status)) {

+    return TPM_DEVICE_NULL;

+  }

+

+  return TPM_DEVICE_2_0_DTPM;

+}

--

2.31.1





-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114070): https://edk2.groups.io/g/devel/message/114070
Mute This Topic: https://groups.io/mt/103831193/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-