]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c
Add TPM Physical Presence >=128 operation value support.
[mirror_edk2.git] / SecurityPkg / Library / DxeTrEEPhysicalPresenceLib / DxeTrEEPhysicalPresenceLib.c
index 89ce436b7ca5d0a14ea2809749f449397e567ea0..9ff9d888ddcf7884afb4acb9a996dfac29c7c5c7 100644 (file)
@@ -7,7 +7,7 @@
 \r
   TrEEExecutePendingTpmRequest() will receive untrusted input and do validation.\r
 \r
-Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2013 - 2015, 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
@@ -34,10 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/EventGroup.h>\r
 #include <Guid/TrEEPhysicalPresenceData.h>\r
 #include <Library/Tpm2CommandLib.h>\r
-\r
-#define TPM_PP_SUCCESS              0\r
-#define TPM_PP_USER_ABORT           ((TPM_RESULT)(-0x10))\r
-#define TPM_PP_BIOS_FAILURE         ((TPM_RESULT)(-0x0f))\r
+#include <Library/TrEEPpVendorLib.h>\r
 \r
 #define CONFIRM_BUFFER_SIZE         4096\r
 \r
@@ -113,16 +110,16 @@ Done:
   @param[in]      CommandCode         Physical presence operation value.\r
   @param[in, out] PpiFlags            The physical presence interface flags.\r
   \r
-  @retval TPM_PP_BIOS_FAILURE         Unknown physical presence operation.\r
-  @retval TPM_PP_BIOS_FAILURE         Error occurred during sending command to TPM or \r
-                                      receiving response from TPM.\r
-  @retval Others                      Return code from the TPM device after command execution.\r
+  @retval TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE  Unknown physical presence operation.\r
+  @retval TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE  Error occurred during sending command to TPM or \r
+                                                   receiving response from TPM.\r
+  @retval Others                                   Return code from the TPM device after command execution.\r
 **/\r
-TPM_RESULT\r
+UINT32\r
 TrEEExecutePhysicalPresence (\r
-  IN      TPM2B_AUTH                *PlatformAuth,  OPTIONAL\r
-  IN      UINT8                     CommandCode,\r
-  IN OUT  UINT8                     *PpiFlags\r
+  IN      TPM2B_AUTH                       *PlatformAuth,  OPTIONAL\r
+  IN      UINT32                           CommandCode,\r
+  IN OUT  EFI_TREE_PHYSICAL_PRESENCE_FLAGS *PpiFlags\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -134,24 +131,24 @@ TrEEExecutePhysicalPresence (
     case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
       Status = TpmCommandClear (PlatformAuth);\r
       if (EFI_ERROR (Status)) {\r
-        return TPM_PP_BIOS_FAILURE;\r
+        return TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
       } else {\r
-        return TPM_PP_SUCCESS;\r
+        return TREE_PP_OPERATION_RESPONSE_SUCCESS;\r
       }\r
 \r
     case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
-      *PpiFlags &= ~TREE_FLAG_NO_PPI_CLEAR;\r
-      return TPM_PP_SUCCESS;\r
+      PpiFlags->PPFlags &= ~TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;\r
+      return TREE_PP_OPERATION_RESPONSE_SUCCESS;\r
 \r
     case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
-      *PpiFlags |= TREE_FLAG_NO_PPI_CLEAR;\r
-      return TPM_PP_SUCCESS;\r
+      PpiFlags->PPFlags |= TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;\r
+      return TREE_PP_OPERATION_RESPONSE_SUCCESS;\r
 \r
     default:\r
       if (CommandCode <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
-        return TPM_PP_SUCCESS;\r
+        return TREE_PP_OPERATION_RESPONSE_SUCCESS;\r
       } else {\r
-        return TPM_PP_BIOS_FAILURE;\r
+        return TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
       }\r
   }\r
 }\r
