\r
ExecutePendingTpmRequest() will receive untrusted input and do validation.\r
\r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials \r
are licensed and made available under the terms and conditions of the BSD License \r
which accompanies this distribution. The full text of the license may be found at \r
#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
Check if there is a valid physical presence command request. Also updates parameter value \r
to whether the requested physical presence command already confirmed by user\r
\r
- @param[in] TcgProtocol EFI TCG Protocol instance. \r
- @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.\r
- True, it indicates the command doesn't require user confirm, or already confirmed \r
- in last boot cycle by user.\r
- False, it indicates the command need user confirm from UI.\r
+ @param[in] TcgPpData EFI TCG Physical Presence request data.\r
+ @param[in] Flags The physical presence interface flags. \r
+ @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.\r
+ True, it indicates the command doesn't require user confirm, or already confirmed \r
+ in last boot cycle by user.\r
+ False, it indicates the command need user confirm from UI.\r
\r
@retval TRUE Physical Presence operation command is valid.\r
@retval FALSE Physical Presence operation command is invalid.\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
\r
@param[in] TcgProtocol EFI TCG Protocol instance. \r
@param[in] TcgPpData Point to the physical presence NV variable.\r
+ @param[in] Flags The physical presence interface flags.\r
\r
**/\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 (TcgPpData->PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {\r
- //\r
- // No operation request\r
- //\r
- return;\r
- }\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
+ if (EFI_ERROR (Status)) {\r
+ return;\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
+ 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
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence flag failed, Status = %r\n", Status));\r
+ return ;\r
+ }\r
+ }\r
+ DEBUG ((EFI_D_INFO, "[TPM] PpiFlags = %x\n", PpiFlags));\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
&TcgPpData\r
);\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
- &gEfiPhysicalPresenceGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- DataSize,\r
- &TcgPpData\r
- );\r
+ ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
+ DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
+ Status = gRT->SetVariable (\r
+ PHYSICAL_PRESENCE_VARIABLE,\r
+ &gEfiPhysicalPresenceGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ DataSize,\r
+ &TcgPpData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence variable failed, Status = %r\n", Status));\r
+ return;\r
}\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
+ // No operation request\r
+ //\r
+ return;\r
+ }\r
\r
Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);\r
if (EFI_ERROR (Status)) {\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