]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.c
SecurityPkg: Support PP version lower than 1.3
[mirror_edk2.git] / SecurityPkg / Library / SmmTcg2PhysicalPresenceLib / SmmTcg2PhysicalPresenceLib.c
index 081ec6c00c55cc042491561c6a4678021fa4a6cf..dfef6c8ca0c8a2e9b1a9894daefe2b628d8e97fe 100644 (file)
@@ -10,7 +10,7 @@
   Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction() and Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction()\r
   will receive untrusted input and do validation.\r
 \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, 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
@@ -27,11 +27,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <Protocol/SmmVariable.h>\r
 \r
+#include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
 #include <Library/Tcg2PpVendorLib.h>\r
 #include <Library/SmmServicesTableLib.h>\r
 \r
+#define     PP_INF_VERSION_1_2    "1.2"\r
+\r
 EFI_SMM_VARIABLE_PROTOCOL  *mTcg2PpSmmVariable;\r
+BOOLEAN                    mIsTcg2PPVerLowerThan_1_3 = FALSE;\r
 \r
 /**\r
   The handler for TPM physical presence function:\r
@@ -89,26 +94,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 +129,20 @@ 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
-    //\r
-    // This command requires UI to prompt user for Auth data.\r
-    //\r
-    return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
+  if ((*OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
+      (*OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) ) {\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
@@ -146,14 +151,14 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
                                    DataSize,\r
                                    &PpData\r
                                    );\r
+    if (EFI_ERROR (Status)) { \r
+      DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
+      ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
+      goto EXIT;\r
+    }\r
   }\r
 \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
-  }\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
@@ -163,12 +168,62 @@ Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
                                    &Flags\r
                                    );\r
     if (EFI_ERROR (Status)) {\r
-      Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT;\r
+      Flags.PPFlags = TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT | TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_DEFAULT;\r
     }\r
-    return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);\r
+    ReturnCode = Tcg2PpVendorLibSubmitRequestToPreOSFunction (*OperationRequest, Flags.PPFlags, *RequestParameter);\r
+  }\r
+\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 TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\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
@@ -240,6 +295,7 @@ Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
       }\r
       break;\r
 \r
+    case TCG2_PHYSICAL_PRESENCE_NO_ACTION:\r
     case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:\r
       RequestConfirmed = TRUE;\r
       break;\r
@@ -263,13 +319,44 @@ Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
       RequestConfirmed = TRUE;\r
       break;\r
 \r
-    default:\r
-      if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+    case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:\r
+      if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {\r
         RequestConfirmed = TRUE;\r
-      } else {\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:\r
+      if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {\r
+        RequestConfirmed = TRUE;\r
+      }\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:\r
+      RequestConfirmed = TRUE;\r
+      break;\r
+\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:\r
+    case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:\r
+      break;\r
+\r
+    default:\r
+      if (mIsTcg2PPVerLowerThan_1_3 == FALSE) {\r
         if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+          //\r
+          // TCG2 PP1.3 spec defined operations that are reserved or un-implemented\r
+          //\r
           return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
         }\r
+      } else {\r
+       //\r
+       // TCG PP lower than 1.3. (1.0, 1.1, 1.2)\r
+       //\r
+       if (OperationRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
+         RequestConfirmed = TRUE;\r
+       } else if (OperationRequest < TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+         return TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
+       }\r
       }\r
       break;\r
   }\r
@@ -286,7 +373,7 @@ Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (
 }\r
 \r
 /**\r
-  The constructor function register UNI strings into imageHandle.\r
+  The constructor function locates SmmVariable protocol.\r
   \r
   It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
 \r
@@ -305,6 +392,10 @@ Tcg2PhysicalPresenceLibConstructor (
 {\r
   EFI_STATUS  Status;\r
 \r
+  if (AsciiStrnCmp(PP_INF_VERSION_1_2, (CHAR8 *)PcdGetPtr(PcdTcgPhysicalPresenceInterfaceVer), sizeof(PP_INF_VERSION_1_2) - 1) <= 0) {\r
+    mIsTcg2PPVerLowerThan_1_3 = TRUE;\r
+  }\r
+\r
   //\r
   // Locate SmmVariableProtocol.\r
   //\r