SecurityPkg: Break out the user prompt from Tcg2 PPI

Break out the PromptForUserConfirmation() function into a lib
so it can be abstracted at the platform level.

Signed-off-by: Raymond Diaz <raymonddiaz@microsoft.com>
Signed-off-by: Bret Barkelew <brbarkel@microsoft.com>
This commit is contained in:
rdiaz 2026-07-22 20:22:03 +00:00 committed by mergify[bot]
parent ffaaf0f14c
commit 2c2f74a581
8 changed files with 246 additions and 55 deletions

View file

@ -237,6 +237,40 @@ instance is provided in-tree (MdeModulePkg/Library/GptLib/GptLib.inf).
GptLib|MdeModulePkg/Library/GptLib/GptLib.inf
##### Breaking Change: New Tcg2PhysicalPresencePromptLib library class dependency
- **Status**: Announced
- **Tracking Issue**: [tianocore/edk2#TBD](https://github.com/tianocore/edk2/issues/12832)
- **Pull Request**: [tianocore/edk2#12820](https://github.com/tianocore/edk2/pull/12820)
- **Type**: Source-Level (Non-removal) - Library class dependency addition (platform-implemented)
**What changed**: `SecurityPkg` `DxeTcg2PhysicalPresenceLib` gained a required dependency on the new
`Tcg2PhysicalPresencePromptLib` library class declared in `SecurityPkg/SecurityPkg.dec`. Platforms
that build `DxeTcg2PhysicalPresenceLib` must resolve `Tcg2PhysicalPresencePromptLib` in their DSC or
the build fails with an unresolved library class.
**Why it changed**: Previously, `DxeTcg2PhysicalPresenceLib` printed the Physical Presence confirmation prompt
directly to the console, giving platforms no clean way to substitute a platform-specific user-interaction mechanism.
Extracting the prompt behind a library class lets platforms provide their own prompt implementation without patching
`DxeTcg2PhysicalPresenceLib` and keeps the TPM 2.0 Physical Presence flow decoupled from any specific UI.
**What replaces it**: Nothing is removed. `DxeTcg2PhysicalPresenceLib` now calls into the
`Tcg2PhysicalPresencePromptLib` interface, and `SecurityPkg` provides the console-based default instance for platforms
that do not implement their own.
**How to migrate**: Platforms building `DxeTcg2PhysicalPresenceLib` must add a `Tcg2PhysicalPresencePromptLib` mapping
to their platform DSC `[LibraryClasses]` section. To keep the existing behavior, map to the in-tree console instance:
Tcg2PhysicalPresencePromptLib|SecurityPkg/Library/Tcg2PhysicalPresencePromptLib/Tcg2PhysicalPresencePromptLibConsole.inf
Platforms that want a custom prompt UI can instead provide their own instance implementing the
`Tcg2PhysicalPresencePromptLib` interface declared in
`SecurityPkg/Include/Library/Tcg2PhysicalPresencePromptLib.h` and map the library class to that instance in their DSC.
**Breaking conditions**: Affects platforms and out-of-tree modules that build `SecurityPkg`'s
`DxeTcg2PhysicalPresenceLib` (`Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf`).
Platforms that do not consume `DxeTcg2PhysicalPresenceLib` are unaffected.
### edk2-stable202608: Behavioral Breaking Changes
None

View file

@ -0,0 +1,47 @@
/** @file -- Tcg2PhysicalPresencePromptLib.h
This library abstracts the action of prompting the user so that it may be overridden in a platform-specific way.
Rather than just printing to the screen.
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#pragma once
/**
Simple function to inform any callers of whether the lib is ready to present a prompt.
Since the prompt itself only returns TRUE or FALSE, make sure all other technical requirements
are out of the way.
@retval EFI_SUCCESS Prompt is ready.
@retval EFI_NOT_READY Prompt is not ready.
@retval EFI_DEVICE_ERROR Library failed to prepare resources.
**/
EFI_STATUS
EFIAPI
Tcg2IsPromptReady (
VOID
);
/**
Presents the given prompt string to the user and returns whether the user
confirmed the requested action.
@param[in] PromptString The string that should occupy the body of the prompt.
@param[in] CautionKey If TRUE, the caller has instructed the user to press
the CAUTION key to confirm.
If FALSE, the caller has instructed the user to press
the ACCEPT key to confirm.
@retval TRUE User confirmed the action.
@retval FALSE User rejected the action or a failure occurred.
**/
BOOLEAN
EFIAPI
Tcg2PromptForUserConfirmation (
IN CHAR16 *PromptString,
IN BOOLEAN CautionKey
);

View file

@ -30,6 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/Tcg2PhysicalPresenceData.h>
#include <Library/Tpm2CommandLib.h>
#include <Library/Tcg2PhysicalPresenceLib.h>
#include <Library/Tcg2PhysicalPresencePromptLib.h>
#include <Library/Tcg2PpVendorLib.h>
#define CONFIRM_BUFFER_SIZE 4096
@ -251,50 +252,6 @@ Tcg2ExecutePhysicalPresence (
}
}
/**
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.
@ -373,8 +330,7 @@ Tcg2UserConfirm (
UINTN BufSize;
BOOLEAN CautionKey;
BOOLEAN NoPpiInfo;
UINT16 Index;
CHAR16 DstStr[81];
BOOLEAN Result;
CHAR16 TempBuffer[1024];
CHAR16 TempBuffer2[1024];
EFI_TCG2_PROTOCOL *Tcg2Protocol;
@ -576,10 +532,12 @@ Tcg2UserConfirm (
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);
Status = Tcg2IsPromptReady ();
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Tcg2IsPromptReady failed w/ Status: %r\n", Status));
Result = FALSE;
} else {
Result = Tcg2PromptForUserConfirmation (ConfirmText, CautionKey);
}
FreePool (TmpStr1);
@ -587,11 +545,7 @@ Tcg2UserConfirm (
FreePool (ConfirmText);
HiiRemovePackages (mTcg2PpStringPackHandle);
if (Tcg2ReadUserKey (CautionKey)) {
return TRUE;
}
return FALSE;
return Result;
}
/**

View file

@ -51,6 +51,7 @@
Tpm2CommandLib
Tcg2PpVendorLib
VariablePolicyHelperLib
Tcg2PhysicalPresencePromptLib
[Protocols]
gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES

View file

@ -0,0 +1,115 @@
/** @file
This instance of the Tcg2PhysicalPresencePromptLib uses the
console and basic key input to prompt the user.
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/Tcg2PhysicalPresencePromptLib.h>
/**
Simple function to inform any callers of whether the lib is ready to present a prompt.
Since the prompt itself only returns TRUE or FALSE, make sure all other technical requirements
are out of the way.
@retval EFI_SUCCESS Prompt is ready.
@retval EFI_NOT_READY Prompt is not ready.
@retval EFI_DEVICE_ERROR Library failed to prepare resources.
**/
EFI_STATUS
EFIAPI
Tcg2IsPromptReady (
VOID
)
{
return EFI_SUCCESS;
}
/**
Read the specified key for user confirmation as specified by
TCG PC Client Platform Physical Presence Interface Specification
version 1.3 Revision 00.52.
@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.
**/
STATIC
BOOLEAN
ReadUserKey (
IN BOOLEAN CautionKey
)
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
while (TRUE) {
Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
if (EFI_ERROR (Status)) {
continue;
}
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
if (EFI_ERROR (Status)) {
continue;
}
if (Key.ScanCode == SCAN_ESC) {
return FALSE;
}
if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
return TRUE;
}
if ((Key.ScanCode == SCAN_F12) && CautionKey) {
return TRUE;
}
}
}
/**
Presents the given prompt string to the user and returns whether the user
confirmed the requested action.
@param[in] PromptString The string that should occupy the body of the prompt.
@param[in] CautionKey If TRUE, the caller has instructed the user to press
the CAUTION key to confirm.
If FALSE, the caller has instructed the user to press
the ACCEPT key to confirm.
@retval TRUE User confirmed the action.
@retval FALSE User rejected the action or a failure occurred.
**/
BOOLEAN
EFIAPI
Tcg2PromptForUserConfirmation (
IN CHAR16 *PromptString,
IN BOOLEAN CautionKey
)
{
UINTN Index;
CHAR16 DstStr[81];
DstStr[80] = L'\0';
for (Index = 0; Index < StrLen (PromptString); Index += 80) {
StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), PromptString + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);
Print (DstStr);
}
if (ReadUserKey (CautionKey)) {
return TRUE;
}
return FALSE;
}

