summaryrefslogtreecommitdiff
path: root/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c')
-rw-r--r--SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c98
1 files changed, 86 insertions, 12 deletions
diff --git a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
index 3414cd2ea..427cc8d66 100644
--- a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
+++ b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
@@ -22,6 +22,7 @@ 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>
@@ -909,12 +910,11 @@ UserConfirm (
BOOLEAN
HaveValidTpmRequest (
IN EFI_PHYSICAL_PRESENCE *TcgPpData,
+ IN UINT8 Flags,
OUT BOOLEAN *RequestConfirmed
)
{
- UINT8 Flags;
-
- Flags = TcgPpData->Flags;
+
*RequestConfirmed = FALSE;
switch (TcgPpData->PPRequest) {
@@ -1003,14 +1003,16 @@ HaveValidTpmRequest (
VOID
ExecutePendingTpmRequest (
IN EFI_TCG_PROTOCOL *TcgProtocol,
- IN EFI_PHYSICAL_PRESENCE *TcgPpData
+ IN EFI_PHYSICAL_PRESENCE *TcgPpData,
+ IN UINT8 Flags
)
{
EFI_STATUS Status;
UINTN DataSize;
BOOLEAN RequestConfirmed;
+ UINT8 NewFlags;
- if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) {
+ if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {
//
// Invalid operation request.
//
@@ -1039,14 +1041,29 @@ ExecutePendingTpmRequest (
// Execute requested physical presence command
//
TcgPpData->PPResponse = TPM_PP_USER_ABORT;
+ NewFlags = Flags;
if (RequestConfirmed) {
- TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags);
+ TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags);
}
//
+ // Save the flags if it is updated.
+ //
+ if (Flags != NewFlags) {
+ Status = gRT->SetVariable (
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (UINT8),
+ &NewFlags
+ );
+ }
+
+
+ //
// Clear request
//
- if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {
+ if ((NewFlags & FLAG_RESET_TRACK) == 0) {
TcgPpData->LastPPRequest = TcgPpData->PPRequest;
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
}
@@ -1123,11 +1140,56 @@ TcgPhysicalPresenceLibProcessRequest (
UINTN DataSize;
EFI_PHYSICAL_PRESENCE TcgPpData;
EFI_TCG_PROTOCOL *TcgProtocol;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
+ UINT8 PpiFlags;
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
if (EFI_ERROR (Status)) {
return ;
}
+
+ //
+ // Initialize physical presence flags.
+ //
+ DataSize = sizeof (UINT8);
+ Status = gRT->GetVariable (
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ PpiFlags = 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 (UINT8),
+ &PpiFlags
+ );
+ }
+ ASSERT_EFI_ERROR (Status);
+ }
+ DEBUG ((EFI_D_ERROR, "[TPM] PpiFlags = %x, Status = %r\n", PpiFlags, Status));
+
+ //
+ // 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.
@@ -1143,7 +1205,6 @@ TcgPhysicalPresenceLibProcessRequest (
if (EFI_ERROR (Status)) {
if (Status == EFI_NOT_FOUND) {
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
- TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
Status = gRT->SetVariable (
PHYSICAL_PRESENCE_VARIABLE,
@@ -1156,7 +1217,7 @@ TcgPhysicalPresenceLibProcessRequest (
ASSERT_EFI_ERROR (Status);
}
- DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest));
+ DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags, TcgPpData.PPRequest));
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
//
@@ -1191,7 +1252,7 @@ TcgPhysicalPresenceLibProcessRequest (
//
// Execute pending TPM request.
//
- ExecutePendingTpmRequest (TcgProtocol, &TcgPpData);
+ ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags);
DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
//
@@ -1223,7 +1284,8 @@ TcgPhysicalPresenceLibNeedUserConfirm(
BOOLEAN LifetimeLock;
BOOLEAN CmdEnable;
EFI_TCG_PROTOCOL *TcgProtocol;
-
+ UINT8 PpiFlags;
+
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
if (EFI_ERROR (Status)) {
return FALSE;
@@ -1244,6 +1306,18 @@ TcgPhysicalPresenceLibNeedUserConfirm(
return FALSE;
}
+ DataSize = sizeof (UINT8);
+ 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
@@ -1251,7 +1325,7 @@ TcgPhysicalPresenceLibNeedUserConfirm(
return FALSE;
}
- if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) {
+ if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
//
// Invalid operation request.
//