summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg')
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf63
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c97
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.c79
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.h34
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12SupportNull.c25
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf40
-rw-r--r--src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c87
7 files changed, 425 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
new file mode 100644
index 00000000..e3491551
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
@@ -0,0 +1,63 @@
+## @file
+# Set TPM device type
+#
+# In SecurityPkg, this module initializes the TPM device type based on a UEFI
+# variable and/or hardware detection. In OvmfPkg, the module only performs TPM
+# hardware detection.
+#
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# Copyright (C) 2018, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tcg2ConfigPei
+ FILE_GUID = BF7F2B0C-9F2F-4889-AB5C-12460022BE87
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Tcg2ConfigPeimEntryPoint
+
+[Sources]
+ Tcg2ConfigPeim.c
+ Tpm12Support.h
+
+[Sources.IA32, Sources.X64]
+ Tpm12Support.c
+
+[Sources.ARM, Sources.AARCH64]
+ Tpm12SupportNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ PeiServicesLib
+ Tpm2DeviceLib
+
+[LibraryClasses.IA32, LibraryClasses.X64]
+ BaseLib
+ Tpm12DeviceLib
+
+[Guids]
+ gEfiTpmDeviceSelectedGuid ## PRODUCES ## GUID # Used as a PPI GUID
+ gEfiTpmDeviceInstanceTpm20DtpmGuid ## SOMETIMES_CONSUMES
+ gEfiTpmDeviceInstanceTpm12Guid ## SOMETIMES_CONSUMES
+
+[Ppis]
+ gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES
+
+[Depex.IA32, Depex.X64]
+ gOvmfTpmMmioAccessiblePpiGuid
+
+[Depex.ARM, Depex.AARCH64]
+ gOvmfTpmDiscoveredPpiGuid
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
new file mode 100644
index 00000000..cf4b3f1d
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
@@ -0,0 +1,97 @@
+/** @file
+ Set TPM device type
+
+ In SecurityPkg, this module initializes the TPM device type based on a UEFI
+ variable and/or hardware detection. In OvmfPkg, the module only performs TPM
+ hardware detection.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2018, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#include <PiPei.h>
+
+#include <Guid/TpmInstance.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Ppi/TpmInitialized.h>
+
+#include "Tpm12Support.h"
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpmSelectedPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTpmDeviceSelectedGuid,
+ NULL
+};
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmInitializationDonePpiGuid,
+ NULL
+};
+
+/**
+ The entry point for Tcg2 configuration driver.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+**/
+EFI_STATUS
+EFIAPI
+Tcg2ConfigPeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINTN Size;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "%a\n", __FUNCTION__));
+
+ Status = InternalTpm12Detect ();
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "%a: TPM1.2 detected\n", __FUNCTION__));
+ Size = sizeof (gEfiTpmDeviceInstanceTpm12Guid);
+ Status = PcdSetPtrS (
+ PcdTpmInstanceGuid,
+ &Size,
+ &gEfiTpmDeviceInstanceTpm12Guid
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ Status = Tpm2RequestUseTpm ();
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "%a: TPM2 detected\n", __FUNCTION__));
+ Size = sizeof (gEfiTpmDeviceInstanceTpm20DtpmGuid);
+ Status = PcdSetPtrS (
+ PcdTpmInstanceGuid,
+ &Size,
+ &gEfiTpmDeviceInstanceTpm20DtpmGuid
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: no TPM detected\n", __FUNCTION__));
+ //
+ // If no TPM2 was detected, we still need to install
+ // TpmInitializationDonePpi. Namely, Tcg2Pei will exit early upon seeing
+ // the default (all-bits-zero) contents of PcdTpmInstanceGuid, thus we have
+ // to install the PPI in its place, in order to unblock any dependent
+ // PEIMs.
+ //
+ Status = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ //
+ // Selection done
+ //
+ Status = PeiServicesInstallPpi (&mTpmSelectedPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.c
new file mode 100644
index 00000000..c6d933d4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.c
@@ -0,0 +1,79 @@
+/** @file
+ Implement the InternalTpm12Detect() function on top of the Tpm12DeviceLib
+ class.
+
+ Copyright (C) 2020, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/Tpm12DeviceLib.h>
+
+#include "Tpm12Support.h"
+
+#pragma pack (1)
+typedef struct {
+ TPM_RSP_COMMAND_HDR Hdr;
+ TPM_CURRENT_TICKS CurrentTicks;
+} TPM_RSP_GET_TICKS;
+#pragma pack ()
+
+/**
+ Probe for the TPM for 1.2 version, by sending TPM1.2 GetTicks
+
+ Sending a TPM1.2 command to a TPM2 should return a TPM1.2
+ header (tag = 0xc4) and error code (TPM_BADTAG = 0x1e)
+
+ @retval EFI_SUCCESS TPM version 1.2 probing successful.
+
+ @return Error codes propagated from Tpm12SubmitCommand().
+**/
+STATIC
+EFI_STATUS
+TestTpm12 (
+ )
+{
+ EFI_STATUS Status;
+ TPM_RQU_COMMAND_HDR Command;
+ TPM_RSP_GET_TICKS Response;
+ UINT32 Length;
+
+ Command.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ Command.paramSize = SwapBytes32 (sizeof (Command));
+ Command.ordinal = SwapBytes32 (TPM_ORD_GetTicks);
+
+ Length = sizeof (Response);
+ Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length,
+ (UINT8 *)&Response);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Detect the presence of a TPM with interface version 1.2.
+
+ @retval EFI_SUCCESS TPM-1.2 available. The Tpm12RequestUseTpm() and
+ Tpm12SubmitCommand(TPM_ORD_GetTicks) operations
+ (from the Tpm12DeviceLib class) have succeeded.
+
+ @return Error codes propagated from Tpm12RequestUseTpm() and
+ Tpm12SubmitCommand().
+**/
+EFI_STATUS
+InternalTpm12Detect (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = Tpm12RequestUseTpm ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return TestTpm12 ();
+}
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.h b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.h
new file mode 100644
index 00000000..b3ebcd41
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12Support.h
@@ -0,0 +1,34 @@
+/** @file
+ Declare the InternalTpm12Detect() function, hiding the TPM-1.2 detection
+ internals.
+
+ Copyright (C) 2020, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef TPM12_SUPPORT_H_
+#define TPM12_SUPPORT_H_
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+ Detect the presence of a TPM with interface version 1.2.
+
+ @retval EFI_UNSUPPORTED The platform that includes this particular
+ implementation of the function does not support
+ TPM-1.2.
+
+ @retval EFI_SUCCESS TPM-1.2 available. The Tpm12RequestUseTpm() and
+ Tpm12SubmitCommand(TPM_ORD_GetTicks) operations
+ (from the Tpm12DeviceLib class) have succeeded.
+
+ @return Error codes propagated from Tpm12RequestUseTpm() and
+ Tpm12SubmitCommand().
+**/
+EFI_STATUS
+InternalTpm12Detect (
+ VOID
+ );
+
+#endif // TPM12_SUPPORT_H_
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12SupportNull.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12SupportNull.c
new file mode 100644
index 00000000..7db2f088
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/Tcg2Config/Tpm12SupportNull.c
@@ -0,0 +1,25 @@
+/** @file
+ Null implementation of InternalTpm12Detect(), always returning
+ EFI_UNSUPPORTED.
+
+ Copyright (C) 2020, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Tpm12Support.h"
+
+/**
+ Detect the presence of a TPM with interface version 1.2.
+
+ @retval EFI_UNSUPPORTED The platform that includes this particular
+ implementation of the function does not support
+ TPM-1.2.
+**/
+EFI_STATUS
+InternalTpm12Detect (
+ VOID
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
new file mode 100644
index 00000000..15fa8e32
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPei.inf
@@ -0,0 +1,40 @@
+## @file
+# Map TPM MMIO range unencrypted when SEV-ES is active.
+# Install gOvmfTpmMmioAccessiblePpiGuid unconditionally.
+#
+# Copyright (C) 2021, Advanced Micro Devices, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = TpmMmioSevDecryptPei
+ FILE_GUID = F12F698A-E506-4A1B-B32E-6920E55DA1C4
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TpmMmioSevDecryptPeimEntryPoint
+
+[Sources]
+ TpmMmioSevDecryptPeim.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ MemEncryptSevLib
+ PcdLib
+ PeimEntryPoint
+ PeiServicesLib
+
+[Ppis]
+ gOvmfTpmMmioAccessiblePpiGuid ## PRODUCES
+
+[FixedPcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## CONSUMES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
new file mode 100644
index 00000000..9315ffed
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/OvmfPkg/Tcg/TpmMmioSevDecryptPei/TpmMmioSevDecryptPeim.c
@@ -0,0 +1,87 @@
+/** @file
+ Map TPM MMIO range unencrypted when SEV-ES is active.
+ Install gOvmfTpmMmioAccessiblePpiGuid unconditionally.
+
+ Copyright (C) 2021, Advanced Micro Devices, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#include <PiPei.h>
+
+#include <Library/DebugLib.h>
+#include <Library/MemEncryptSevLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR mTpmMmioRangeAccessible = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gOvmfTpmMmioAccessiblePpiGuid,
+ NULL
+};
+
+/**
+ The entry point for TPM MMIO range mapping driver.
+
+ @param[in] FileHandle Handle of the file being invoked.
+ @param[in] PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_ABORTED No need to keep this PEIM resident
+**/
+EFI_STATUS
+EFIAPI
+TpmMmioSevDecryptPeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ RETURN_STATUS DecryptStatus;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "%a\n", __FUNCTION__));
+
+ //
+ // If SEV is active, MMIO succeeds against an encrypted physical address
+ // because the nested page fault (NPF) that occurs on access does not
+ // include the encryption bit in the guest physical address provided to the
+ // hypervisor.
+ //
+ // If SEV-ES is active, MMIO would succeed against an encrypted physical
+ // address because the #VC handler uses the virtual address (which is an
+ // identity mapped physical address without the encryption bit) as the guest
+ // physical address of the MMIO target in the VMGEXIT.
+ //
+ // However, if SEV-ES is active, before performing the actual MMIO, an
+ // additional MMIO mitigation check is performed in the #VC handler to ensure
+ // that MMIO is being done to/from an unencrypted address. To prevent guest
+ // termination in this scenario, mark the range unencrypted ahead of access.
+ //
+ if (MemEncryptSevEsIsEnabled ()) {
+ DEBUG ((DEBUG_INFO,
+ "%a: mapping TPM MMIO address range unencrypted\n",
+ __FUNCTION__));
+
+ DecryptStatus = MemEncryptSevClearPageEncMask (
+ 0,
+ FixedPcdGet64 (PcdTpmBaseAddress),
+ EFI_SIZE_TO_PAGES ((UINTN) 0x5000),
+ FALSE
+ );
+
+ if (RETURN_ERROR (DecryptStatus)) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: failed to map TPM MMIO address range unencrypted\n",
+ __FUNCTION__));
+ ASSERT_RETURN_ERROR (DecryptStatus);
+ }
+ }
+
+ //
+ // MMIO range available
+ //
+ Status = PeiServicesInstallPpi (&mTpmMmioRangeAccessible);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_ABORTED;
+}