This commit is contained in:
Sean Rhodes 2026-08-25 17:41:32 +02:00 committed by GitHub
commit e79e479f57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 236 additions and 72 deletions

View file

@ -80,6 +80,7 @@
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
Tpm2HelpLib|SecurityPkg/Library/Tpm2HelpLib/Tpm2HelpLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
Tcg2PhysicalPresencePlatformLib|OvmfPkg/Library/Tcg2PhysicalPresencePlatformLibQemu/DxeTcg2PhysicalPresencePlatformLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
TpmPlatformHierarchyLib|SecurityPkg/Library/PeiDxeTpmPlatformHierarchyLib/PeiDxeTpmPlatformHierarchyLib.inf
!else

View file

@ -10,6 +10,7 @@
!endif
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf
Tcg2PhysicalPresencePlatformLib|OvmfPkg/Library/Tcg2PhysicalPresencePlatformLibQemu/DxeTcg2PhysicalPresencePlatformLib.inf
Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
!else
Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf

View file

@ -0,0 +1,41 @@
/** @file
Returns the platform specific Physical Presence configuration.
Copyright (c) 2020, 9elements GmbH. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __TCG2_PHYSICAL_PRESENCE_PLATFORM_LIB_H__
#define __TCG2_PHYSICAL_PRESENCE_PLATFORM_LIB_H__
#include <Base.h>
typedef enum {
Tcg2PhysicalPresenceTpmVersionUnknown,
Tcg2PhysicalPresenceTpmVersion12,
Tcg2PhysicalPresenceTpmVersion20
} TCG2_PHYSICAL_PRESENCE_TPM_VERSION;
typedef struct {
EFI_PHYSICAL_ADDRESS PpiAddress;
TCG2_PHYSICAL_PRESENCE_TPM_VERSION TpmVersion;
BOOLEAN PpiInMmio;
} TCG2_PHYSICAL_PRESENCE_PLATFORM_CONFIG;
/**
Reads the platform specific Physical Presence configuration.
@param[out] Config The config structure to fill in.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_INVALID_PARAMETER A required pointer argument was NULL.
@retval EFI_PROTOCOL_ERROR Invalid config entry size.
**/
EFI_STATUS
EFIAPI
TpmPpiPlatformReadConfig (
OUT TCG2_PHYSICAL_PRESENCE_PLATFORM_CONFIG *Config
);
#endif

View file

