]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c
SecurityPkg/OpalPassword: Add PCD to skip password prompt
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPassword / OpalDriver.c
index ed7f9682559a6208f30478a52912301e71f3ebcd..e14fa32354ea09c7665e661c95ba0dcbe48e7c63 100644 (file)
@@ -424,6 +424,52 @@ BuildOpalDeviceInfo (
   FreePool (S3InitDevices);\r
 }\r
 \r
+/**\r
+\r
+  Send BlockSid command if needed.\r
+\r
+**/\r
+VOID\r
+SendBlockSidCommand (\r
+  VOID\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE                         *Itr;\r
+  TCG_RESULT                                 Result;\r
+  OPAL_SESSION                               Session;\r
+  UINT32                                     PpStorageFlag;\r
+\r
+  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
+  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
+    //\r
+    // Send BlockSID command to each Opal disk\r
+    //\r
+    Itr = mOpalDriver.DeviceList;\r
+    while (Itr != NULL) {\r
+      if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
+        ZeroMem(&Session, sizeof(Session));\r
+        Session.Sscp = Itr->OpalDisk.Sscp;\r
+        Session.MediaId = Itr->OpalDisk.MediaId;\r
+        Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
+\r
+        DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));\r
+        Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE\r
+        if (Result != TcgResultSuccess) {\r
+          DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
+          break;\r
+        }\r
+\r
+        //\r
+        // Record BlockSID command has been sent.\r
+        //\r
+        Itr->OpalDisk.SentBlockSID = TRUE;\r
+      }\r
+\r
+      Itr = Itr->Next;\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.\r
 \r
@@ -475,6 +521,11 @@ OpalEndOfDxeEventNotify (
     TmpDev = TmpDev->Next;\r
   }\r
 \r
+  //\r
+  // Send BlockSid command if needed.\r
+  //\r
+  SendBlockSidCommand ();\r
+\r
   DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));\r
 \r
   gBS->CloseEvent (Event);\r
@@ -487,6 +538,7 @@ OpalEndOfDxeEventNotify (
                             OPAL request.\r
   @param[in]  PopUpString   Pop up string.\r
   @param[in]  PopUpString2  Pop up string in line 2.\r
+  @param[in]  PopUpString3  Pop up string in line 3.\r
 \r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
@@ -498,6 +550,7 @@ OpalDriverPopUpPsidInput (
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString,\r
   IN CHAR16                 *PopUpString2,\r
+  IN CHAR16                 *PopUpString3,\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
@@ -527,15 +580,28 @@ OpalDriverPopUpPsidInput (
         NULL\r
       );\r
     } else {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &InputKey,\r
-        PopUpString,\r
-        PopUpString2,\r
-        L"---------------------",\r
-        Mask,\r
-        NULL\r
-      );\r
+      if (PopUpString3 == NULL) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString,\r
+          PopUpString2,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString,\r
+          PopUpString2,\r
+          PopUpString3,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      }\r
     }\r
 \r
     //\r
