]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
SecurityPkg/Tcg2Dxe: Properly shutdown TPM before reset
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Dxe / Tcg2Dxe.c
index c2c52e32b88ac9e4ad7bbe20bb12e2c443f47129..e2f346217aab9e276a5c06d6e9a618ec0fe5cfa6 100644 (file)
@@ -31,6 +31,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/VariableWrite.h>\r
 #include <Protocol/Tcg2Protocol.h>\r
 #include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/ResetNotification.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
@@ -2412,6 +2413,68 @@ OnExitBootServicesFailed (
 \r
 }\r
 \r
+/**\r
+  This routine is called to properly shutdown the TPM before system reset.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\r
+\r
+  @param[in]  ResetType         The type of reset to perform.\r
+  @param[in]  ResetStatus       The status code for the reset.\r
+  @param[in]  DataSize          The size, in bytes, of ResetData.\r
+  @param[in]  ResetData         For a ResetType of EfiResetCold, EfiResetWarm, or\r
+                                EfiResetShutdown the data buffer starts with a Null-terminated\r
+                                string, optionally followed by additional binary data.\r
+                                The string is a description that the caller may use to further\r
+                                indicate the reason for the system reset. ResetData is only\r
+                                valid if ResetStatus is something other than EFI_SUCCESS\r
+                                unless the ResetType is EfiResetPlatformSpecific\r
+                                where a minimum amount of ResetData is always required.\r
+                                For a ResetType of EfiResetPlatformSpecific the data buffer\r
+                                also starts with a Null-terminated string that is followed\r
+                                by an EFI_GUID that describes the specific type of reset to perform.\r
+**/\r
+VOID\r
+EFIAPI\r
+ShutdownTpmOnReset (\r
+  IN EFI_RESET_TYPE           ResetType,\r
+  IN EFI_STATUS               ResetStatus,\r
+  IN UINTN                    DataSize,\r
+  IN VOID                     *ResetData OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
+  DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
+}\r
+\r
+/**\r
+  Hook the system reset to properly shutdown TPM.\r
+  It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+  Part 1: Architecture, Revision 01.16.\r
+\r
+  @param[in]  Event     Event whose notification function is being invoked\r
+  @param[in]  Context   Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+OnResetNotificationInstall (\r
+  IN EFI_EVENT                      Event,\r
+  IN VOID                           *Context\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_RESET_NOTIFICATION_PROTOCOL   *ResetNotify;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
+    ASSERT_EFI_ERROR (Status);\r
+    DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
+\r
+    gBS->CloseEvent (Event);\r
+  }\r
+}\r
+\r
 /**\r
   The function install Tcg2 protocol.\r
   \r
@@ -2609,6 +2672,11 @@ DriverEntry (
     // may update SecureBoot value based on last setting.\r
     //\r
     EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+\r
+    //\r
+    // Hook the system reset to properly shutdown TPM.\r
+    //\r
+    EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
   }\r
 \r
   //\r