2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
17 // HII GUI to manage Opal features if the device is Opal capable
18 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
19 // window during boot requesting a user password
21 #include "OpalDriver.h"
24 EFI_GUID mOpalDeviceLockBoxGuid
= OPAL_DEVICE_LOCKBOX_GUID
;
26 BOOLEAN mOpalEndOfDxe
= FALSE
;
27 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
28 UINTN mOpalRequestVariableSize
= 0;
29 CHAR16 mPopUpString
[100];
31 OPAL_DRIVER mOpalDriver
;
36 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
37 OpalEfiDriverBindingSupported
,
38 OpalEfiDriverBindingStart
,
39 OpalEfiDriverBindingStop
,
47 The function determines the available actions for the OPAL_DISK provided.
49 @param[in] SupportedAttributes The supported attributes for the device.
50 @param[in] LockingFeature The locking status for the device.
51 @param[in] OwnerShip The ownership for the device.
52 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
57 OpalSupportGetAvailableActions(
58 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
59 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
61 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
64 BOOLEAN ExistingPassword
;
66 NULL_CHECK(AvalDiskActions
);
68 AvalDiskActions
->AdminPass
= 1;
69 AvalDiskActions
->UserPass
= 0;
70 AvalDiskActions
->DisableUser
= 0;
71 AvalDiskActions
->Unlock
= 0;
74 // Revert is performed on locking sp, so only allow if locking sp is enabled
76 if (LockingFeature
->LockingEnabled
) {
77 AvalDiskActions
->Revert
= 1;
81 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
83 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
86 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
87 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
88 // intact and accessible
90 AvalDiskActions
->PsidRevert
= 1;
91 AvalDiskActions
->RevertKeepDataForced
= 0;
94 // Secure erase is performed by generating a new encryption key
95 // this is only available if encryption is supported
97 AvalDiskActions
->SecureErase
= 1;
99 AvalDiskActions
->PsidRevert
= 0;
100 AvalDiskActions
->SecureErase
= 0;
103 // If no media encryption is supported, then a revert (using password) will not
104 // erase the Data (since you can't generate a new encryption key)
106 AvalDiskActions
->RevertKeepDataForced
= 1;
109 if (LockingFeature
->Locked
) {
110 AvalDiskActions
->Unlock
= 1;
112 AvalDiskActions
->Unlock
= 0;
116 // Only allow user to set password if an admin password exists
118 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
119 AvalDiskActions
->UserPass
= ExistingPassword
;
122 // This will still show up even if there isn't a user, which is fine
124 AvalDiskActions
->DisableUser
= ExistingPassword
;
126 return TcgResultSuccess
;
130 Enable Opal Feature for the input device.
132 @param[in] Session The opal session for the opal device.
134 @param[in] MsidLength Msid Length
135 @param[in] Password Admin password
136 @param[in] PassLength Length of password in bytes
141 OpalSupportEnableOpalFeature (
142 IN OPAL_SESSION
*Session
,
144 IN UINT32 MsidLength
,
153 NULL_CHECK(Password
);
155 Ret
= OpalUtilSetAdminPasswordAsSid(
162 if (Ret
== TcgResultSuccess
) {
164 // Enable global locking range
166 Ret
= OpalUtilSetOpalLockingRange(
170 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
184 Update password for the Opal disk.
186 @param[in, out] OpalDisk The disk to update password.
187 @param[in] Password The input password.
188 @param[in] PasswordLength The input password length.
192 OpalSupportUpdatePassword (
193 IN OUT OPAL_DISK
*OpalDisk
,
195 IN UINT32 PasswordLength
198 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
199 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
203 Extract device info from the device path.
205 @param[in] DevicePath Device path info for the device.
206 @param[out] DevInfoLength Device information length needed.
207 @param[out] DevInfo Device information extracted.
211 ExtractDeviceInfoFromDevicePath (
212 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
213 OUT UINT32
*DevInfoLength
,
214 OUT OPAL_DEVICE_LOCKBOX_DATA
*DevInfo OPTIONAL
217 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
218 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
219 PCI_DEVICE_PATH
*PciDevPath
;
222 OPAL_PCI_DEVICE
*PciDevice
;
224 ASSERT (DevicePath
!= NULL
);
225 ASSERT (DevInfoLength
!= NULL
);
227 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
230 TmpDevPath
= DevicePath
;
235 while (!IsDevicePathEnd (TmpDevPath
)) {
236 if ((TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
) &&
237 (TmpDevPath
->SubType
== MSG_SATA_DP
|| TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
238 if (DevInfo
!= NULL
) {
239 DevInfo
->DevicePathLength
= (UINT32
) GetDevicePathSize (DevicePath
);
240 CopyMem (DevInfo
->DevicePath
, DevicePath
, DevInfo
->DevicePathLength
);
243 DeviceType
= (TmpDevPath
->SubType
== MSG_SATA_DP
) ? OPAL_DEVICE_TYPE_ATA
: OPAL_DEVICE_TYPE_NVME
;
244 *DevInfoLength
= sizeof (OPAL_DEVICE_LOCKBOX_DATA
) + (UINT32
) GetDevicePathSize (DevicePath
);
247 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
254 TmpDevPath
= DevicePath
;
255 TmpDevPath2
= NextDevicePathNode (DevicePath
);
256 while (!IsDevicePathEnd (TmpDevPath2
)) {
257 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
258 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
259 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
) &&
260 (TmpDevPath2
->SubType
== MSG_SATA_DP
|| TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
261 if (DevInfo
!= NULL
) {
262 PciDevice
= &DevInfo
->Device
;
263 PciDevice
->Segment
= 0;
264 PciDevice
->Bus
= BusNum
;
265 PciDevice
->Device
= PciDevPath
->Device
;
266 PciDevice
->Function
= PciDevPath
->Function
;
269 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
270 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
275 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
276 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
279 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
284 Build OPAL device info and save them to LockBox.
288 BuildOpalDeviceInfo (
293 OPAL_DEVICE_LOCKBOX_DATA
*DevInfo
;
294 OPAL_DEVICE_LOCKBOX_DATA
*TempDevInfo
;
295 UINTN TotalDevInfoLength
;
296 UINT32 DevInfoLength
;
297 OPAL_DRIVER_DEVICE
*TmpDev
;
299 BOOLEAN S3InitDevicesExist
;
300 UINTN S3InitDevicesLength
;
301 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
302 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevicesBak
;
305 // Build OPAL device info and save them to LockBox.
307 TotalDevInfoLength
= 0;
308 TmpDev
= mOpalDriver
.DeviceList
;
309 while (TmpDev
!= NULL
) {
310 ExtractDeviceInfoFromDevicePath (
311 TmpDev
->OpalDisk
.OpalDevicePath
,
315 TotalDevInfoLength
+= DevInfoLength
;
316 TmpDev
= TmpDev
->Next
;
319 if (TotalDevInfoLength
== 0) {
323 S3InitDevicesLength
= sizeof (DummyData
);
324 Status
= RestoreLockBox (
325 &gS3StorageDeviceInitListGuid
,
329 ASSERT ((Status
== EFI_NOT_FOUND
) || (Status
== EFI_BUFFER_TOO_SMALL
));
330 if (Status
== EFI_NOT_FOUND
) {
331 S3InitDevices
= NULL
;
332 S3InitDevicesExist
= FALSE
;
333 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
334 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
335 ASSERT (S3InitDevices
!= NULL
);
336 if (S3InitDevices
== NULL
) {
340 Status
= RestoreLockBox (
341 &gS3StorageDeviceInitListGuid
,
345 ASSERT_EFI_ERROR (Status
);
346 S3InitDevicesExist
= TRUE
;
351 DevInfo
= AllocateZeroPool (TotalDevInfoLength
);
352 ASSERT (DevInfo
!= NULL
);
353 if (DevInfo
== NULL
) {
357 TempDevInfo
= DevInfo
;
358 TmpDev
= mOpalDriver
.DeviceList
;
359 while (TmpDev
!= NULL
) {
360 ExtractDeviceInfoFromDevicePath (
361 TmpDev
->OpalDisk
.OpalDevicePath
,
365 TempDevInfo
->Length
= DevInfoLength
;
366 TempDevInfo
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
368 TempDevInfo
->Password
,
369 TmpDev
->OpalDisk
.Password
,
370 TmpDev
->OpalDisk
.PasswordLength
372 TempDevInfo
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
374 S3InitDevicesBak
= S3InitDevices
;
375 S3InitDevices
= AppendDevicePathInstance (
377 TmpDev
->OpalDisk
.OpalDevicePath
379 if (S3InitDevicesBak
!= NULL
) {
380 FreePool (S3InitDevicesBak
);
382 ASSERT (S3InitDevices
!= NULL
);
383 if (S3InitDevices
== NULL
) {
387 TempDevInfo
= (OPAL_DEVICE_LOCKBOX_DATA
*) ((UINTN
) TempDevInfo
+ DevInfoLength
);
388 TmpDev
= TmpDev
->Next
;
391 Status
= SaveLockBox (
392 &mOpalDeviceLockBoxGuid
,
396 ASSERT_EFI_ERROR (Status
);
398 Status
= SetLockBoxAttributes (
399 &mOpalDeviceLockBoxGuid
,
400 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
402 ASSERT_EFI_ERROR (Status
);
404 S3InitDevicesLength
= GetDevicePathSize (S3InitDevices
);
405 if (S3InitDevicesExist
) {
406 Status
= UpdateLockBox (
407 &gS3StorageDeviceInitListGuid
,
412 ASSERT_EFI_ERROR (Status
);
414 Status
= SaveLockBox (
415 &gS3StorageDeviceInitListGuid
,
419 ASSERT_EFI_ERROR (Status
);
421 Status
= SetLockBoxAttributes (
422 &gS3StorageDeviceInitListGuid
,
423 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
425 ASSERT_EFI_ERROR (Status
);
428 ZeroMem (DevInfo
, TotalDevInfoLength
);
430 FreePool (S3InitDevices
);
434 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
436 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
438 @param Event Event whose notification function is being invoked.
439 @param Context Pointer to the notification function's context.
444 OpalEndOfDxeEventNotify (
449 OPAL_DRIVER_DEVICE
*TmpDev
;
451 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
453 mOpalEndOfDxe
= TRUE
;
455 if (mOpalRequestVariable
!= NULL
) {
457 // Free the OPAL request variable buffer here
458 // as the OPAL requests should have been processed.
460 FreePool (mOpalRequestVariable
);
461 mOpalRequestVariable
= NULL
;
462 mOpalRequestVariableSize
= 0;
466 // If no any device, return directly.
468 if (mOpalDriver
.DeviceList
== NULL
) {
469 gBS
->CloseEvent (Event
);
473 BuildOpalDeviceInfo ();
478 TmpDev
= mOpalDriver
.DeviceList
;
479 while (TmpDev
!= NULL
) {
480 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
481 TmpDev
= TmpDev
->Next
;
484 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
486 gBS
->CloseEvent (Event
);
490 Get Psid input from the popup window.
492 @param[in] Dev The device which need Psid to process Psid Revert
494 @param[in] PopUpString Pop up string.
495 @param[in] PopUpString2 Pop up string in line 2.
497 @param[out] PressEsc Whether user escape function through Press ESC.
499 @retval Psid string if success. NULL if failed.
503 OpalDriverPopUpPsidInput (
504 IN OPAL_DRIVER_DEVICE
*Dev
,
505 IN CHAR16
*PopUpString
,
506 IN CHAR16
*PopUpString2
,
507 OUT BOOLEAN
*PressEsc
510 EFI_INPUT_KEY InputKey
;
512 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
513 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
516 ZeroMem(Unicode
, sizeof(Unicode
));
517 ZeroMem(Mask
, sizeof(Mask
));
521 gST
->ConOut
->ClearScreen(gST
->ConOut
);
525 Mask
[InputLength
] = L
'_';
526 if (PopUpString2
== NULL
) {
528 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
531 L
"---------------------",
537 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
541 L
"---------------------",
550 if (InputKey
.ScanCode
== SCAN_NULL
) {
554 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
556 // Add the null terminator.
558 Unicode
[InputLength
] = 0;
559 Mask
[InputLength
] = 0;
561 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
562 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
563 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
568 // delete last key entered
570 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
571 if (InputLength
> 0) {
572 Unicode
[InputLength
] = 0;
573 Mask
[InputLength
] = 0;
578 // add Next key entry
580 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
581 Mask
[InputLength
] = InputKey
.UnicodeChar
;
583 if (InputLength
== PSID_CHARACTER_LENGTH
) {
585 // Add the null terminator.
587 Unicode
[InputLength
] = 0;
588 Mask
[InputLength
] = 0;
598 if (InputKey
.ScanCode
== SCAN_ESC
) {
604 gST
->ConOut
->ClearScreen(gST
->ConOut
);
606 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
607 ZeroMem (Unicode
, sizeof (Unicode
));
608 ZeroMem (Mask
, sizeof (Mask
));
612 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
614 ZeroMem (Unicode
, sizeof (Unicode
));
615 ZeroMem (Mask
, sizeof (Mask
));
619 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
620 ZeroMem (Unicode
, sizeof (Unicode
));
621 ZeroMem (Mask
, sizeof (Mask
));
628 Get password input from the popup window.
630 @param[in] Dev The device which need password to unlock or
631 process OPAL request.
632 @param[in] PopUpString1 Pop up string 1.
633 @param[in] PopUpString2 Pop up string 2.
634 @param[out] PressEsc Whether user escape function through Press ESC.
636 @retval Password string if success. NULL if failed.
640 OpalDriverPopUpPasswordInput (
641 IN OPAL_DRIVER_DEVICE
*Dev
,
642 IN CHAR16
*PopUpString1
,
643 IN CHAR16
*PopUpString2
,
644 OUT BOOLEAN
*PressEsc
647 EFI_INPUT_KEY InputKey
;
649 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
650 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
653 ZeroMem(Unicode
, sizeof(Unicode
));
654 ZeroMem(Mask
, sizeof(Mask
));
658 gST
->ConOut
->ClearScreen(gST
->ConOut
);
662 Mask
[InputLength
] = L
'_';
663 if (PopUpString2
== NULL
) {
665 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
668 L
"---------------------",
674 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
678 L
"---------------------",
687 if (InputKey
.ScanCode
== SCAN_NULL
) {
691 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
693 // Add the null terminator.
695 Unicode
[InputLength
] = 0;
696 Mask
[InputLength
] = 0;
698 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
699 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
700 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
705 // delete last key entered
707 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
708 if (InputLength
> 0) {
709 Unicode
[InputLength
] = 0;
710 Mask
[InputLength
] = 0;
715 // add Next key entry
717 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
718 Mask
[InputLength
] = L
'*';
720 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
722 // Add the null terminator.
724 Unicode
[InputLength
] = 0;
725 Mask
[InputLength
] = 0;
735 if (InputKey
.ScanCode
== SCAN_ESC
) {
741 gST
->ConOut
->ClearScreen(gST
->ConOut
);
743 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
744 ZeroMem (Unicode
, sizeof (Unicode
));
748 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
750 ZeroMem (Unicode
, sizeof (Unicode
));
754 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
755 ZeroMem (Unicode
, sizeof (Unicode
));
763 @param[in] Dev The OPAL device.
764 @param[in] RequestString Request string.
766 @return Pop up string.
771 IN OPAL_DRIVER_DEVICE
*Dev
,
772 IN CHAR16
*RequestString
775 if (Dev
->Name16
== NULL
) {
776 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
778 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
785 Check if disk is locked, show popup window and ask for password if it is.
787 @param[in] Dev The device which need to be unlocked.
788 @param[in] RequestString Request string.
792 OpalDriverRequestPassword (
793 IN OPAL_DRIVER_DEVICE
*Dev
,
794 IN CHAR16
*RequestString
802 OPAL_SESSION Session
;
812 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
814 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
818 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
820 ZeroMem(&Session
, sizeof(Session
));
821 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
822 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
823 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
825 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
827 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
831 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
832 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
836 // Current device in the lock status and
837 // User not input password and press ESC,
838 // keep device in lock status and continue boot.
842 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
844 L
"Press ENTER to skip the request and continue boot,",
845 L
"Press ESC to input password again",
848 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
850 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
851 gST
->ConOut
->ClearScreen(gST
->ConOut
);
853 // Keep lock and continue boot.
858 // Let user input password again.
864 // Current device in the unlock status and
865 // User not input password and press ESC,
866 // Shutdown the device.
870 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
872 L
"Press ENTER to shutdown, Press ESC to input password again",
875 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
877 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
878 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
881 // Let user input password again.
888 if (Password
== NULL
) {
892 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
895 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
897 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
898 if (Ret
== TcgResultSuccess
) {
899 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
903 if (Ret
== TcgResultSuccess
) {
904 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
905 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
907 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
910 if (Password
!= NULL
) {
911 ZeroMem (Password
, PasswordLen
);
915 if (Ret
== TcgResultSuccess
) {
920 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
921 // before accept new password.
923 if (Ret
== TcgResultFailureInvalidType
) {
924 Count
= MAX_PASSWORD_TRY_COUNT
;
932 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
934 L
"Invalid password.",
935 L
"Press ENTER to retry",
938 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
941 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
944 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
946 L
"Opal password retry count exceeds the limit. Must shutdown!",
947 L
"Press ENTER to shutdown",
950 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
952 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
958 Process Enable Feature OPAL request.
960 @param[in] Dev The device which has Enable Feature OPAL request.
961 @param[in] RequestString Request string.
965 ProcessOpalRequestEnableFeature (
966 IN OPAL_DRIVER_DEVICE
*Dev
,
967 IN CHAR16
*RequestString
973 CHAR8
*PasswordConfirm
;
974 UINT32 PasswordLenConfirm
;
975 OPAL_SESSION Session
;
985 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
987 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
991 ZeroMem(&Session
, sizeof(Session
));
992 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
993 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
994 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
996 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
997 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1001 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1003 L
"Press ENTER to skip the request and continue boot,",
1004 L
"Press ESC to input password again",
1007 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1009 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1010 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1014 // Let user input password again.
1020 if (Password
== NULL
) {
1024 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1026 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1027 if (PasswordConfirm
== NULL
) {
1028 ZeroMem (Password
, PasswordLen
);
1029 FreePool (Password
);
1033 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1034 if ((PasswordLen
!= PasswordLenConfirm
) ||
1035 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1036 ZeroMem (Password
, PasswordLen
);
1037 FreePool (Password
);
1038 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1039 FreePool (PasswordConfirm
);
1042 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1044 L
"Passwords are not the same.",
1045 L
"Press ENTER to retry",
1048 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1053 if (PasswordConfirm
!= NULL
) {
1054 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1055 FreePool (PasswordConfirm
);
1058 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1059 if (Ret
== TcgResultSuccess
) {
1060 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1061 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1063 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1066 if (Password
!= NULL
) {
1067 ZeroMem (Password
, PasswordLen
);
1068 FreePool (Password
);
1071 if (Ret
== TcgResultSuccess
) {
1079 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1082 L
"Press ENTER to retry",
1085 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1088 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1091 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1093 L
"Opal password retry count exceeds the limit.",
1094 L
"Press ENTER to skip the request and continue boot",
1097 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1098 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1103 Process Disable User OPAL request.
1105 @param[in] Dev The device which has Disable User OPAL request.
1106 @param[in] RequestString Request string.
1110 ProcessOpalRequestDisableUser (
1111 IN OPAL_DRIVER_DEVICE
*Dev
,
1112 IN CHAR16
*RequestString
1118 OPAL_SESSION Session
;
1122 BOOLEAN PasswordFailed
;
1123 CHAR16
*PopUpString
;
1129 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1131 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1135 ZeroMem(&Session
, sizeof(Session
));
1136 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1137 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1138 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1140 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1141 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1145 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1147 L
"Press ENTER to skip the request and continue boot,",
1148 L
"Press ESC to input password again",
1151 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1153 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1154 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1158 // Let user input password again.
1164 if (Password
== NULL
) {
1168 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1170 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1171 if (Ret
== TcgResultSuccess
) {
1172 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1173 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1175 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1178 if (Password
!= NULL
) {
1179 ZeroMem (Password
, PasswordLen
);
1180 FreePool (Password
);
1183 if (Ret
== TcgResultSuccess
) {
1191 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1193 L
"Invalid password, request failed.",
1194 L
"Press ENTER to retry",
1197 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1200 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1203 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1205 L
"Opal password retry count exceeds the limit.",
1206 L
"Press ENTER to skip the request and continue boot",
1209 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1210 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1215 Process Psid Revert OPAL request.
1217 @param[in] Dev The device which has Psid Revert OPAL request.
1218 @param[in] RequestString Request string.
1222 ProcessOpalRequestPsidRevert (
1223 IN OPAL_DRIVER_DEVICE
*Dev
,
1224 IN CHAR16
*RequestString
1230 OPAL_SESSION Session
;
1234 CHAR16
*PopUpString
;
1235 CHAR16
*PopUpString2
;
1242 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1244 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1246 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1247 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1248 PopUpString2
= AllocateZeroPool (BufferSize
);
1249 ASSERT (PopUpString2
!= NULL
);
1253 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1254 Dev
->OpalDisk
.EstimateTimeCost
1257 PopUpString2
= NULL
;
1262 ZeroMem(&Session
, sizeof(Session
));
1263 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1264 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1265 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1267 while (Count
< MAX_PSID_TRY_COUNT
) {
1268 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1272 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1274 L
"Press ENTER to skip the request and continue boot,",
1275 L
"Press ESC to input Psid again",
1278 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1280 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1281 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1285 // Let user input Psid again.
1295 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1297 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1298 if (Ret
== TcgResultSuccess
) {
1299 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1301 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1305 ZeroMem (Psid
, PsidLen
);
1309 if (Ret
== TcgResultSuccess
) {
1317 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1319 L
"Invalid Psid, request failed.",
1320 L
"Press ENTER to retry",
1323 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1326 if (Count
>= MAX_PSID_TRY_COUNT
) {
1329 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1331 L
"Opal Psid retry count exceeds the limit.",
1332 L
"Press ENTER to skip the request and continue boot",
1335 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1336 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1340 if (PopUpString2
!= NULL
) {
1341 FreePool (PopUpString2
);
1346 Process Admin Revert OPAL request.
1348 @param[in] Dev The device which has Revert OPAL request.
1349 @param[in] KeepUserData Whether to keep user data or not.
1350 @param[in] RequestString Request string.
1354 ProcessOpalRequestRevert (
1355 IN OPAL_DRIVER_DEVICE
*Dev
,
1356 IN BOOLEAN KeepUserData
,
1357 IN CHAR16
*RequestString
1363 OPAL_SESSION Session
;
1367 BOOLEAN PasswordFailed
;
1368 CHAR16
*PopUpString
;
1369 CHAR16
*PopUpString2
;
1376 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1378 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1380 if ((!KeepUserData
) &&
1381 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1382 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1383 PopUpString2
= AllocateZeroPool (BufferSize
);
1384 ASSERT (PopUpString2
!= NULL
);
1388 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1389 Dev
->OpalDisk
.EstimateTimeCost
1392 PopUpString2
= NULL
;
1397 ZeroMem(&Session
, sizeof(Session
));
1398 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1399 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1400 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1402 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1403 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1407 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1409 L
"Press ENTER to skip the request and continue boot,",
1410 L
"Press ESC to input password again",
1413 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1415 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1416 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1420 // Let user input password again.
1426 if (Password
== NULL
) {
1430 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1432 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1433 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1435 // For pyrite type device which does not support media encryption,
1436 // it does not accept "Keep User Data" parameter.
1437 // So here hardcode a FALSE for this case.
1439 Ret
= OpalUtilRevert(
1446 Dev
->OpalDisk
.MsidLength
1449 Ret
= OpalUtilRevert(
1456 Dev
->OpalDisk
.MsidLength
1459 if (Ret
== TcgResultSuccess
) {
1460 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1461 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1463 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1466 if (Password
!= NULL
) {
1467 ZeroMem (Password
, PasswordLen
);
1468 FreePool (Password
);
1471 if (Ret
== TcgResultSuccess
) {
1479 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1481 L
"Invalid password, request failed.",
1482 L
"Press ENTER to retry",
1485 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1488 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1491 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1493 L
"Opal password retry count exceeds the limit.",
1494 L
"Press ENTER to skip the request and continue boot",
1497 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1498 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1502 if (PopUpString2
!= NULL
) {
1503 FreePool (PopUpString2
);
1508 Process Secure Erase OPAL request.
1510 @param[in] Dev The device which has Secure Erase OPAL request.
1511 @param[in] RequestString Request string.
1515 ProcessOpalRequestSecureErase (
1516 IN OPAL_DRIVER_DEVICE
*Dev
,
1517 IN CHAR16
*RequestString
1523 OPAL_SESSION Session
;
1527 BOOLEAN PasswordFailed
;
1528 CHAR16
*PopUpString
;
1534 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1536 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1540 ZeroMem(&Session
, sizeof(Session
));
1541 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1542 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1543 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1545 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1546 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1550 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1552 L
"Press ENTER to skip the request and continue boot,",
1553 L
"Press ESC to input password again",
1556 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1558 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1559 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1563 // Let user input password again.
1569 if (Password
== NULL
) {
1573 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1575 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1576 if (Ret
== TcgResultSuccess
) {
1577 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1578 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1580 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1583 if (Password
!= NULL
) {
1584 ZeroMem (Password
, PasswordLen
);
1585 FreePool (Password
);
1588 if (Ret
== TcgResultSuccess
) {
1596 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1598 L
"Invalid password, request failed.",
1599 L
"Press ENTER to retry",
1602 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1605 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1608 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1610 L
"Opal password retry count exceeds the limit.",
1611 L
"Press ENTER to skip the request and continue boot",
1614 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1615 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1620 Process Set Admin Pwd OPAL request.
1622 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1623 @param[in] RequestString Request string.
1627 ProcessOpalRequestSetUserPwd (
1628 IN OPAL_DRIVER_DEVICE
*Dev
,
1629 IN CHAR16
*RequestString
1634 UINT32 OldPasswordLen
;
1637 CHAR8
*PasswordConfirm
;
1638 UINT32 PasswordLenConfirm
;
1639 OPAL_SESSION Session
;
1643 CHAR16
*PopUpString
;
1649 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1651 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1655 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1656 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1660 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1662 L
"Press ENTER to skip the request and continue boot,",
1663 L
"Press ESC to input password again",
1666 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1668 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1669 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1673 // Let user input password again.
1679 if (OldPassword
== NULL
) {
1683 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1685 ZeroMem(&Session
, sizeof(Session
));
1686 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1687 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1688 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1689 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1690 if (Ret
== TcgResultSuccess
) {
1691 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1693 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1694 if (Ret
== TcgResultSuccess
) {
1695 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1697 ZeroMem (OldPassword
, OldPasswordLen
);
1698 FreePool (OldPassword
);
1699 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1702 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1704 L
"Incorrect password.",
1705 L
"Press ENTER to retry",
1708 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1714 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1715 if (Password
== NULL
) {
1716 ZeroMem (OldPassword
, OldPasswordLen
);
1717 FreePool (OldPassword
);
1721 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1723 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1724 if (PasswordConfirm
== NULL
) {
1725 ZeroMem (OldPassword
, OldPasswordLen
);
1726 FreePool (OldPassword
);
1727 ZeroMem (Password
, PasswordLen
);
1728 FreePool (Password
);
1732 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1733 if ((PasswordLen
!= PasswordLenConfirm
) ||
1734 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1735 ZeroMem (OldPassword
, OldPasswordLen
);
1736 FreePool (OldPassword
);
1737 ZeroMem (Password
, PasswordLen
);
1738 FreePool (Password
);
1739 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1740 FreePool (PasswordConfirm
);
1743 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1745 L
"Passwords are not the same.",
1746 L
"Press ENTER to retry",
1749 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1754 if (PasswordConfirm
!= NULL
) {
1755 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1756 FreePool (PasswordConfirm
);
1759 ZeroMem(&Session
, sizeof(Session
));
1760 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1761 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1762 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1763 Ret
= OpalUtilSetUserPassword(
1770 if (Ret
== TcgResultSuccess
) {
1771 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1772 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1774 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1777 if (OldPassword
!= NULL
) {
1778 ZeroMem (OldPassword
, OldPasswordLen
);
1779 FreePool (OldPassword
);
1782 if (Password
!= NULL
) {
1783 ZeroMem (Password
, PasswordLen
);
1784 FreePool (Password
);
1787 if (Ret
== TcgResultSuccess
) {
1795 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1798 L
"Press ENTER to retry",
1801 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1804 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1807 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1809 L
"Opal password retry count exceeds the limit.",
1810 L
"Press ENTER to skip the request and continue boot",
1813 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1814 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1819 Process Set Admin Pwd OPAL request.
1821 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1822 @param[in] RequestString Request string.
1826 ProcessOpalRequestSetAdminPwd (
1827 IN OPAL_DRIVER_DEVICE
*Dev
,
1828 IN CHAR16
*RequestString
1833 UINT32 OldPasswordLen
;
1836 CHAR8
*PasswordConfirm
;
1837 UINT32 PasswordLenConfirm
;
1838 OPAL_SESSION Session
;
1842 CHAR16
*PopUpString
;
1848 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1850 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1854 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1855 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1859 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1861 L
"Press ENTER to skip the request and continue boot,",
1862 L
"Press ESC to input password again",
1865 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1867 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1868 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1872 // Let user input password again.
1878 if (OldPassword
== NULL
) {
1882 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1884 ZeroMem(&Session
, sizeof(Session
));
1885 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1886 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1887 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1888 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1889 if (Ret
== TcgResultSuccess
) {
1890 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1892 ZeroMem (OldPassword
, OldPasswordLen
);
1893 FreePool (OldPassword
);
1894 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1897 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1899 L
"Incorrect password.",
1900 L
"Press ENTER to retry",
1903 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1908 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1909 if (Password
== NULL
) {
1910 ZeroMem (OldPassword
, OldPasswordLen
);
1911 FreePool (OldPassword
);
1915 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1917 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1918 if (PasswordConfirm
== NULL
) {
1919 ZeroMem (OldPassword
, OldPasswordLen
);
1920 FreePool (OldPassword
);
1921 ZeroMem (Password
, PasswordLen
);
1922 FreePool (Password
);
1926 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1927 if ((PasswordLen
!= PasswordLenConfirm
) ||
1928 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1929 ZeroMem (OldPassword
, OldPasswordLen
);
1930 FreePool (OldPassword
);
1931 ZeroMem (Password
, PasswordLen
);
1932 FreePool (Password
);
1933 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1934 FreePool (PasswordConfirm
);
1937 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1939 L
"Passwords are not the same.",
1940 L
"Press ENTER to retry",
1943 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1948 if (PasswordConfirm
!= NULL
) {
1949 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1950 FreePool (PasswordConfirm
);
1954 ZeroMem(&Session
, sizeof(Session
));
1955 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1956 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1957 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1958 Ret
= OpalUtilSetAdminPassword(
1965 if (Ret
== TcgResultSuccess
) {
1966 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1967 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1969 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1972 if (OldPassword
!= NULL
) {
1973 ZeroMem (OldPassword
, OldPasswordLen
);
1974 FreePool (OldPassword
);
1977 if (Password
!= NULL
) {
1978 ZeroMem (Password
, PasswordLen
);
1979 FreePool (Password
);
1982 if (Ret
== TcgResultSuccess
) {
1990 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1993 L
"Press ENTER to retry",
1996 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1999 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2002 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2004 L
"Opal password retry count exceeds the limit.",
2005 L
"Press ENTER to skip the request and continue boot",
2008 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2009 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2014 Process OPAL request.
2016 @param[in] Dev The device which has OPAL request.
2020 ProcessOpalRequest (
2021 IN OPAL_DRIVER_DEVICE
*Dev
2025 OPAL_REQUEST_VARIABLE
*TempVariable
;
2026 OPAL_REQUEST_VARIABLE
*Variable
;
2028 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2029 UINTN DevicePathSizeInVariable
;
2030 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2031 UINTN DevicePathSize
;
2032 BOOLEAN KeepUserData
;
2034 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2036 if (mOpalRequestVariable
== NULL
) {
2037 Status
= GetVariable2 (
2038 OPAL_REQUEST_VARIABLE_NAME
,
2039 &gHiiSetupVariableGuid
,
2040 (VOID
**) &Variable
,
2043 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2046 mOpalRequestVariable
= Variable
;
2047 mOpalRequestVariableSize
= VariableSize
;
2050 // Delete the OPAL request variable.
2052 Status
= gRT
->SetVariable (
2053 OPAL_REQUEST_VARIABLE_NAME
,
2054 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2059 ASSERT_EFI_ERROR (Status
);
2061 Variable
= mOpalRequestVariable
;
2062 VariableSize
= mOpalRequestVariableSize
;
2066 // Process the OPAL requests.
2068 TempVariable
= Variable
;
2069 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2070 (VariableSize
>= TempVariable
->Length
) &&
2071 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2072 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2073 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2074 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2075 DevicePathSize
= GetDevicePathSize (DevicePath
);
2076 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2077 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2079 // Found the node for the OPAL device.
2081 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2082 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2084 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2085 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2087 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2088 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2090 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2091 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2092 ProcessOpalRequestRevert (
2095 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2098 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2099 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2101 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2102 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2104 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2105 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2111 VariableSize
-= TempVariable
->Length
;
2112 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2115 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2119 Add new device to the global device list.
2121 @param Dev New create device.
2126 IN OPAL_DRIVER_DEVICE
*Dev
2129 OPAL_DRIVER_DEVICE
*TmpDev
;
2131 if (mOpalDriver
.DeviceList
== NULL
) {
2132 mOpalDriver
.DeviceList
= Dev
;
2134 TmpDev
= mOpalDriver
.DeviceList
;
2135 while (TmpDev
->Next
!= NULL
) {
2136 TmpDev
= TmpDev
->Next
;
2144 Remove one device in the global device list.
2146 @param Dev The device need to be removed.
2151 IN OPAL_DRIVER_DEVICE
*Dev
2154 OPAL_DRIVER_DEVICE
*TmpDev
;
2156 if (mOpalDriver
.DeviceList
== NULL
) {
2160 if (mOpalDriver
.DeviceList
== Dev
) {
2161 mOpalDriver
.DeviceList
= NULL
;
2165 TmpDev
= mOpalDriver
.DeviceList
;
2166 while (TmpDev
->Next
!= NULL
) {
2167 if (TmpDev
->Next
== Dev
) {
2168 TmpDev
->Next
= Dev
->Next
;
2175 Get current device count.
2177 @retval return the current created device count.
2186 OPAL_DRIVER_DEVICE
*TmpDev
;
2189 TmpDev
= mOpalDriver
.DeviceList
;
2191 while (TmpDev
!= NULL
) {
2193 TmpDev
= TmpDev
->Next
;
2200 Get devcie list info.
2202 @retval return the device list pointer.
2205 OpalDriverGetDeviceList(
2209 return mOpalDriver
.DeviceList
;
2213 ReadyToBoot callback to send BlockSid command.
2215 @param Event Pointer to this event
2216 @param Context Event handler private Data
2221 ReadyToBootCallback (
2226 OPAL_DRIVER_DEVICE
*Itr
;
2228 OPAL_SESSION Session
;
2229 UINT32 PpStorageFlag
;
2231 gBS
->CloseEvent (Event
);
2233 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2234 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2236 // Send BlockSID command to each Opal disk
2238 Itr
= mOpalDriver
.DeviceList
;
2239 while (Itr
!= NULL
) {
2240 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2241 ZeroMem(&Session
, sizeof(Session
));
2242 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2243 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2244 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2246 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2247 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2248 if (Result
!= TcgResultSuccess
) {
2249 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2260 Stop this Controller.
2262 @param Dev The device need to be stopped.
2266 OpalDriverStopDevice (
2267 OPAL_DRIVER_DEVICE
*Dev
2273 FreePool(Dev
->Name16
);
2276 // remove OPAL_DRIVER_DEVICE from the list
2277 // it updates the controllerList pointer
2282 // close protocols that were opened
2286 &gEfiStorageSecurityCommandProtocolGuid
,
2287 gOpalDriverBinding
.DriverBindingHandle
,
2293 &gEfiBlockIoProtocolGuid
,
2294 gOpalDriverBinding
.DriverBindingHandle
,
2302 Get devcie name through the component name protocol.
2304 @param[in] AllHandlesBuffer The handle buffer for current system.
2305 @param[in] NumAllHandles The number of handles for the handle buffer.
2306 @param[in] Dev The device which need to get name.
2307 @param[in] UseComp1 Whether use component name or name2 protocol.
2309 @retval TRUE Find the name for this device.
2310 @retval FALSE Not found the name for this device.
2313 OpalDriverGetDeviceNameByProtocol(
2314 EFI_HANDLE
*AllHandlesBuffer
,
2315 UINTN NumAllHandles
,
2316 OPAL_DRIVER_DEVICE
*Dev
,
2320 EFI_HANDLE
* ProtocolHandlesBuffer
;
2321 UINTN NumProtocolHandles
;
2323 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2326 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2329 EFI_HANDLE TmpHandle
;
2332 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2336 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2339 // Find all EFI_HANDLES with protocol
2341 Status
= gBS
->LocateHandleBuffer(
2345 &NumProtocolHandles
,
2346 &ProtocolHandlesBuffer
2348 if (EFI_ERROR(Status
)) {
2354 // Exit early if no supported devices
2356 if (NumProtocolHandles
== 0) {
2361 // Get printable name by iterating through all protocols
2362 // using the handle as the child, and iterate through all handles for the controller
2363 // exit loop early once found, if not found, then delete device
2364 // storage security protocol instances already exist, add them to internal list
2366 Status
= EFI_DEVICE_ERROR
;
2367 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2370 if (Dev
->Name16
!= NULL
) {
2374 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2376 Status
= gBS
->OpenProtocol(
2382 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2384 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2389 // Use all handles array as controller handle
2391 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2392 Status
= Cnp1_2
->GetControllerName(
2394 AllHandlesBuffer
[Index2
],
2396 LANGUAGE_ISO_639_2_ENGLISH
,
2399 if (EFI_ERROR(Status
)) {
2400 Status
= Cnp1_2
->GetControllerName(
2402 AllHandlesBuffer
[Index2
],
2404 LANGUAGE_RFC_3066_ENGLISH
,
2408 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2409 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2410 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2411 ASSERT (Dev
->Name16
!= NULL
);
2412 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2413 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2414 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2417 // Retrieve bridge BDF info and port number or namespace depending on type
2420 Status
= gBS
->OpenProtocol(
2422 &gEfiDevicePathProtocolGuid
,
2423 (VOID
**)&TmpDevPath
,
2426 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2428 if (!EFI_ERROR(Status
)) {
2429 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2433 if (Dev
->Name16
!= NULL
) {
2434 FreePool(Dev
->Name16
);
2437 if (Dev
->NameZ
!= NULL
) {
2438 FreePool(Dev
->NameZ
);
2449 Get devcie name through the component name protocol.
2451 @param[in] Dev The device which need to get name.
2453 @retval TRUE Find the name for this device.
2454 @retval FALSE Not found the name for this device.
2457 OpalDriverGetDriverDeviceName(
2458 OPAL_DRIVER_DEVICE
*Dev
2461 EFI_HANDLE
* AllHandlesBuffer
;
2462 UINTN NumAllHandles
;
2466 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2471 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2473 if (Dev
->Name16
== NULL
) {
2474 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2476 // Find all EFI_HANDLES
2478 Status
= gBS
->LocateHandleBuffer(
2485 if (EFI_ERROR(Status
)) {
2486 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2491 // Try component Name2
2493 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2494 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2495 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2496 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2506 Main entry for this driver.
2508 @param ImageHandle Image Handle this driver.
2509 @param SystemTable Pointer to SystemTable.
2511 @retval EFI_SUCESS This function always complete successfully.
2515 EfiDriverEntryPoint(
2516 IN EFI_HANDLE ImageHandle
,
2517 IN EFI_SYSTEM_TABLE
* SystemTable
2521 EFI_EVENT ReadyToBootEvent
;
2522 EFI_EVENT EndOfDxeEvent
;
2524 Status
= EfiLibInstallDriverBindingComponentName2 (
2527 &gOpalDriverBinding
,
2529 &gOpalComponentName
,
2530 &gOpalComponentName2
2533 if (EFI_ERROR(Status
)) {
2534 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2539 // Initialize Driver object
2541 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2542 mOpalDriver
.Handle
= ImageHandle
;
2544 Status
= gBS
->CreateEventEx (
2547 OpalEndOfDxeEventNotify
,
2549 &gEfiEndOfDxeEventGroupGuid
,
2552 ASSERT_EFI_ERROR (Status
);
2555 // register a ReadyToBoot event callback for sending BlockSid command
2557 Status
= EfiCreateEventReadyToBootEx (
2559 ReadyToBootCallback
,
2560 (VOID
*) &ImageHandle
,
2565 // Install Hii packages.
2573 Tests to see if this driver supports a given controller.
2575 This function checks to see if the controller contains an instance of the
2576 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2577 and returns EFI_SUCCESS if it does.
2579 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2580 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2581 must support a protocol interface that supplies
2582 an I/O abstraction to the driver.
2583 @param[in] RemainingDevicePath This parameter is ignored.
2585 @retval EFI_SUCCESS The device contains required protocols
2586 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2587 RemainingDevicePath is already being managed by the driver
2589 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2590 RemainingDevicePath is already being managed by a different
2591 driver or an application that requires exclusive access.
2592 Currently not implemented.
2593 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2598 OpalEfiDriverBindingSupported(
2599 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2600 IN EFI_HANDLE Controller
,
2601 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2605 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2606 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2608 if (mOpalEndOfDxe
) {
2609 return EFI_UNSUPPORTED
;
2613 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2615 Status
= gBS
->OpenProtocol(
2617 &gEfiStorageSecurityCommandProtocolGuid
,
2618 ( VOID
** )&SecurityCommand
,
2619 This
->DriverBindingHandle
,
2621 EFI_OPEN_PROTOCOL_BY_DRIVER
2624 if (Status
== EFI_ALREADY_STARTED
) {
2628 if (EFI_ERROR(Status
)) {
2633 // Close protocol and reopen in Start call
2637 &gEfiStorageSecurityCommandProtocolGuid
,
2638 This
->DriverBindingHandle
,
2643 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2646 Status
= gBS
->OpenProtocol(
2648 &gEfiBlockIoProtocolGuid
,
2650 This
->DriverBindingHandle
,
2652 EFI_OPEN_PROTOCOL_BY_DRIVER
2655 if (EFI_ERROR(Status
)) {
2656 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2661 // Close protocol and reopen in Start call
2665 &gEfiBlockIoProtocolGuid
,
2666 This
->DriverBindingHandle
,
2674 Enables Opal Management on a supported device if available.
2676 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2677 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2678 This function will complete the other necessary checks, such as verifying the device supports
2679 the correct version of Opal. Upon verification, it will add the device to the
2680 Opal HII list in order to expose Opal managmeent options.
2682 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2683 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2684 must support a protocol interface that supplies
2685 an I/O abstraction to the driver.
2686 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2687 parameter is ignored by device drivers, and is optional for bus
2688 drivers. For a bus driver, if this parameter is NULL, then handles
2689 for all the children of Controller are created by this driver.
2690 If this parameter is not NULL and the first Device Path Node is
2691 not the End of Device Path Node, then only the Handle for the
2692 child device specified by the first Device Path Node of
2693 RemainingDevicePath is created by this driver.
2694 If the first Device Path Node of RemainingDevicePath is
2695 the End of Device Path Node, no child Handle is created by this
2698 @retval EFI_SUCCESS Opal management was enabled.
2699 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2700 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2701 @retval Others The driver failed to start the device.
2706 OpalEfiDriverBindingStart(
2707 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2708 IN EFI_HANDLE Controller
,
2709 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2713 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2714 OPAL_DRIVER_DEVICE
*Dev
;
2715 OPAL_DRIVER_DEVICE
*Itr
;
2718 Itr
= mOpalDriver
.DeviceList
;
2719 while (Itr
!= NULL
) {
2720 if (Controller
== Itr
->Handle
) {
2727 // Create internal device for tracking. This allows all disks to be tracked
2730 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2732 return EFI_OUT_OF_RESOURCES
;
2734 Dev
->Handle
= Controller
;
2737 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2739 Status
= gBS
->OpenProtocol(
2741 &gEfiStorageSecurityCommandProtocolGuid
,
2742 (VOID
**)&Dev
->Sscp
,
2743 This
->DriverBindingHandle
,
2745 EFI_OPEN_PROTOCOL_BY_DRIVER
2747 if (EFI_ERROR(Status
)) {
2753 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2756 Status
= gBS
->OpenProtocol(
2758 &gEfiBlockIoProtocolGuid
,
2760 This
->DriverBindingHandle
,
2762 EFI_OPEN_PROTOCOL_BY_DRIVER
2764 if (EFI_ERROR(Status
)) {
2766 // Close storage security that was opened
2770 &gEfiStorageSecurityCommandProtocolGuid
,
2771 This
->DriverBindingHandle
,
2782 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2786 &gEfiBlockIoProtocolGuid
,
2787 This
->DriverBindingHandle
,
2792 // Acquire Ascii printable name of child, if not found, then ignore device
2794 Result
= OpalDriverGetDriverDeviceName (Dev
);
2799 Status
= OpalDiskInitialize (Dev
);
2800 if (EFI_ERROR (Status
)) {
2804 AddDeviceToTail(Dev
);
2807 // Check if device is locked and prompt for password.
2809 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2812 // Process OPAL request from last boot.
2814 ProcessOpalRequest (Dev
);
2820 // free device, close protocols and exit
2824 &gEfiStorageSecurityCommandProtocolGuid
,
2825 This
->DriverBindingHandle
,
2831 return EFI_DEVICE_ERROR
;
2835 Stop this driver on Controller.
2837 @param This Protocol instance pointer.
2838 @param Controller Handle of device to stop driver on
2839 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2840 children is zero stop the entire bus driver.
2841 @param ChildHandleBuffer List of Child Handles to Stop.
2843 @retval EFI_SUCCESS This driver is removed Controller.
2844 @retval other This driver could not be removed from this device.
2849 OpalEfiDriverBindingStop(
2850 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2851 EFI_HANDLE Controller
,
2852 UINTN NumberOfChildren
,
2853 EFI_HANDLE
* ChildHandleBuffer
2856 OPAL_DRIVER_DEVICE
* Itr
;
2858 Itr
= mOpalDriver
.DeviceList
;
2861 // does Controller match any of the devices we are managing for Opal
2863 while (Itr
!= NULL
) {
2864 if (Itr
->Handle
== Controller
) {
2865 OpalDriverStopDevice (Itr
);
2872 return EFI_NOT_FOUND
;
2877 Unloads UEFI Driver. Very useful for debugging and testing.
2879 @param ImageHandle Image Handle this driver.
2881 @retval EFI_SUCCESS This function always complete successfully.
2882 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2886 OpalEfiDriverUnload (
2887 IN EFI_HANDLE ImageHandle
2891 OPAL_DRIVER_DEVICE
*Itr
;
2893 Status
= EFI_SUCCESS
;
2895 if (ImageHandle
!= gImageHandle
) {
2896 return (EFI_INVALID_PARAMETER
);
2900 // Uninstall any interface added to each device by us
2902 while (mOpalDriver
.DeviceList
) {
2903 Itr
= mOpalDriver
.DeviceList
;
2905 // Remove OPAL_DRIVER_DEVICE from the list
2906 // it updates the controllerList pointer
2908 OpalDriverStopDevice(Itr
);
2912 // Uninstall the HII capability
2914 Status
= HiiUninstall();