summaryrefslogtreecommitdiff
path: root/SecurityPkg/Library/DxeTcgPhysicalPresenceLib
diff options
context:
space:
mode:
authorczhang46 <czhang46@6f19259b-4bc3-4df7-8a09-765794883524>2012-11-01 04:46:26 +0000
committerczhang46 <czhang46@6f19259b-4bc3-4df7-8a09-765794883524>2012-11-01 04:46:26 +0000
commit482114024e0f82cd235e5741aaed437ee371ffbb (patch)
tree1f818759cc5708e23a38df7ae4f9d04706fa1221 /SecurityPkg/Library/DxeTcgPhysicalPresenceLib
parent16cd325fc1d7b8f9e668ee8f12fced2b643f1b01 (diff)
downloadedk2-482114024e0f82cd235e5741aaed437ee371ffbb.zip
edk2-482114024e0f82cd235e5741aaed437ee371ffbb.tar.gz
edk2-482114024e0f82cd235e5741aaed437ee371ffbb.tar.bz2
Add Physical Presence request UI detection logic. Refine UIConfirm ReadKey logic
Signed-off-by : chao zhang <chao.b.zhang@intel.com> Reviewed-by : dong guo <guo.dong@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13908 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'SecurityPkg/Library/DxeTcgPhysicalPresenceLib')
-rw-r--r--SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c246
1 files changed, 191 insertions, 55 deletions
diff --git a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
index 4b99ab8..2130b2b 100644
--- a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
+++ b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
@@ -440,7 +440,7 @@ ExecutePhysicalPresence (
If false, F10 is used as confirm key.
@retval TRUE User confirmed the changes by input.
- @retval FALSE User discarded the changes.
+ @retval FALSE User discarded the changes or device error.
**/
BOOLEAN
@@ -451,22 +451,29 @@ ReadUserKey (
EFI_STATUS Status;
EFI_INPUT_KEY Key;
UINT16 InputKey;
-
+ UINTN Index;
+
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;
- }
- }
+ 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) {
@@ -886,32 +893,34 @@ UserConfirm (
}
/**
- 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.
+ 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] TcgProtocol EFI TCG Protocol instance.
+ @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.
**/
-VOID
-ExecutePendingTpmRequest (
- IN EFI_TCG_PROTOCOL *TcgProtocol,
- IN EFI_PHYSICAL_PRESENCE *TcgPpData
+BOOLEAN
+HaveValidTpmRequest (
+ IN EFI_PHYSICAL_PRESENCE *TcgPpData,
+ OUT BOOLEAN *RequestConfirmed
)
{
- EFI_STATUS Status;
- UINTN DataSize;
UINT8 Flags;
- BOOLEAN RequestConfirmed;
+
+ Flags = TcgPpData->Flags;
+ *RequestConfirmed = FALSE;
- Flags = TcgPpData->Flags;
- RequestConfirmed = FALSE;
switch (TcgPpData->PPRequest) {
case PHYSICAL_PRESENCE_NO_ACTION:
- return;
+ *RequestConfirmed = TRUE;
+ return TRUE;
case PHYSICAL_PRESENCE_ENABLE:
case PHYSICAL_PRESENCE_DISABLE:
case PHYSICAL_PRESENCE_ACTIVATE:
@@ -924,64 +933,106 @@ ExecutePendingTpmRequest (
case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
if ((Flags & FLAG_NO_PPI_PROVISION) != 0) {
- RequestConfirmed = TRUE;
+ *RequestConfirmed = TRUE;
}
break;
case PHYSICAL_PRESENCE_CLEAR:
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
if ((Flags & FLAG_NO_PPI_CLEAR) != 0) {
- RequestConfirmed = TRUE;
+ *RequestConfirmed = TRUE;
}
break;
case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) {
- RequestConfirmed = TRUE;
+ *RequestConfirmed = TRUE;
}
break;
case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) {
- RequestConfirmed = TRUE;
+ *RequestConfirmed = TRUE;
}
- break;
+ 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;
+ *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:
//
- // Invalid operation request.
+ // Wrong Physical Presence command
//
- TcgPpData->PPResponse = TPM_PP_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;
+ return FALSE;
}
if ((Flags & FLAG_RESET_TRACK) != 0) {
//
// It had been confirmed in last boot, it doesn't need confirm again.
//
- RequestConfirmed = TRUE;
+ *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.
+
+**/
+VOID
+ExecutePendingTpmRequest (
+ IN EFI_TCG_PROTOCOL *TcgProtocol,
+ IN EFI_PHYSICAL_PRESENCE *TcgPpData
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ BOOLEAN RequestConfirmed;
+
+ if (TcgPpData->PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
+ //
+ // No operation request
+ //
+ return;
+ }
+
+ if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) {
+ //
+ // Invalid operation request.
+ //
+ TcgPpData->PPResponse = TPM_PP_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;
}
if (!RequestConfirmed) {
@@ -1149,3 +1200,88 @@ TcgPhysicalPresenceLibProcessRequest (
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;
+
+ 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;
+ }
+
+ if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
+ //
+ // No operation request
+ //
+ return FALSE;
+ }
+
+ if (!HaveValidTpmRequest(&TcgPpData, &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;
+}
+