View file

@ -0,0 +1,34 @@
## @file
# This instance of the Tcg2PhysicalPresencePromptLib uses the
# console and basic key input to prompt the user.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
[Defines]
INF_VERSION = 0x00010017
BASE_NAME = Tcg2PhysicalPresencePromptLibConsole
FILE_GUID = 54A17646-E8E3-4BED-A7D8-D9E5E7684E85
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
LIBRARY_CLASS = Tcg2PhysicalPresencePromptLib|DXE_DRIVER
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
Tcg2PhysicalPresencePromptLibConsole.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
SecurityPkg/SecurityPkg.dec
[LibraryClasses]
BaseLib
UefiLib
UefiBootServicesTableLib

View file

@ -103,6 +103,10 @@
#
PlatformPKProtectionLib|Include/Library/PlatformPKProtectionLib.h
## @libraryclass Provides platform abstraction for physical presence prompting.
#
Tcg2PhysicalPresencePromptLib|Include/Library/Tcg2PhysicalPresencePromptLib.h
## @libraryclass Perform SPDM (following SPDM spec) and measure data to TPM (following TCG PFP spec).
##
SpdmSecurityLib|Include/Library/SpdmSecurityLib.h

View file

@ -138,6 +138,7 @@
Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibTcg/Tpm12DeviceLibTcg.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
Tcg2PhysicalPresencePromptLib|SecurityPkg/Library/Tcg2PhysicalPresencePromptLib/Tcg2PhysicalPresencePromptLibConsole.inf
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER,]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@ -236,6 +237,7 @@
SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
SecurityPkg/Library/PeiTcg2PhysicalPresenceLib/PeiTcg2PhysicalPresenceLib.inf
SecurityPkg/Library/Tcg2PhysicalPresencePromptLib/Tcg2PhysicalPresencePromptLibConsole.inf
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf