Revision: 14619
http://sourceforge.net/p/edk2/code/14619
Author: gdong1
Date: 2013-09-03 07:39:26 +0000 (Tue, 03 Sep 2013)
Log Message:
-----------
Enhance TPM driver to protect TPM physical presence flags.
Signed-off-by: Dong Guo <[email protected]>
Reviewed-by: Yao Jiewen <[email protected]>
Reviewed-by: Ouyang, Qian <[email protected]>
Modified Paths:
--------------
trunk/edk2/SecurityPkg/Include/Guid/PhysicalPresenceData.h
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
trunk/edk2/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
Modified: trunk/edk2/SecurityPkg/Include/Guid/PhysicalPresenceData.h
===================================================================
--- trunk/edk2/SecurityPkg/Include/Guid/PhysicalPresenceData.h 2013-09-02
13:13:29 UTC (rev 14618)
+++ trunk/edk2/SecurityPkg/Include/Guid/PhysicalPresenceData.h 2013-09-03
07:39:26 UTC (rev 14619)
@@ -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 @@
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 @@
#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
Modified:
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
===================================================================
---
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
2013-09-02 13:13:29 UTC (rev 14618)
+++
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
2013-09-03 07:39:26 UTC (rev 14619)
@@ -22,6 +22,7 @@
#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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
//
// 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 @@
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 @@
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 @@
return FALSE;
}
- if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) {
+ if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
//
// Invalid operation request.
//
Modified:
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
===================================================================
---
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
2013-09-02 13:13:29 UTC (rev 14618)
+++
trunk/edk2/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf
2013-09-03 07:39:26 UTC (rev 14619)
@@ -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
Modified: trunk/edk2/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
===================================================================
--- trunk/edk2/SecurityPkg/Tcg/TcgSmm/TcgSmm.c 2013-09-02 13:13:29 UTC (rev
14618)
+++ trunk/edk2/SecurityPkg/Tcg/TcgSmm/TcgSmm.c 2013-09-03 07:39:26 UTC (rev
14619)
@@ -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 @@
}
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) {
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits