/** @file | |
Execute pending TPM requests from OS or BIOS and Lock TPM. | |
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. | |
ExecutePendingTpmRequest() will receive untrusted input and do validation. | |
Copyright (c) 2006 - 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 <PiDxe.h> | |
#include <Protocol/TcgService.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 <Guid/EventGroup.h> | |
#include <Guid/PhysicalPresenceData.h> | |
#include <Library/TcgPpVendorLib.h> | |
#define CONFIRM_BUFFER_SIZE 4096 | |
EFI_HII_HANDLE mPpStringPackHandle; | |
/** | |
Get string by string id from HII Interface. | |
@param[in] Id String ID. | |
@retval CHAR16 * String from ID. | |
@retval NULL If error occurs. | |
**/ | |
CHAR16 * | |
PhysicalPresenceGetStringById ( | |
IN EFI_STRING_ID Id | |
) | |
{ | |
return HiiGetString (mPpStringPackHandle, Id, NULL); | |
} | |
/** | |
Get TPM physical presence permanent flags. | |
@param[in] TcgProtocol EFI TCG Protocol instance. | |
@param[out] LifetimeLock physicalPresenceLifetimeLock permanent flag. | |
@param[out] CmdEnable physicalPresenceCMDEnable permanent flag. | |
@retval EFI_SUCCESS Flags were returns successfully. | |
@retval other Failed to locate EFI TCG Protocol. | |
**/ | |
EFI_STATUS | |
GetTpmCapability ( | |
IN EFI_TCG_PROTOCOL *TcgProtocol, | |
OUT BOOLEAN *LifetimeLock, | |
OUT BOOLEAN *CmdEnable | |
) | |
{ | |
EFI_STATUS Status; | |
TPM_RQU_COMMAND_HDR *TpmRqu; | |
TPM_RSP_COMMAND_HDR *TpmRsp; | |
UINT32 *SendBufPtr; | |
UINT8 SendBuffer[sizeof (*TpmRqu) + sizeof (UINT32) * 3]; | |
TPM_PERMANENT_FLAGS *TpmPermanentFlags; | |
UINT8 RecvBuffer[40]; | |
// | |
// Fill request header | |
// | |
TpmRsp = (TPM_RSP_COMMAND_HDR*)RecvBuffer; | |
TpmRqu = (TPM_RQU_COMMAND_HDR*)SendBuffer; | |
TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); | |
TpmRqu->paramSize = SwapBytes32 (sizeof (SendBuffer)); | |
TpmRqu->ordinal = SwapBytes32 (TPM_ORD_GetCapability); | |
// | |
// Set request parameter | |
// | |
SendBufPtr = (UINT32*)(TpmRqu + 1); | |
WriteUnaligned32 (SendBufPtr++, SwapBytes32 (TPM_CAP_FLAG)); | |
WriteUnaligned32 (SendBufPtr++, SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT))); | |
WriteUnaligned32 (SendBufPtr, SwapBytes32 (TPM_CAP_FLAG_PERMANENT)); | |
Status = TcgProtocol->PassThroughToTpm ( | |
TcgProtocol, | |
sizeof (SendBuffer), | |
(UINT8*)TpmRqu, | |
sizeof (RecvBuffer), | |
(UINT8*)&RecvBuffer | |
); | |
ASSERT_EFI_ERROR (Status); | |
ASSERT (TpmRsp->tag == SwapBytes16 (TPM_TAG_RSP_COMMAND)); | |
ASSERT (TpmRsp->returnCode == 0); | |
TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)]; | |
if (LifetimeLock != NULL) { | |
*LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock; | |
} | |
if (CmdEnable != NULL) { | |
*CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable; | |
} | |
return Status; | |
} | |
/** | |
Issue TSC_PhysicalPresence command to TPM. | |
@param[in] TcgProtocol EFI TCG Protocol instance. | |
@param[in] PhysicalPresence The state to set the TPM's Physical Presence flags. | |
@retval EFI_SUCCESS TPM executed the command successfully. | |
@retval EFI_SECURITY_VIOLATION TPM returned error when executing the command. | |
@retval other Failed to locate EFI TCG Protocol. | |
**/ | |
EFI_STATUS | |
TpmPhysicalPresence ( | |
IN EFI_TCG_PROTOCOL *TcgProtocol, | |
IN TPM_PHYSICAL_PRESENCE PhysicalPresence | |
) | |
{ | |
EFI_STATUS Status; | |
TPM_RQU_COMMAND_HDR *TpmRqu; | |
TPM_PHYSICAL_PRESENCE *TpmPp; | |
TPM_RSP_COMMAND_HDR TpmRsp; | |
UINT8 Buffer[sizeof (*TpmRqu) + sizeof (*TpmPp)]; | |
TpmRqu = (TPM_RQU_COMMAND_HDR*)Buffer; | |
TpmPp = (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1); | |
TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); | |
TpmRqu->paramSize = SwapBytes32 (sizeof (Buffer)); | |
TpmRqu->ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence); | |
WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) SwapBytes16 (PhysicalPresence)); | |
Status = TcgProtocol->PassThroughToTpm ( | |
TcgProtocol, | |
sizeof (Buffer), | |
(UINT8*)TpmRqu, | |
sizeof (TpmRsp), | |
(UINT8*)&TpmRsp | |
); | |
ASSERT_EFI_ERROR (Status); | |
ASSERT (TpmRsp.tag == SwapBytes16 (TPM_TAG_RSP_COMMAND)); | |
if (TpmRsp.returnCode != 0) { | |
// | |
// If it fails, some requirements may be needed for this command. | |
// | |
return EFI_SECURITY_VIOLATION; | |
} | |
return Status; | |
} | |
/** | |
Issue a TPM command for which no additional output data will be returned. | |
@param[in] TcgProtocol EFI TCG Protocol instance. | |
@param[in] Ordinal TPM command code. | |
@param[in] AdditionalParameterSize Additional parameter size. | |
@param[in] AdditionalParameters Pointer to the Additional paramaters. | |
@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 | |
TpmCommandNoReturnData ( | |
IN EFI_TCG_PROTOCOL *TcgProtocol, | |
IN TPM_COMMAND_CODE Ordinal, | |
IN UINTN AdditionalParameterSize, | |
IN VOID *AdditionalParameters | |
) | |
{ | |
EFI_STATUS Status; | |
TPM_RQU_COMMAND_HDR *TpmRqu; | |
TPM_RSP_COMMAND_HDR TpmRsp; | |
UINT32 Size; | |
TpmRqu = (TPM_RQU_COMMAND_HDR*) AllocatePool (sizeof (*TpmRqu) + AdditionalParameterSize); | |
if (TpmRqu == NULL) { | |
return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; | |
} | |
TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); | |
Size = (UINT32)(sizeof (*TpmRqu) + AdditionalParameterSize); | |
TpmRqu->paramSize = SwapBytes32 (Size); | |
TpmRqu->ordinal = SwapBytes32 (Ordinal); | |
CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize); | |
Status = TcgProtocol->PassThroughToTpm ( | |
TcgProtocol, | |
Size, | |
(UINT8*)TpmRqu, | |
(UINT32)sizeof (TpmRsp), | |
(UINT8*)&TpmRsp | |
); | |
FreePool (TpmRqu); | |
if (EFI_ERROR (Status) || (TpmRsp.tag != SwapBytes16 (TPM_TAG_RSP_COMMAND))) { | |
return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; | |
} | |
return SwapBytes32 (TpmRsp.returnCode); | |
} | |
/** | |
Execute physical presence operation requested by the OS. | |
@param[in] TcgProtocol EFI TCG Protocol instance. | |
@param[in] CommandCode Physical presence operation value. | |
@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 | |
ExecutePhysicalPresence ( | |
IN EFI_TCG_PROTOCOL *TcgProtocol, | |
IN UINT32 CommandCode, | |
IN OUT EFI_PHYSICAL_PRESENCE_FLAGS *PpiFlags | |
) | |
{ | |
BOOLEAN BoolVal; | |
UINT32 TpmResponse; | |
UINT32 InData[5]; | |
switch (CommandCode) { | |
case PHYSICAL_PRESENCE_ENABLE: | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_PhysicalEnable, | |
0, | |
NULL | |
); | |
case PHYSICAL_PRESENCE_DISABLE: | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_PhysicalDisable, | |
0, | |
NULL | |
); | |
case PHYSICAL_PRESENCE_ACTIVATE: | |
BoolVal = FALSE; | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_PhysicalSetDeactivated, | |
sizeof (BoolVal), | |
&BoolVal | |
); | |
case PHYSICAL_PRESENCE_DEACTIVATE: | |
BoolVal = TRUE; | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_PhysicalSetDeactivated, | |
sizeof (BoolVal), | |
&BoolVal | |
); | |
case PHYSICAL_PRESENCE_CLEAR: | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_ForceClear, | |
0, | |
NULL | |
); | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE, PpiFlags); | |
if (TpmResponse == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ACTIVATE, PpiFlags); | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE, PpiFlags); | |
if (TpmResponse == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DISABLE, PpiFlags); | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: | |
BoolVal = TRUE; | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_SetOwnerInstall, | |
sizeof (BoolVal), | |
&BoolVal | |
); | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: | |
BoolVal = FALSE; | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_SetOwnerInstall, | |
sizeof (BoolVal), | |
&BoolVal | |
); | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: | |
// | |
// PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE | |
// PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE will be executed after reboot | |
// | |
if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags); | |
PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} else { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE, PpiFlags); | |
PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE, PpiFlags); | |
if (TpmResponse == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE_DISABLE, PpiFlags); | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: | |
InData[0] = SwapBytes32 (TPM_SET_STCLEAR_DATA); // CapabilityArea | |
InData[1] = SwapBytes32 (sizeof(UINT32)); // SubCapSize | |
InData[2] = SwapBytes32 (TPM_SD_DEFERREDPHYSICALPRESENCE); // SubCap | |
InData[3] = SwapBytes32 (sizeof(UINT32)); // SetValueSize | |
InData[4] = SwapBytes32 (1); // UnownedFieldUpgrade; bit0 | |
return TpmCommandNoReturnData ( | |
TcgProtocol, | |
TPM_ORD_SetCapability, | |
sizeof (UINT32) * 5, | |
InData | |
); | |
case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: | |
// | |
// TPM_SetOperatorAuth | |
// This command requires UI to prompt user for Auth data | |
// Here it is NOT implemented | |
// | |
return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; | |
case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags); | |
if (TpmResponse == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags); | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE: | |
PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION; | |
return 0; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: | |
PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION; | |
return 0; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: | |
PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR; | |
return 0; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: | |
PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR; | |
return 0; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE: | |
PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE; | |
return 0; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: | |
PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE; | |
return 0; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: | |
// | |
// PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR | |
// PHYSICAL_PRESENCE_CLEAR will be executed after reboot. | |
// | |
if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags); | |
PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} else { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags); | |
PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} | |
return TpmResponse; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: | |
// | |
// PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE | |
// PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE will be executed after reboot. | |
// | |
if ((PpiFlags->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags); | |
PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} else { | |
TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags); | |
PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK; | |
} | |
return TpmResponse; | |
default: | |
; | |
} | |
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 or device error. | |
**/ | |
BOOLEAN | |
ReadUserKey ( | |
IN BOOLEAN CautionKey | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_INPUT_KEY Key; | |
UINT16 InputKey; | |
UINTN Index; | |
InputKey = 0; | |
do { | |
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); | |
if (Status == EFI_NOT_READY) { | |
gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); | |
continue; | |
} | |
if (Status == EFI_DEVICE_ERROR) { | |
return FALSE; | |
} | |
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; | |
} | |
/** | |
The constructor function register UNI strings into imageHandle. | |
It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. | |
@param ImageHandle The firmware allocated handle for the EFI image. | |
@param SystemTable A pointer to the EFI System Table. | |
@retval EFI_SUCCESS The constructor successfully added string package. | |
@retval Other value The constructor can't add string package. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
TcgPhysicalPresenceLibConstructor ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
mPpStringPackHandle = HiiAddPackages (&gEfiPhysicalPresenceGuid, ImageHandle, DxeTcgPhysicalPresenceLibStrings, NULL); | |
ASSERT (mPpStringPackHandle != NULL); | |
return EFI_SUCCESS; | |
} | |
/** | |
Display the confirm text and get user confirmation. | |
@param[in] TpmPpCommand The requested TPM physical presence command. | |
@retval TRUE The user has confirmed the changes. | |
@retval FALSE The user doesn't confirm the changes. | |
**/ | |
BOOLEAN | |
UserConfirm ( | |
IN UINT32 TpmPpCommand | |
) | |
{ | |
CHAR16 *ConfirmText; | |
CHAR16 *TmpStr1; | |
CHAR16 *TmpStr2; | |
UINTN BufSize; | |
BOOLEAN CautionKey; | |
UINT16 Index; | |
CHAR16 DstStr[81]; | |
TmpStr2 = NULL; | |
CautionKey = FALSE; | |
BufSize = CONFIRM_BUFFER_SIZE; | |
ConfirmText = AllocateZeroPool (BufSize); | |
ASSERT (ConfirmText != NULL); | |
switch (TpmPpCommand) { | |
case PHYSICAL_PRESENCE_ENABLE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_DISABLE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_ACTIVATE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_DEACTIVATE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_CLEAR: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (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); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: | |
// | |
// TPM_SetOperatorAuth | |
// This command requires UI to prompt user for Auth data | |
// Here it is NOT implemented | |
// | |
break; | |
case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (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); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (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); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: | |
CautionKey = TRUE; | |
TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE)); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); | |
UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY)); | |
StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1); | |
FreePool (TmpStr1); | |
break; | |
default: | |
; | |
} | |
if (TmpStr2 == NULL) { | |
FreePool (ConfirmText); | |
return FALSE; | |
} | |
TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_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); | |
if (ReadUserKey (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 TCG 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 | |
HaveValidTpmRequest ( | |
IN EFI_PHYSICAL_PRESENCE *TcgPpData, | |
IN EFI_PHYSICAL_PRESENCE_FLAGS Flags, | |
OUT BOOLEAN *RequestConfirmed | |
) | |
{ | |
BOOLEAN IsRequestValid; | |
*RequestConfirmed = FALSE; | |
switch (TcgPpData->PPRequest) { | |
case PHYSICAL_PRESENCE_NO_ACTION: | |
*RequestConfirmed = TRUE; | |
return TRUE; | |
case PHYSICAL_PRESENCE_ENABLE: | |
case PHYSICAL_PRESENCE_DISABLE: | |
case PHYSICAL_PRESENCE_ACTIVATE: | |
case PHYSICAL_PRESENCE_DEACTIVATE: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE: | |
case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: | |
case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH: | |
if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) { | |
*RequestConfirmed = TRUE; | |
} | |
break; | |
case PHYSICAL_PRESENCE_CLEAR: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: | |
if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) { | |
*RequestConfirmed = TRUE; | |
} | |
break; | |
case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: | |
if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != 0) { | |
*RequestConfirmed = TRUE; | |
} | |
break; | |
case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: | |
if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0 && (Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) { | |
*RequestConfirmed = TRUE; | |
} | |
break; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE: | |
case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE: | |
case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE: | |
*RequestConfirmed = TRUE; | |
break; | |
case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE: | |
case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE: | |
case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE: | |
break; | |
default: | |
if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { | |
IsRequestValid = TcgPpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed); | |
if (!IsRequestValid) { | |
return FALSE; | |
} else { | |
break; | |
} | |
} else { | |
// | |
// Wrong Physical Presence command | |
// | |
return FALSE; | |
} | |
} | |
if ((Flags.PPFlags & TCG_VENDOR_LIB_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] TcgProtocol EFI TCG Protocol instance. | |
@param[in] TcgPpData Point to the physical presence NV variable. | |
@param[in] Flags The physical presence interface flags. | |
**/ | |
VOID | |
ExecutePendingTpmRequest ( | |
IN EFI_TCG_PROTOCOL *TcgProtocol, | |
IN EFI_PHYSICAL_PRESENCE *TcgPpData, | |
IN EFI_PHYSICAL_PRESENCE_FLAGS Flags | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN DataSize; | |
BOOLEAN RequestConfirmed; | |
EFI_PHYSICAL_PRESENCE_FLAGS NewFlags; | |
BOOLEAN ResetRequired; | |
UINT32 NewPPFlags; | |
if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) { | |
// | |
// Invalid operation request. | |
// | |
TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE; | |
TcgPpData->LastPPRequest = TcgPpData->PPRequest; | |
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE); | |
Status = gRT->SetVariable ( | |
PHYSICAL_PRESENCE_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
DataSize, | |
TcgPpData | |
); | |
return; | |
} | |
ResetRequired = FALSE; | |
if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { | |
NewFlags = Flags; | |
NewPPFlags = NewFlags.PPFlags; | |
TcgPpData->PPResponse = TcgPpVendorLibExecutePendingRequest (TcgPpData->PPRequest, &NewPPFlags, &ResetRequired); | |
NewFlags.PPFlags = (UINT8)NewPPFlags; | |
} else { | |
if (!RequestConfirmed) { | |
// | |
// Print confirm text and wait for approval. | |
// | |
RequestConfirmed = UserConfirm (TcgPpData->PPRequest); | |
} | |
// | |
// Execute requested physical presence command | |
// | |
TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT; | |
NewFlags = Flags; | |
if (RequestConfirmed) { | |
TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags); | |
} | |
} | |
// | |
// Save the flags if it is updated. | |
// | |
if (CompareMem (&Flags, &NewFlags, sizeof(EFI_PHYSICAL_PRESENCE_FLAGS)) != 0) { | |
Status = gRT->SetVariable ( | |
PHYSICAL_PRESENCE_FLAGS_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
sizeof (EFI_PHYSICAL_PRESENCE_FLAGS), | |
&NewFlags | |
); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
} | |
// | |
// Clear request | |
// | |
if ((NewFlags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) { | |
TcgPpData->LastPPRequest = TcgPpData->PPRequest; | |
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; | |
} | |
// | |
// Save changes | |
// | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE); | |
Status = gRT->SetVariable ( | |
PHYSICAL_PRESENCE_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
DataSize, | |
TcgPpData | |
); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) { | |
return; | |
} | |
// | |
// Reset system to make new TPM settings in effect | |
// | |
switch (TcgPpData->LastPPRequest) { | |
case PHYSICAL_PRESENCE_ACTIVATE: | |
case PHYSICAL_PRESENCE_DEACTIVATE: | |
case PHYSICAL_PRESENCE_CLEAR: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE: | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE: | |
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE: | |
case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE: | |
case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR: | |
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: | |
break; | |
default: | |
if (TcgPpData->LastPPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) { | |
if (ResetRequired) { | |
break; | |
} else { | |
return ; | |
} | |
} | |
if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) { | |
break; | |
} | |
return; | |
} | |
Print (L"Rebooting system to make TPM settings in effect\n"); | |
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); | |
ASSERT (FALSE); | |
} | |
/** | |
Check and execute the pending TPM request and Lock TPM. | |
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. At last, it will lock TPM to prevent TPM state change by malware. | |
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. This API should also | |
be invoked as early as possible as TPM is locked in this function. | |
**/ | |
VOID | |
EFIAPI | |
TcgPhysicalPresenceLibProcessRequest ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
BOOLEAN LifetimeLock; | |
BOOLEAN CmdEnable; | |
UINTN DataSize; | |
EFI_PHYSICAL_PRESENCE TcgPpData; | |
EFI_TCG_PROTOCOL *TcgProtocol; | |
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; | |
EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags; | |
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); | |
if (EFI_ERROR (Status)) { | |
return ; | |
} | |
// | |
// Initialize physical presence flags. | |
// | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS); | |
Status = gRT->GetVariable ( | |
PHYSICAL_PRESENCE_FLAGS_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
NULL, | |
&DataSize, | |
&PpiFlags | |
); | |
if (EFI_ERROR (Status)) { | |
PpiFlags.PPFlags = TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION; | |
Status = gRT->SetVariable ( | |
PHYSICAL_PRESENCE_FLAGS_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
sizeof (EFI_PHYSICAL_PRESENCE_FLAGS), | |
&PpiFlags | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence flag failed, Status = %r\n", Status)); | |
return ; | |
} | |
} | |
DEBUG ((EFI_D_INFO, "[TPM] PpiFlags = %x\n", PpiFlags.PPFlags)); | |
// | |
// 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, | |
PHYSICAL_PRESENCE_FLAGS_VARIABLE, | |
&gEfiPhysicalPresenceGuid | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((EFI_D_ERROR, "[TPM] Error when lock variable %s, Status = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status)); | |
ASSERT_EFI_ERROR (Status); | |
} | |
} | |
// | |
// Initialize physical presence variable. | |
// | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE); | |
Status = gRT->GetVariable ( | |
PHYSICAL_PRESENCE_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
NULL, | |
&DataSize, | |
&TcgPpData | |
); | |
if (EFI_ERROR (Status)) { | |
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData)); | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE); | |
Status = gRT->SetVariable ( | |
PHYSICAL_PRESENCE_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
DataSize, | |
&TcgPpData | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence variable failed, Status = %r\n", Status)); | |
return; | |
} | |
} | |
DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags.PPFlags, TcgPpData.PPRequest)); | |
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) { | |
// | |
// No operation request | |
// | |
return; | |
} | |
Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable); | |
if (EFI_ERROR (Status)) { | |
return ; | |
} | |
if (!CmdEnable) { | |
if (LifetimeLock) { | |
// | |
// physicalPresenceCMDEnable is locked, can't execute physical presence command. | |
// | |
return ; | |
} | |
Status = TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD_ENABLE); | |
if (EFI_ERROR (Status)) { | |
return ; | |
} | |
} | |
// | |
// Set operator physical presence flags | |
// | |
TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESENT); | |
// | |
// Execute pending TPM request. | |
// | |
ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags); | |
DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse)); | |
// | |
// Lock physical presence. | |
// | |
TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK); | |
} | |
/** | |
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 | |
TcgPhysicalPresenceLibNeedUserConfirm( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_PHYSICAL_PRESENCE TcgPpData; | |
UINTN DataSize; | |
BOOLEAN RequestConfirmed; | |
BOOLEAN LifetimeLock; | |
BOOLEAN CmdEnable; | |
EFI_TCG_PROTOCOL *TcgProtocol; | |
EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags; | |
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); | |
if (EFI_ERROR (Status)) { | |
return FALSE; | |
} | |
// | |
// Check Tpm requests | |
// | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE); | |
Status = gRT->GetVariable ( | |
PHYSICAL_PRESENCE_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
NULL, | |
&DataSize, | |
&TcgPpData | |
); | |
if (EFI_ERROR (Status)) { | |
return FALSE; | |
} | |
DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS); | |
Status = gRT->GetVariable ( | |
PHYSICAL_PRESENCE_FLAGS_VARIABLE, | |
&gEfiPhysicalPresenceGuid, | |
NULL, | |
&DataSize, | |
&PpiFlags | |
); | |
if (EFI_ERROR (Status)) { | |
return FALSE; | |
} | |
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) { | |
// | |
// No operation request | |
// | |
return FALSE; | |
} | |
if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) { | |
// | |
// Invalid operation request. | |
// | |
return FALSE; | |
} | |
// | |
// Check Tpm Capability | |
// | |
Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable); | |
if (EFI_ERROR (Status)) { | |
return FALSE; | |
} | |
if (!CmdEnable) { | |
if (LifetimeLock) { | |
// | |
// physicalPresenceCMDEnable is locked, can't execute physical presence command. | |
// | |
return FALSE; | |
} | |
} | |
if (!RequestConfirmed) { | |
// | |
// Need UI to confirm | |
// | |
return TRUE; | |
} | |
return FALSE; | |
} | |