summaryrefslogtreecommitdiff
path: root/SecurityPkg
diff options
context:
space:
mode:
Diffstat (limited to 'SecurityPkg')
-rw-r--r--SecurityPkg/Include/Guid/PhysicalPresenceData.h25
-rw-r--r--SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c98
-rw-r--r--SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf3
-rw-r--r--SecurityPkg/Tcg/TcgSmm/TcgSmm.c19
4 files changed, 120 insertions, 25 deletions
diff --git a/SecurityPkg/Include/Guid/PhysicalPresenceData.h b/SecurityPkg/Include/Guid/PhysicalPresenceData.h
index 4db20a7b1..942865784 100644
--- a/SecurityPkg/Include/Guid/PhysicalPresenceData.h
+++ b/SecurityPkg/Include/Guid/PhysicalPresenceData.h
@@ -4,7 +4,7 @@
cleared after it is processed in the next boot cycle. The TPM response
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
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
@@ -29,18 +29,9 @@ typedef struct {
UINT8 PPRequest; ///< Physical Presence request command.
UINT8 LastPPRequest;
UINT32 PPResponse;
- UINT8 Flags;
} 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
//
#define PHYSICAL_PRESENCE_NO_ACTION 0
@@ -67,6 +58,20 @@ typedef struct {
#define PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR 21
#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;
#endif
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.
//
diff --git a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
index 0a197fd31..d700ed2e8 100644
--- a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
+++ b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
@@ -6,7 +6,7 @@
# This driver will have external input - variable.
# 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
# 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
@@ -53,6 +53,7 @@
[Protocols]
gEfiTcgProtocolGuid
+ gEdkiiVariableLockProtocolGuid
[Guids]
gEfiPhysicalPresenceGuid
diff --git a/SecurityPkg/Tcg/TcgSmm/TcgSmm.c b/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
index 7a16b9ca2..97cd916d0 100644
--- a/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
+++ b/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
@@ -8,7 +8,7 @@
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
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
@@ -103,7 +103,22 @@ PhysicalPresenceCallback (
}
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS;
} 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;
switch (mTcgNvs->PhysicalPresence.Request) {