@@ -625,6 +691,7 @@ OpalDriverPopUpPsidInput (
                             process OPAL request.\r
   @param[in]  PopUpString1  Pop up string 1.\r
   @param[in]  PopUpString2  Pop up string 2.\r
+  @param[in]  PopUpString3  Pop up string 3.\r
   @param[out] PressEsc      Whether user escape function through Press ESC.\r
 \r
   @retval Password string if success. NULL if failed.\r
@@ -635,6 +702,7 @@ OpalDriverPopUpPasswordInput (
   IN OPAL_DRIVER_DEVICE     *Dev,\r
   IN CHAR16                 *PopUpString1,\r
   IN CHAR16                 *PopUpString2,\r
+  IN CHAR16                 *PopUpString3,\r
   OUT BOOLEAN               *PressEsc\r
   )\r
 {\r
@@ -664,15 +732,28 @@ OpalDriverPopUpPasswordInput (
         NULL\r
       );\r
     } else {\r
-      CreatePopUp (\r
-        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
-        &InputKey,\r
-        PopUpString1,\r
-        PopUpString2,\r
-        L"---------------------",\r
-        Mask,\r
-        NULL\r
-      );\r
+      if (PopUpString3 == NULL) {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString1,\r
+          PopUpString2,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      } else {\r
+        CreatePopUp (\r
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+          &InputKey,\r
+          PopUpString1,\r
+          PopUpString2,\r
+          PopUpString3,\r
+          L"---------------------",\r
+          Mask,\r
+          NULL\r
+        );\r
+      }\r
     }\r
 \r
     //\r
@@ -818,12 +899,24 @@ OpalDriverRequestPassword (
 \r
     IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
 \r
-    if (IsLocked && PcdGetBool (PcdSkipOpalDxeUnlock)) {\r
-      return;\r
+    //\r
+    // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.\r
+    // Due to board design, device may not power off during system warm boot, which result in\r
+    // security status remain unlocked status, hence we add device security status check here.\r
+    //\r
+    // If device is in the locked status, device keeps locked and system continues booting.\r
+    // If device is in the unlocked status, system is forced shutdown to support security requirement.\r
+    //\r
+    if (PcdGetBool (PcdSkipOpalPasswordPrompt)) {\r
+      if (IsLocked) {\r
+        return;\r
+      } else {\r
+        gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);\r
+      }\r
     }\r
 \r
     while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-      Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+      Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
       if (PressEsc) {\r
         if (IsLocked) {\r
           //\r
@@ -988,7 +1081,7 @@ ProcessOpalRequestEnableFeature (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1017,7 +1110,7 @@ ProcessOpalRequestEnableFeature (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (Password, PasswordLen);\r
       FreePool (Password);\r
@@ -1132,7 +1225,7 @@ ProcessOpalRequestDisableUser (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1227,6 +1320,7 @@ ProcessOpalRequestPsidRevert (
   TCG_RESULT            Ret;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
@@ -1238,17 +1332,19 @@ ProcessOpalRequestPsidRevert (
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
   if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
-    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");\r
+    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
-        L"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",\r
+        L"WARNING: Revert action will take about %d seconds",\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
+    PopUpString3 = L"DO NOT power off system during the revert action!";\r
   } else {\r
     PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
   }\r
 \r
   Count = 0;\r
@@ -1259,7 +1355,7 @@ ProcessOpalRequestPsidRevert (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PSID_TRY_COUNT) {\r
-    Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, &PressEsc);\r
+    Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1361,6 +1457,7 @@ ProcessOpalRequestRevert (
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
   CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
   UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
@@ -1373,17 +1470,19 @@ ProcessOpalRequestRevert (
 \r
   if ((!KeepUserData) &&\r
       (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) {\r
-    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");\r
+    BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds");\r
     PopUpString2 = AllocateZeroPool (BufferSize);\r
     ASSERT (PopUpString2 != NULL);\r
     UnicodeSPrint (\r
         PopUpString2,\r
         BufferSize,\r
-        L"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",\r
+        L"WARNING: Revert action will take about %d seconds",\r
         Dev->OpalDisk.EstimateTimeCost\r
       );\r
+    PopUpString3 = L"DO NOT power off system during the revert action!";\r
   } else {\r
     PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
   }\r
 \r
   Count = 0;\r
@@ -1394,7 +1493,7 @@ ProcessOpalRequestRevert (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1520,6 +1619,9 @@ ProcessOpalRequestSecureErase (
   TCG_RESULT            Ret;\r
   BOOLEAN               PasswordFailed;\r
   CHAR16                *PopUpString;\r
+  CHAR16                *PopUpString2;\r
+  CHAR16                *PopUpString3;\r
+  UINTN                 BufferSize;\r
 \r
   if (Dev == NULL) {\r
     return;\r
@@ -1529,6 +1631,21 @@ ProcessOpalRequestSecureErase (
 \r
   PopUpString = OpalGetPopUpString (Dev, RequestString);\r
 \r
+  if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {\r
+    BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds");\r
+    PopUpString2 = AllocateZeroPool (BufferSize);\r
+    ASSERT (PopUpString2 != NULL);\r
+    UnicodeSPrint (\r
+        PopUpString2,\r
+        BufferSize,\r
+        L"WARNING: Secure erase action will take about %d seconds",\r
+        Dev->OpalDisk.EstimateTimeCost\r
+      );\r
+    PopUpString3 = L"DO NOT power off system during the action!";\r
+  } else {\r
+    PopUpString2 = NULL;\r
+    PopUpString3 = NULL;\r
+  }\r
   Count = 0;\r
 \r
   ZeroMem(&Session, sizeof(Session));\r
@@ -1537,7 +1654,7 @@ ProcessOpalRequestSecureErase (
   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1551,7 +1668,7 @@ ProcessOpalRequestSecureErase (
 \r
         if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
           gST->ConOut->ClearScreen(gST->ConOut);\r
-          return;\r
+          goto Done;\r
         } else {\r
           //\r
           // Let user input password again.\r
@@ -1608,6 +1725,11 @@ ProcessOpalRequestSecureErase (
     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
     gST->ConOut->ClearScreen(gST->ConOut);\r
   }\r
+\r
+Done:\r
+  if (PopUpString2 != NULL) {\r
+    FreePool (PopUpString2);\r
+  }\r
 }\r
 \r
 /**\r
@@ -1647,7 +1769,7 @@ ProcessOpalRequestSetUserPwd (
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc);\r
+    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1705,7 +1827,7 @@ ProcessOpalRequestSetUserPwd (
       }\r
     }\r
 \r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -1714,7 +1836,7 @@ ProcessOpalRequestSetUserPwd (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -1846,7 +1968,7 @@ ProcessOpalRequestSetAdminPwd (
   Count = 0;\r
 \r
   while (Count < MAX_PASSWORD_TRY_COUNT) {\r
-    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc);\r
+    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);\r
     if (PressEsc) {\r
         do {\r
           CreatePopUp (\r
@@ -1899,7 +2021,7 @@ ProcessOpalRequestSetAdminPwd (
       continue;\r
     }\r
 \r
-    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc);\r
+    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);\r
     if (Password == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -1908,7 +2030,7 @@ ProcessOpalRequestSetAdminPwd (
     }\r
     PasswordLen = (UINT32) AsciiStrLen(Password);\r
 \r
-    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc);\r
+    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);\r
     if (PasswordConfirm == NULL) {\r
       ZeroMem (OldPassword, OldPasswordLen);\r
       FreePool (OldPassword);\r
@@ -2099,6 +2221,12 @@ ProcessOpalRequest (
         ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");\r
       }\r
 \r
+      //\r
+      // Update Device ownership.\r
+      // Later BlockSID command may block the update.\r
+      //\r
+      OpalDiskUpdateOwnerShip (&Dev->OpalDisk);\r
+\r
       break;\r
     }\r
 \r
@@ -2203,53 +2331,6 @@ OpalDriverGetDeviceList(
   return mOpalDriver.DeviceList;\r
 }\r
 \r
-/**\r
-  ReadyToBoot callback to send BlockSid command.\r
-\r
-  @param  Event   Pointer to this event\r
-  @param  Context Event handler private Data\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ReadyToBootCallback (\r
-  IN EFI_EVENT        Event,\r
-  IN VOID             *Context\r
-  )\r
-{\r
-  OPAL_DRIVER_DEVICE                         *Itr;\r
-  TCG_RESULT                                 Result;\r
-  OPAL_SESSION                               Session;\r
-  UINT32                                     PpStorageFlag;\r
-\r
-  gBS->CloseEvent (Event);\r
-\r
-  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();\r
-  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {\r
-    //\r
-    // Send BlockSID command to each Opal disk\r
-    //\r
-    Itr = mOpalDriver.DeviceList;\r
-    while (Itr != NULL) {\r
-      if (Itr->OpalDisk.SupportedAttributes.BlockSid) {\r
-        ZeroMem(&Session, sizeof(Session));\r
-        Session.Sscp = Itr->OpalDisk.Sscp;\r
-        Session.MediaId = Itr->OpalDisk.MediaId;\r
-        Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
-\r
-        DEBUG ((DEBUG_INFO, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));\r
-        Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE\r
-        if (Result != TcgResultSuccess) {\r
-          DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
-          break;\r
-        }\r
-      }\r
-\r
-      Itr = Itr->Next;\r
-    }\r
-  }\r
-}\r
-\r
 /**\r
   Stop this Controller.\r
 \r
@@ -2512,7 +2593,6 @@ EfiDriverEntryPoint(
   )\r
 {\r
   EFI_STATUS                     Status;\r
-  EFI_EVENT                      ReadyToBootEvent;\r
   EFI_EVENT                      EndOfDxeEvent;\r
 \r
   Status = EfiLibInstallDriverBindingComponentName2 (\r
@@ -2545,16 +2625,6 @@ EfiDriverEntryPoint(
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // register a ReadyToBoot event callback for sending BlockSid command\r
-  //\r
-  Status = EfiCreateEventReadyToBootEx (\r
-                  TPL_CALLBACK,\r
-                  ReadyToBootCallback,\r
-                  (VOID *) &ImageHandle,\r
-                  &ReadyToBootEvent\r
-                  );\r
-\r
   //\r
   // Install Hii packages.\r
   //\r