SecurityPkg: Tcg2: Fix TCG2 PP issues
authorZhang, Chao B <chao.b.zhang@intel.com>
Tue, 27 Sep 2016 01:46:40 +0000 (09:46 +0800)
committerZhang, Chao B <chao.b.zhang@intel.com>
Thu, 29 Sep 2016 02:30:30 +0000 (10:30 +0800)
Several issues exist in TCG2 PP
1. TCG2 PP use NVS PPRQ/PPRM as PP parameter as well as current
PP state cache. But it doesn't handle PP set failure case
2. TCG2 PP Submit TPM Operation Request to Pre-OS Environment forgets
to clean PPRM
3. Potential alignment issue

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Chao Zhang <chao.b.zhang@intel.com>
Reviewed-by: Qin Long <qin.long@intel.com>
SecurityPkg/Include/Library/Tcg2PhysicalPresenceLib.h
SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
SecurityPkg/Tcg/Tcg2Smm/Tpm.asl

index ce45f174549651197ae4720edd611b6abcd4e4b1..1bee13a5113a89c452f2f8be82d3ac02146ea602 100644 (file)
@@ -2,7 +2,7 @@
   Ihis library is intended to be used by BDS modules.\r
   This library will execute TPM2 request.\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials \r
 are licensed and made available under the terms and conditions of the BSD License \r
 which accompanies this distribution.  The full text of the license may be found at \r
@@ -116,6 +116,26 @@ Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
   OUT UINT32                *Response\r
   );\r
 \r
+/**\r
+  The handler for TPM physical presence function:\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+\r
+  @param[in out]  Pointer to OperationRequest TPM physical presence operation request.\r
+  @param[in out]  Pointer to RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+        Submit TPM Operation Request to Pre-OS Environment 2.\r
+  **/\r
+UINT32\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
+  IN OUT UINT32               *OperationRequest,\r
+  IN OUT UINT32               *RequestParameter\r
+  );\r
 \r
 /**\r
   The handler for TPM physical presence function:\r
@@ -125,7 +145,7 @@ Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
   This API should be invoked in OS runtime phase to interface with ACPI method.\r
 \r
   Caution: This function may receive untrusted input.\r
-  \r
+\r
   @param[in]      OperationRequest TPM physical presence operation request.\r
   @param[in]      RequestParameter TPM physical presence operation request parameter.\r
 \r
index 081ec6c00c55cc042491561c6a4678021fa4a6cf..8fcce74aef3753d049e011b9f2990a384371cc04 100644 (file)
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmVariable.h>\r
 \r
 #include <Library/DebugLib.h>\r
+#include <Library/BaseMemorylib.h>\r
 #include <Library/Tcg2PpVendorLib.h>\r
 #include <Library/SmmServicesTableLib.h>\r
 \r
@@ -89,26 +90,27 @@ Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
   This API should be invoked in OS runtime phase to interface with ACPI method.\r
 \r
   Caution: This function may receive untrusted input.\r
-  \r
-  @param[in]      OperationRequest TPM physical presence operation request.\r
-  @param[in]      RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @param[in out]  Pointer to OperationRequest TPM physical presence operation request.\r
+  @param[in out]  Pointer to RequestParameter TPM physical presence operation request parameter.\r
 \r
   @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
-          Submit TPM Operation Request to Pre-OS Environment 2.\r
-**/\r
+        Submit TPM Operation Request to Pre-OS Environment 2.\r
+  **/\r
 UINT32\r
-EFIAPI\r
-Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
-  IN UINT32                 OperationRequest,\r
-  IN UINT32                 RequestParameter\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
+  IN OUT UINT32               *OperationRequest,\r
+  IN OUT UINT32               *RequestParameter\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
+  UINT32                            ReturnCode;\r
   UINTN                             DataSize;\r
   EFI_TCG2_PHYSICAL_PRESENCE        PpData;\r
   EFI_TCG2_PHYSICAL_PRESENCE_FLAGS  Flags;\r
 \r
-  DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));\r
+  DEBUG ((EFI_D_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", *OperationRequest, *RequestParameter));\r
+  ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
 \r
   //\r
   // Get the Physical Presence variable\r
@@ -123,21 +125,23 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
                                  );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
-    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+    ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+    goto EXIT;\r
   }\r
 \r