@ -27,8 +27,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/Tpm2CommandLib.h>
#include <Library/Tcg2PhysicalPresencePlatformLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
@ -40,42 +40,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
EFI_HII_HANDLE mTcg2PpStringPackHandle;
#define TCG2_PHYSICAL_PRESENCE_USER_CONFIRM_TIMEOUT_100NS (3ULL * 60ULL * 10000000ULL)
#define TPM_PPI_FLAGS (QEMU_TPM_PPI_FUNC_ALLOWED_USR_REQ)
STATIC volatile QEMU_TPM_PPI *mPpi;
/**
Reads QEMU PPI config from fw_cfg.
@param[out] The Config structure to read to.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size.
**/
STATIC
EFI_STATUS
QemuTpmReadConfig (
OUT QEMU_FWCFG_TPM_CONFIG *Config
)
{
EFI_STATUS Status;
FIRMWARE_CONFIG_ITEM FwCfgItem;
UINTN FwCfgSize;
Status = QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem, &FwCfgSize);
if (EFI_ERROR (Status)) {
return Status;
}
if (FwCfgSize != sizeof (*Config)) {
return EFI_PROTOCOL_ERROR;
}
QemuFwCfgSelectItem (FwCfgItem);
QemuFwCfgReadBytes (sizeof (*Config), Config);
return EFI_SUCCESS;
}
/**
Initializes QEMU PPI memory region.
@ -88,29 +58,34 @@ QemuTpmInitPPI (
VOID
)
{
EFI_STATUS Status;
QEMU_FWCFG_TPM_CONFIG Config;
EFI_PHYSICAL_ADDRESS PpiAddress64;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINTN Idx;
EFI_STATUS Status;
TCG2_PHYSICAL_PRESENCE_PLATFORM_CONFIG Config;
EFI_PHYSICAL_ADDRESS PpiAddress64;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
UINTN Idx;
if (mPpi != NULL) {
return EFI_SUCCESS;
}
Status = QemuTpmReadConfig (&Config);
Status = TpmPpiPlatformReadConfig (&Config);
if (EFI_ERROR (Status)) {
return Status;
}
mPpi = (QEMU_TPM_PPI *)(UINTN)Config.PpiAddress;
if (mPpi == NULL) {
if ((Config.PpiAddress == 0) || (Config.PpiAddress > MAX_UINTN)) {
return EFI_PROTOCOL_ERROR;
}
PpiAddress64 = Config.PpiAddress;
mPpi = (QEMU_TPM_PPI *)(UINTN)PpiAddress64;
DEBUG ((DEBUG_INFO, "[TPM2PP] mPpi=%p version=%d\n", mPpi, Config.TpmVersion));
PpiAddress64 = (UINTN)mPpi;
if (PpiAddress64 > MAX_UINT64 - sizeof (*mPpi) + 1) {
DEBUG ((DEBUG_ERROR, "[TPM2PP] mPpi address overflows\n"));
goto InvalidPpiAddress;
}
if ((PpiAddress64 & ~(UINT64)EFI_PAGE_MASK) !=
((PpiAddress64 + sizeof *mPpi - 1) & ~(UINT64)EFI_PAGE_MASK))
{
@ -124,19 +99,29 @@ QemuTpmInitPPI (
goto InvalidPpiAddress;
}
if (!EFI_ERROR (Status) &&
((Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) &&
(Descriptor.GcdMemoryType != EfiGcdMemoryTypeNonExistent)))
{
DEBUG ((DEBUG_ERROR, "[TPM2PP] mPpi has an invalid memory type\n"));
goto InvalidPpiAddress;
if (Config.PpiInMmio) {
if (!EFI_ERROR (Status) &&
((Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) &&
(Descriptor.GcdMemoryType != EfiGcdMemoryTypeNonExistent)))
{
DEBUG ((DEBUG_ERROR, "[TPM2PP] mPpi has an invalid memory type\n"));
goto InvalidPpiAddress;
}
} else {
if (!EFI_ERROR (Status) &&
((Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) &&
(Descriptor.GcdMemoryType != EfiGcdMemoryTypeSystemMemory)))
{
DEBUG ((DEBUG_ERROR, "[TPM2PP] mPpi has an invalid memory type\n"));
goto InvalidPpiAddress;
}
}
for (Idx = 0; Idx < ARRAY_SIZE (mPpi->Func); Idx++) {
mPpi->Func[Idx] = 0;
}
if (Config.TpmVersion == QEMU_TPM_VERSION_2) {
if (Config.TpmVersion == Tcg2PhysicalPresenceTpmVersion20) {
mPpi->Func[TCG2_PHYSICAL_PRESENCE_NO_ACTION] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_CLEAR] = TPM_PPI_FLAGS;
mPpi->Func[TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR] = TPM_PPI_FLAGS;
@ -365,31 +350,51 @@ Tcg2ReadUserKey (
EFI_STATUS Status;
EFI_INPUT_KEY Key;
UINT16 InputKey;
EFI_EVENT TimeoutEvent;
EFI_EVENT WaitList[2];
UINTN WaitIndex;
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;
Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &TimeoutEvent);
if (EFI_ERROR (Status)) {
return FALSE;
}
return FALSE;
Status = gBS->SetTimer (
TimeoutEvent,
TimerRelative,
TCG2_PHYSICAL_PRESENCE_USER_CONFIRM_TIMEOUT_100NS
);
if (EFI_ERROR (Status)) {
gBS->CloseEvent (TimeoutEvent);
return FALSE;
}
WaitList[0] = gST->ConIn->WaitForKey;
WaitList[1] = TimeoutEvent;
InputKey = 0;
while (InputKey == 0) {
Status = gBS->WaitForEvent (ARRAY_SIZE (WaitList), WaitList, &WaitIndex);
if (EFI_ERROR (Status) || (WaitIndex == 1)) {
break;
}
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (EFI_ERROR (Status)) {
continue;
}
if ((Key.ScanCode == SCAN_ESC) ||
((Key.ScanCode == SCAN_F10) && !CautionKey) ||
((Key.ScanCode == SCAN_F12) && CautionKey))
{
InputKey = Key.ScanCode;
}
}
gBS->CloseEvent (TimeoutEvent);
return (BOOLEAN)((InputKey != 0) && (InputKey != SCAN_ESC));
}
/**

View file

@ -57,12 +57,12 @@
HobLib
MemoryAllocationLib
PrintLib
QemuFwCfgLib
Tpm2CommandLib
UefiBootManagerLib
UefiBootServicesTableLib
UefiLib
UefiRuntimeServicesTableLib
Tcg2PhysicalPresencePlatformLib
[Protocols]
gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES

View file

@ -0,0 +1,76 @@
/** @file
Returns the platform specific configuration for the QEMU PPI.
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) 2018, Red Hat, Inc.
Copyright (c) 2018, IBM Corporation. All rights reserved.<BR>
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <IndustryStandard/QemuTpm.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/Tcg2PhysicalPresencePlatformLib.h>
/**
Reads QEMU PPI config from fw_cfg.
@param[out] Config The config structure to fill in.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_INVALID_PARAMETER A required pointer argument was NULL.
@retval EFI_PROTOCOL_ERROR Invalid fw_cfg entry size.
**/
EFI_STATUS
EFIAPI
TpmPpiPlatformReadConfig (
OUT TCG2_PHYSICAL_PRESENCE_PLATFORM_CONFIG *Config
)
{
EFI_STATUS Status;
FIRMWARE_CONFIG_ITEM FwCfgItem;
UINTN FwCfgSize;
QEMU_FWCFG_TPM_CONFIG QemuConfig;
if (Config == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = QemuFwCfgFindFile ("etc/tpm/config", &FwCfgItem, &FwCfgSize);
if (EFI_ERROR (Status)) {
return Status;
}
if (FwCfgSize != sizeof (QemuConfig)) {
return EFI_PROTOCOL_ERROR;
}
QemuFwCfgSelectItem (FwCfgItem);
QemuFwCfgReadBytes (sizeof (QemuConfig), &QemuConfig);
Config->PpiAddress = QemuConfig.PpiAddress;
Config->PpiInMmio = TRUE;
switch (QemuConfig.TpmVersion) {
case QEMU_TPM_VERSION_1_2:
Config->TpmVersion = Tcg2PhysicalPresenceTpmVersion12;
break;
case QEMU_TPM_VERSION_2:
Config->TpmVersion = Tcg2PhysicalPresenceTpmVersion20;
break;
default:
Config->TpmVersion = Tcg2PhysicalPresenceTpmVersionUnknown;
break;
}
return EFI_SUCCESS;
}

View file

@ -0,0 +1,36 @@
## @file
# Returns the platform specific configuration for the QEMU PPI.
#
# 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) 2018, Red Hat, Inc.
# Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = Tcg2PhysicalPresencePlatformLibQemu
FILE_GUID = 9336E7F0-6CA1-4E6D-A0E9-DFE5F077AA02
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = Tcg2PhysicalPresencePlatformLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#
[Sources]
DxeTcg2PhysicalPresencePlatformLib.c
[Packages]
OvmfPkg/OvmfPkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
QemuFwCfgLib

View file

@ -83,6 +83,10 @@
#
QemuFwCfgLib|Include/Library/QemuFwCfgLib.h
## @libraryclass Reads platform-specific TPM Physical Presence configuration.
#
Tcg2PhysicalPresencePlatformLib|Include/Library/Tcg2PhysicalPresencePlatformLib.h
## @libraryclass S3 support for QEMU fw_cfg
#
QemuFwCfgS3Lib|Include/Library/QemuFwCfgS3Lib.h