#include <PiDxe.h>\r
\r
#include <Protocol/TcgService.h>\r
+#include <Protocol/VariableLock.h>\r
#include <Library/DebugLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/UefiRuntimeServicesTableLib.h>\r
BOOLEAN\r
HaveValidTpmRequest (\r
IN EFI_PHYSICAL_PRESENCE *TcgPpData,\r
+ IN UINT8 Flags,\r
OUT BOOLEAN *RequestConfirmed\r
)\r
{\r
- UINT8 Flags;\r
- \r
- Flags = TcgPpData->Flags;\r
+\r
*RequestConfirmed = FALSE;\r
\r
switch (TcgPpData->PPRequest) {\r
VOID\r
ExecutePendingTpmRequest (\r
IN EFI_TCG_PROTOCOL *TcgProtocol,\r
- IN EFI_PHYSICAL_PRESENCE *TcgPpData\r
+ IN EFI_PHYSICAL_PRESENCE *TcgPpData,\r
+ IN UINT8 Flags\r
)\r
{\r
EFI_STATUS Status;\r
UINTN DataSize;\r
BOOLEAN RequestConfirmed;\r
+ UINT8 NewFlags;\r
\r
- if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) {\r
+ if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {\r
//\r
// Invalid operation request.\r
//\r
// Execute requested physical presence command\r
//\r
TcgPpData->PPResponse = TPM_PP_USER_ABORT;\r
+ NewFlags = Flags;\r
if (RequestConfirmed) {\r
- TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags);\r
+ TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags);\r
}\r
\r
+ //\r
+ // Save the flags if it is updated.\r
+ //\r
+ if (Flags != NewFlags) {\r
+ Status = gRT->SetVariable (\r
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ sizeof (UINT8),\r
+ &NewFlags\r
+ ); \r
+ }\r
+\r
+\r
//\r
// Clear request\r
//\r
- if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {\r
+ if ((NewFlags & FLAG_RESET_TRACK) == 0) {\r
TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; \r
}\r
UINTN DataSize;\r
EFI_PHYSICAL_PRESENCE TcgPpData;\r
EFI_TCG_PROTOCOL *TcgProtocol;\r
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;\r
+ UINT8 PpiFlags;\r
\r
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
if (EFI_ERROR (Status)) {\r
return ;\r
}\r
+\r
+ //\r
+ // Initialize physical presence flags.\r
+ //\r
+ DataSize = sizeof (UINT8);\r
+ Status = gRT->GetVariable (\r
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &PpiFlags\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ PpiFlags = FLAG_NO_PPI_PROVISION;\r
+ Status = gRT->SetVariable (\r
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ sizeof (UINT8),\r
+ &PpiFlags\r
+ );\r
+ }\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ DEBUG ((EFI_D_ERROR, "[TPM] PpiFlags = %x, Status = %r\n", PpiFlags, Status));\r
+\r
+ //\r
+ // This flags variable controls whether physical presence is required for TPM command. \r
+ // It should be protected from malicious software. We set it as read-only variable here.\r
+ //\r
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = VariableLockProtocol->RequestToLock (\r
+ VariableLockProtocol,\r
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[TPM] Error when lock variable %s, Status = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
\r
//\r
// Initialize physical presence variable.\r
if (EFI_ERROR (Status)) {\r
if (Status == EFI_NOT_FOUND) {\r
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
- TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;\r
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
Status = gRT->SetVariable (\r
PHYSICAL_PRESENCE_VARIABLE,\r
ASSERT_EFI_ERROR (Status);\r
}\r
\r
- DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest));\r
+ DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags, TcgPpData.PPRequest));\r
\r
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {\r
//\r
//\r
// Execute pending TPM request.\r
// \r
- ExecutePendingTpmRequest (TcgProtocol, &TcgPpData);\r
+ ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags);\r
DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));\r
\r
//\r
BOOLEAN LifetimeLock;\r
BOOLEAN CmdEnable;\r
EFI_TCG_PROTOCOL *TcgProtocol;\r
-\r
+ UINT8 PpiFlags;\r
+ \r
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
if (EFI_ERROR (Status)) {\r
return FALSE;\r
return FALSE;\r
}\r
\r
+ DataSize = sizeof (UINT8);\r
+ Status = gRT->GetVariable (\r
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &PpiFlags\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+ \r
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {\r
//\r
// No operation request\r
return FALSE;\r
}\r
\r
- if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) {\r
+ if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {\r
//\r
// Invalid operation request.\r
//\r