Enhance TPM driver to protect TPM physical presence flags.
Signed-off-by: Dong Guo <guo.dong@intel.com> Reviewed-by: Yao Jiewen <jiewen.yao@intel.com> Reviewed-by: Ouyang, Qian <qian.ouyang@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14619 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -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.
|
||||
//
|
||||
|
Reference in New Issue
Block a user