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

Reply via email to