@@ -233,7 +230,7 @@ TrEEPhysicalPresenceLibConstructor (
 **/\r
 BOOLEAN\r
 TrEEUserConfirm (\r
-  IN      UINT                    TpmPpCommand\r
+  IN      UINT32                    TpmPpCommand\r
   )\r
 {\r
   CHAR16                            *ConfirmText;\r
@@ -346,11 +343,13 @@ TrEEUserConfirm (
 **/\r
 BOOLEAN\r
 TrEEHaveValidTpmRequest  (\r
-  IN      EFI_TREE_PHYSICAL_PRESENCE     *TcgPpData,\r
-  IN      UINT8                          Flags,\r
-  OUT     BOOLEAN                        *RequestConfirmed\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE       *TcgPpData,\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE_FLAGS Flags,\r
+  OUT     BOOLEAN                          *RequestConfirmed\r
   )\r
 {\r
+  BOOLEAN  IsRequestValid;\r
+\r
   *RequestConfirmed = FALSE;\r
 \r
   switch (TcgPpData->PPRequest) {\r
@@ -361,7 +360,7 @@ TrEEHaveValidTpmRequest  (
     case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
     case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
     case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
-      if ((Flags & TREE_FLAG_NO_PPI_CLEAR) != 0) {\r
+      if ((Flags.PPFlags & TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {\r
         *RequestConfirmed = TRUE;\r
       }\r
       break;\r
@@ -374,13 +373,22 @@ TrEEHaveValidTpmRequest  (
       break;\r
 \r
     default:\r
-      //\r
-      // Wrong Physical Presence command\r
-      //\r
-      return FALSE;\r
+      if (TcgPpData->PPRequest >= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+        IsRequestValid = TrEEPpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);\r
+        if (!IsRequestValid) {\r
+          return FALSE;\r
+        } else {\r
+          break;\r
+        }\r
+      } else {\r
+        //\r
+        // Wrong Physical Presence command\r
+        //\r
+        return FALSE;\r
+      }\r
   }\r
 \r
-  if ((Flags & TREE_FLAG_RESET_TRACK) != 0) {\r
+  if ((Flags.PPFlags & TREE_VENDOR_LIB_FLAG_RESET_TRACK) != 0) {\r
     //\r
     // It had been confirmed in last boot, it doesn't need confirm again.\r
     //\r
@@ -407,15 +415,17 @@ TrEEHaveValidTpmRequest  (
 **/\r
 VOID\r
 TrEEExecutePendingTpmRequest (\r
-  IN      TPM2B_AUTH                     *PlatformAuth,  OPTIONAL\r
-  IN      EFI_TREE_PHYSICAL_PRESENCE     *TcgPpData,\r
-  IN      UINT8                          Flags\r
+  IN      TPM2B_AUTH                       *PlatformAuth,  OPTIONAL\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE       *TcgPpData,\r
+  IN      EFI_TREE_PHYSICAL_PRESENCE_FLAGS Flags\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
   UINTN                             DataSize;\r
   BOOLEAN                           RequestConfirmed;\r
-  UINT8                             NewFlags;\r
+  EFI_TREE_PHYSICAL_PRESENCE_FLAGS  NewFlags;\r
+  BOOLEAN                           ResetRequired;\r
+  UINT32                            NewPPFlags;\r
 \r
   if (TcgPpData->PPRequest == TREE_PHYSICAL_PRESENCE_NO_ACTION) {\r
     //\r
@@ -429,9 +439,9 @@ TrEEExecutePendingTpmRequest (
     // Invalid operation request.\r
     //\r
     if (TcgPpData->PPRequest <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
-      TcgPpData->PPResponse = TPM_PP_SUCCESS;\r
+      TcgPpData->PPResponse = TREE_PP_OPERATION_RESPONSE_SUCCESS;\r
     } else {\r
-      TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE;\r
+      TcgPpData->PPResponse = TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE;\r
     }\r
     TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
     TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;\r
@@ -446,33 +456,41 @@ TrEEExecutePendingTpmRequest (
     return;\r
   }\r
 \r
-  if (!RequestConfirmed) {\r
+  ResetRequired = FALSE;\r
+  if (TcgPpData->PPRequest >= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+    NewFlags = Flags;\r
+    NewPPFlags = NewFlags.PPFlags;\r
+    TcgPpData->PPResponse = TrEEPpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);\r
+    NewFlags.PPFlags = (UINT8)NewPPFlags;\r
+  } else {\r
+    if (!RequestConfirmed) {\r
+      //\r
+      // Print confirm text and wait for approval. \r
+      //\r
+      RequestConfirmed = TrEEUserConfirm (TcgPpData->PPRequest\r
+                                          );\r
+    }\r
+\r
     //\r
-    // Print confirm text and wait for approval. \r
+    // Execute requested physical presence command\r
     //\r
-    RequestConfirmed = TrEEUserConfirm (TcgPpData->PPRequest\r
-                                        );\r
-  }\r
-\r
-  //\r
-  // Execute requested physical presence command\r
-  //\r
-  TcgPpData->PPResponse = TPM_PP_USER_ABORT;\r
-  NewFlags = Flags;\r
-  if (RequestConfirmed) {\r
-    TcgPpData->PPResponse = TrEEExecutePhysicalPresence (PlatformAuth, TcgPpData->PPRequest, \r
-                                                         &NewFlags);\r
+    TcgPpData->PPResponse = TREE_PP_OPERATION_RESPONSE_USER_ABORT;\r
+    NewFlags = Flags;\r
+    if (RequestConfirmed) {\r
+      TcgPpData->PPResponse = TrEEExecutePhysicalPresence (PlatformAuth, TcgPpData->PPRequest, \r
+                                                           &NewFlags);\r
+    }\r
   }\r
 \r
   //\r
   // Save the flags if it is updated.\r
   //\r
-  if (Flags != NewFlags) {\r
+  if (CompareMem (&Flags, &NewFlags, sizeof(EFI_TREE_PHYSICAL_PRESENCE_FLAGS)) != 0) {\r
     Status   = gRT->SetVariable (\r
                       TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
                       &gEfiTrEEPhysicalPresenceGuid,\r
                       EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                      sizeof (UINT8),\r
+                      sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS),\r
                       &NewFlags\r
                       ); \r
   }\r
@@ -480,7 +498,7 @@ TrEEExecutePendingTpmRequest (
   //\r
   // Clear request\r
   //\r
-  if ((NewFlags & TREE_FLAG_RESET_TRACK) == 0) {\r
+  if ((NewFlags.PPFlags & TREE_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {\r
     TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
     TcgPpData->PPRequest = TREE_PHYSICAL_PRESENCE_NO_ACTION;    \r
   }\r
@@ -500,7 +518,7 @@ TrEEExecutePendingTpmRequest (
     return;\r
   }\r
 \r
-  if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) {\r
+  if (TcgPpData->PPResponse == TREE_PP_OPERATION_RESPONSE_USER_ABORT) {\r
     return;\r
   }\r
 \r
@@ -514,6 +532,13 @@ TrEEExecutePendingTpmRequest (
     case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
       break;\r
     default:\r
+      if (TcgPpData->LastPPRequest >= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
+        if (ResetRequired) {\r
+          break;\r
+        } else {\r
+          return ;\r
+        }\r
+      }\r
       if (TcgPpData->PPRequest != TREE_PHYSICAL_PRESENCE_NO_ACTION) {\r
         break;\r
       }\r
@@ -549,7 +574,7 @@ TrEEPhysicalPresenceLibProcessRequest (
   EFI_TREE_PHYSICAL_PRESENCE        TcgPpData;\r
   EFI_TREE_PROTOCOL                 *TreeProtocol;\r
   EDKII_VARIABLE_LOCK_PROTOCOL      *VariableLockProtocol;\r
-  UINT8                             PpiFlags;\r
+  EFI_TREE_PHYSICAL_PRESENCE_FLAGS  PpiFlags;\r
 \r
   Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
   if (EFI_ERROR (Status)) {\r
@@ -559,7 +584,7 @@ TrEEPhysicalPresenceLibProcessRequest (
   //\r
   // Initialize physical presence flags.\r
   //\r
-  DataSize = sizeof (UINT8);\r
+  DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS);\r
   Status = gRT->GetVariable (\r
                   TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
                   &gEfiTrEEPhysicalPresenceGuid,\r
@@ -568,12 +593,12 @@ TrEEPhysicalPresenceLibProcessRequest (
                   &PpiFlags\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    PpiFlags = 0;\r
+    PpiFlags.PPFlags = 0;\r
     Status   = gRT->SetVariable (\r
                       TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
                       &gEfiTrEEPhysicalPresenceGuid,\r
                       EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                      sizeof (UINT8),\r
+                      sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS),\r
                       &PpiFlags\r
                       );\r
     if (EFI_ERROR (Status)) {\r
@@ -581,7 +606,7 @@ TrEEPhysicalPresenceLibProcessRequest (
       return ;\r
     }\r
   }\r
-  DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags));\r
+  DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags.PPFlags));\r
 \r
   //\r
   // This flags variable controls whether physical presence is required for TPM command. \r
@@ -627,13 +652,13 @@ TrEEPhysicalPresenceLibProcessRequest (
     }\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
+  DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));\r
 \r
   //\r
   // Execute pending TPM request.\r
   //  \r
   TrEEExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);\r
-  DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags));\r
+  DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));\r
 \r
 }\r
 \r
@@ -658,7 +683,7 @@ TrEEPhysicalPresenceLibNeedUserConfirm(
   UINTN                             DataSize;\r
   BOOLEAN                           RequestConfirmed;\r
   EFI_TREE_PROTOCOL                 *TreeProtocol;\r
-  UINT8                             PpiFlags;\r
+  EFI_TREE_PHYSICAL_PRESENCE_FLAGS  PpiFlags;\r
 \r
   Status = gBS->LocateProtocol (&gEfiTrEEProtocolGuid, NULL, (VOID **) &TreeProtocol);\r
   if (EFI_ERROR (Status)) {\r
@@ -680,7 +705,7 @@ TrEEPhysicalPresenceLibNeedUserConfirm(
     return FALSE;\r
   }\r
 \r
-  DataSize = sizeof (UINT8);\r
+  DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS);\r
   Status = gRT->GetVariable (\r
                   TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
                   &gEfiTrEEPhysicalPresenceGuid,\r