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:
parent
db06c2d723
commit
ed094569d6
|
@ -4,7 +4,7 @@
|
||||||
cleared after it is processed in the next boot cycle. The TPM response
|
cleared after it is processed in the next boot cycle. The TPM response
|
||||||
is saved to variable.
|
is saved to variable.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -29,17 +29,8 @@ typedef struct {
|
||||||
UINT8 PPRequest; ///< Physical Presence request command.
|
UINT8 PPRequest; ///< Physical Presence request command.
|
||||||
UINT8 LastPPRequest;
|
UINT8 LastPPRequest;
|
||||||
UINT32 PPResponse;
|
UINT32 PPResponse;
|
||||||
UINT8 Flags;
|
|
||||||
} EFI_PHYSICAL_PRESENCE;
|
} EFI_PHYSICAL_PRESENCE;
|
||||||
|
|
||||||
//
|
|
||||||
// The definition bit of the flags
|
|
||||||
//
|
|
||||||
#define FLAG_NO_PPI_PROVISION BIT0
|
|
||||||
#define FLAG_NO_PPI_CLEAR BIT1
|
|
||||||
#define FLAG_NO_PPI_MAINTENANCE BIT2
|
|
||||||
#define FLAG_RESET_TRACK BIT3
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// The definition of physical presence operation actions
|
// The definition of physical presence operation actions
|
||||||
//
|
//
|
||||||
|
@ -67,6 +58,20 @@ typedef struct {
|
||||||
#define PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR 21
|
#define PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR 21
|
||||||
#define PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE 22
|
#define PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE 22
|
||||||
|
|
||||||
|
//
|
||||||
|
// This variable is used to save TPM Management Flags and corresponding operations.
|
||||||
|
// It should be protected from malicious software (e.g. Set it as read-only variable).
|
||||||
|
//
|
||||||
|
#define PHYSICAL_PRESENCE_FLAGS_VARIABLE L"PhysicalPresenceFlags"
|
||||||
|
|
||||||
|
//
|
||||||
|
// The definition bit of the TPM Management Flags
|
||||||
|
//
|
||||||
|
#define FLAG_NO_PPI_PROVISION BIT0
|
||||||
|
#define FLAG_NO_PPI_CLEAR BIT1
|
||||||
|
#define FLAG_NO_PPI_MAINTENANCE BIT2
|
||||||
|
#define FLAG_RESET_TRACK BIT3
|
||||||
|
|
||||||
extern EFI_GUID gEfiPhysicalPresenceGuid;
|
extern EFI_GUID gEfiPhysicalPresenceGuid;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
|
||||||
#include <Protocol/TcgService.h>
|
#include <Protocol/TcgService.h>
|
||||||
|
#include <Protocol/VariableLock.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
@ -909,12 +910,11 @@ UserConfirm (
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
HaveValidTpmRequest (
|
HaveValidTpmRequest (
|
||||||
IN EFI_PHYSICAL_PRESENCE *TcgPpData,
|
IN EFI_PHYSICAL_PRESENCE *TcgPpData,
|
||||||
|
IN UINT8 Flags,
|
||||||
OUT BOOLEAN *RequestConfirmed
|
OUT BOOLEAN *RequestConfirmed
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT8 Flags;
|
|
||||||
|
|
||||||
Flags = TcgPpData->Flags;
|
|
||||||
*RequestConfirmed = FALSE;
|
*RequestConfirmed = FALSE;
|
||||||
|
|
||||||
switch (TcgPpData->PPRequest) {
|
switch (TcgPpData->PPRequest) {
|
||||||
|
@ -1003,14 +1003,16 @@ HaveValidTpmRequest (
|
||||||
VOID
|
VOID
|
||||||
ExecutePendingTpmRequest (
|
ExecutePendingTpmRequest (
|
||||||
IN EFI_TCG_PROTOCOL *TcgProtocol,
|
IN EFI_TCG_PROTOCOL *TcgProtocol,
|
||||||
IN EFI_PHYSICAL_PRESENCE *TcgPpData
|
IN EFI_PHYSICAL_PRESENCE *TcgPpData,
|
||||||
|
IN UINT8 Flags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN DataSize;
|
UINTN DataSize;
|
||||||
BOOLEAN RequestConfirmed;
|
BOOLEAN RequestConfirmed;
|
||||||
|
UINT8 NewFlags;
|
||||||
|
|
||||||
if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) {
|
if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {
|
||||||
//
|
//
|
||||||
// Invalid operation request.
|
// Invalid operation request.
|
||||||
//
|
//
|
||||||
|
@ -1039,14 +1041,29 @@ ExecutePendingTpmRequest (
|
||||||
// Execute requested physical presence command
|
// Execute requested physical presence command
|
||||||
//
|
//
|
||||||
TcgPpData->PPResponse = TPM_PP_USER_ABORT;
|
TcgPpData->PPResponse = TPM_PP_USER_ABORT;
|
||||||
|
NewFlags = Flags;
|
||||||
if (RequestConfirmed) {
|
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
|
// Clear request
|
||||||
//
|
//
|
||||||
if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {
|
if ((NewFlags & FLAG_RESET_TRACK) == 0) {
|
||||||
TcgPpData->LastPPRequest = TcgPpData->PPRequest;
|
TcgPpData->LastPPRequest = TcgPpData->PPRequest;
|
||||||
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
|
TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
|
||||||
}
|
}
|
||||||
|
@ -1123,12 +1140,57 @@ TcgPhysicalPresenceLibProcessRequest (
|
||||||
UINTN DataSize;
|
UINTN DataSize;
|
||||||
EFI_PHYSICAL_PRESENCE TcgPpData;
|
EFI_PHYSICAL_PRESENCE TcgPpData;
|
||||||
EFI_TCG_PROTOCOL *TcgProtocol;
|
EFI_TCG_PROTOCOL *TcgProtocol;
|
||||||
|
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
|
||||||
|
UINT8 PpiFlags;
|
||||||
|
|
||||||
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
|
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return ;
|
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.
|
// Initialize physical presence variable.
|
||||||
//
|
//
|
||||||
|
@ -1143,7 +1205,6 @@ TcgPhysicalPresenceLibProcessRequest (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if (Status == EFI_NOT_FOUND) {
|
if (Status == EFI_NOT_FOUND) {
|
||||||
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
|
ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
|
||||||
TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;
|
|
||||||
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
|
DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
|
||||||
Status = gRT->SetVariable (
|
Status = gRT->SetVariable (
|
||||||
PHYSICAL_PRESENCE_VARIABLE,
|
PHYSICAL_PRESENCE_VARIABLE,
|
||||||
|
@ -1156,7 +1217,7 @@ TcgPhysicalPresenceLibProcessRequest (
|
||||||
ASSERT_EFI_ERROR (Status);
|
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) {
|
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
|
||||||
//
|
//
|
||||||
|
@ -1191,7 +1252,7 @@ TcgPhysicalPresenceLibProcessRequest (
|
||||||
//
|
//
|
||||||
// Execute pending TPM request.
|
// Execute pending TPM request.
|
||||||
//
|
//
|
||||||
ExecutePendingTpmRequest (TcgProtocol, &TcgPpData);
|
ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags);
|
||||||
DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
|
DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1223,6 +1284,7 @@ TcgPhysicalPresenceLibNeedUserConfirm(
|
||||||
BOOLEAN LifetimeLock;
|
BOOLEAN LifetimeLock;
|
||||||
BOOLEAN CmdEnable;
|
BOOLEAN CmdEnable;
|
||||||
EFI_TCG_PROTOCOL *TcgProtocol;
|
EFI_TCG_PROTOCOL *TcgProtocol;
|
||||||
|
UINT8 PpiFlags;
|
||||||
|
|
||||||
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
|
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
@ -1244,6 +1306,18 @@ TcgPhysicalPresenceLibNeedUserConfirm(
|
||||||
return FALSE;
|
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) {
|
if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
|
||||||
//
|
//
|
||||||
// No operation request
|
// No operation request
|
||||||
|
@ -1251,7 +1325,7 @@ TcgPhysicalPresenceLibNeedUserConfirm(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) {
|
if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
|
||||||
//
|
//
|
||||||
// Invalid operation request.
|
// Invalid operation request.
|
||||||
//
|
//
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# This driver will have external input - variable.
|
# This driver will have external input - variable.
|
||||||
# This external input must be validated carefully to avoid security issue.
|
# This external input must be validated carefully to avoid security issue.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiTcgProtocolGuid
|
gEfiTcgProtocolGuid
|
||||||
|
gEdkiiVariableLockProtocolGuid
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiPhysicalPresenceGuid
|
gEfiPhysicalPresenceGuid
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
|
PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
|
||||||
|
|
||||||
Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -103,7 +103,22 @@ PhysicalPresenceCallback (
|
||||||
}
|
}
|
||||||
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS;
|
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS;
|
||||||
} else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
|
} else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
|
||||||
Flags = PpData.Flags;
|
//
|
||||||
|
// Get the Physical Presence flags
|
||||||
|
//
|
||||||
|
DataSize = sizeof (UINT8);
|
||||||
|
Status = mSmmVariable->SmmGetVariable (
|
||||||
|
PHYSICAL_PRESENCE_FLAGS_VARIABLE,
|
||||||
|
&gEfiPhysicalPresenceGuid,
|
||||||
|
NULL,
|
||||||
|
&DataSize,
|
||||||
|
&Flags
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
RequestConfirmed = FALSE;
|
RequestConfirmed = FALSE;
|
||||||
|
|
||||||
switch (mTcgNvs->PhysicalPresence.Request) {
|
switch (mTcgNvs->PhysicalPresence.Request) {
|
||||||
|
|
Loading…
Reference in New Issue