-  if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
-      (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
+  if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
+      (*OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
     //\r
     // This command requires UI to prompt user for Auth data.\r
     //\r
-    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+    ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+    goto EXIT;\r
   }\r
 \r
-  if ((PpData.PPRequest != OperationRequest) ||\r
-      (PpData.PPRequestParameter != RequestParameter)) {\r
-    PpData.PPRequest = (UINT8)OperationRequest;\r
-    PpData.PPRequestParameter = RequestParameter;\r
+  if ((PpData.PPRequest != *OperationRequest) ||\r
+      (PpData.PPRequestParameter != *RequestParameter)) {\r
+    PpData.PPRequest = (UINT8)*OperationRequest;\r
+    PpData.PPRequestParameter = *RequestParameter;\r
     DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
     Status = mTcg2PpSmmVariable->SmmSetVariable (\r
                                    TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
@@ -150,10 +154,11 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
 \r
   if (EFI_ERROR (Status)) { \r
     DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
-    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+    ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+    goto EXIT;\r
   }\r
 \r
-  if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+  if (*OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
     DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);\r
     Status = mTcg2PpSmmVariable->SmmGetVariable (\r
                                    TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
@@ -165,10 +170,60 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
     if (EFI_ERROR (Status)) {\r
       Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
     }\r
-    return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
+    ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
   }\r
 \r
-  return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
+EXIT:\r
+  //\r
+  // Sync PPRQ/PPRM from PP Variable if PP submission fails\r
+  //\r
+  if (ReturnCode != TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {\r
+    DEBUG ((EFI_D_ERROR, "[TPM2] Submit PP Request failure! Sync PPRQ/PPRM with PP variable.\n", Status));\r
+    DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);\r
+    ZeroMem(&PpData, DataSize);\r
+    Status = mTcg2PpSmmVariable->SmmGetVariable (\r
+                                   TCG2_PHYSICAL_PRESENCE_VARIABLE,\r
+                                   &gEfiTcg2PhysicalPresenceGuid,\r
+                                   NULL,\r
+                                   &DataSize,\r
+                                   &PpData\r
+                                   );\r
+    *OperationRequest = (UINT32)PpData.PPRequest;\r
+    *RequestParameter = PpData.PPRequestParameter;\r
+  }\r
+\r
+  return ReturnCode;\r
+}\r
+\r
+/**\r
+  The handler for TPM physical presence function:\r
+  Submit TPM Operation Request to Pre-OS Environment and\r
+  Submit TPM Operation Request to Pre-OS Environment 2.\r
+\r
+  This API should be invoked in OS runtime phase to interface with ACPI method.\r
+\r
+  Caution: This function may receive untrusted input.\r
+  \r
+  @param[in]      OperationRequest TPM physical presence operation request.\r
+  @param[in]      RequestParameter TPM physical presence operation request parameter.\r
+\r
+  @return Return Code for Submit TPM Operation Request to Pre-OS Environment and\r
+          Submit TPM Operation Request to Pre-OS Environment 2.\r
+**/\r
+UINT32\r
+EFIAPI\r
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
+  IN UINT32                 OperationRequest,\r
+  IN UINT32                 RequestParameter\r
+  )\r
+{\r
+  UINT32                 TempOperationRequest;\r
+  UINT32                 TempRequestParameter;\r
+\r
+  TempOperationRequest = OperationRequest;\r
+  TempRequestParameter = RequestParameter;\r
+\r
+  return Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx(&TempOperationRequest, &TempRequestParameter);\r
 }\r
 \r
 /**\r
index f3b76418a2e60c4efff10e8ec40276ee7dc169b8..d02123dfa61fb282420675d7dd8533afc0a96a1c 100644 (file)
@@ -119,6 +119,9 @@ PhysicalPresenceCallback (
 {\r
   UINT32                MostRecentRequest;\r
   UINT32                Response;\r
+  UINT32                OperationRequest;\r
+  UINT32                RequestParameter;\r
+\r
 \r
   if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {\r
     mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (\r
@@ -130,10 +133,15 @@ PhysicalPresenceCallback (
     return EFI_SUCCESS;\r
   } else if ((mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) \r
           || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) {\r
-    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (\r
-                                             mTcgNvs->PhysicalPresence.Request,\r
-                                             mTcgNvs->PhysicalPresence.RequestParameter\r
+\r
+    OperationRequest = mTcgNvs->PhysicalPresence.Request;\r
+    RequestParameter = mTcgNvs->PhysicalPresence.RequestParameter;\r
+    mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (\r
+                                             &OperationRequest,\r
+                                             &RequestParameter\r
                                              );\r
+    mTcgNvs->PhysicalPresence.Request = OperationRequest;\r
+    mTcgNvs->PhysicalPresence.RequestParameter = RequestParameter;\r
   } else if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {\r
     mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (mTcgNvs->PPRequestUserConfirm);\r
   }\r
index 84143cfce98ed78e2108ebf8c44f27cd656f5b36..2083a3e2cebb8a62265d52ee510ef4872050c61b 100644 (file)
@@ -198,6 +198,7 @@ DefinitionBlock (
             //\r
                   \r
             Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
+            Store (0, PPRM)\r
             Store (0x02, PPIP)\r
               \r
             //\r