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 SPDX-License-Identifier: BSD-2-Clause-Patent
10 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
11 // HII GUI to manage Opal features if the device is Opal capable
12 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
13 // window during boot requesting a user password
15 #include "OpalDriver.h"
18 EFI_GUID mOpalDeviceLockBoxGuid
= OPAL_DEVICE_LOCKBOX_GUID
;
20 BOOLEAN mOpalEndOfDxe
= FALSE
;
21 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
22 UINTN mOpalRequestVariableSize
= 0;
23 CHAR16 mPopUpString
[100];
25 OPAL_DRIVER mOpalDriver
;
30 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
31 OpalEfiDriverBindingSupported
,
32 OpalEfiDriverBindingStart
,
33 OpalEfiDriverBindingStop
,
41 The function determines the available actions for the OPAL_DISK provided.
43 @param[in] SupportedAttributes The supported attributes for the device.
44 @param[in] LockingFeature The locking status for the device.
45 @param[in] OwnerShip The ownership for the device.
46 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
51 OpalSupportGetAvailableActions(
52 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
53 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
55 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
58 BOOLEAN ExistingPassword
;
60 NULL_CHECK(AvalDiskActions
);
62 AvalDiskActions
->AdminPass
= 1;
63 AvalDiskActions
->UserPass
= 0;
64 AvalDiskActions
->DisableUser
= 0;
65 AvalDiskActions
->Unlock
= 0;
68 // Revert is performed on locking sp, so only allow if locking sp is enabled
70 if (LockingFeature
->LockingEnabled
) {
71 AvalDiskActions
->Revert
= 1;
75 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
77 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
80 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
81 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
82 // intact and accessible
84 AvalDiskActions
->PsidRevert
= 1;
85 AvalDiskActions
->RevertKeepDataForced
= 0;
88 // Secure erase is performed by generating a new encryption key
89 // this is only available if encryption is supported
91 AvalDiskActions
->SecureErase
= 1;
93 AvalDiskActions
->PsidRevert
= 0;
94 AvalDiskActions
->SecureErase
= 0;
97 // If no media encryption is supported, then a revert (using password) will not
98 // erase the Data (since you can't generate a new encryption key)
100 AvalDiskActions
->RevertKeepDataForced
= 1;
103 if (LockingFeature
->Locked
) {
104 AvalDiskActions
->Unlock
= 1;
106 AvalDiskActions
->Unlock
= 0;
110 // Only allow user to set password if an admin password exists
112 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
113 AvalDiskActions
->UserPass
= ExistingPassword
;
116 // This will still show up even if there isn't a user, which is fine
118 AvalDiskActions
->DisableUser
= ExistingPassword
;
120 return TcgResultSuccess
;
124 Enable Opal Feature for the input device.
126 @param[in] Session The opal session for the opal device.
128 @param[in] MsidLength Msid Length
129 @param[in] Password Admin password
130 @param[in] PassLength Length of password in bytes
135 OpalSupportEnableOpalFeature (
136 IN OPAL_SESSION
*Session
,
138 IN UINT32 MsidLength
,
147 NULL_CHECK(Password
);
149 Ret
= OpalUtilSetAdminPasswordAsSid(
156 if (Ret
== TcgResultSuccess
) {
158 // Enable global locking range
160 Ret
= OpalUtilSetOpalLockingRange(
164 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
178 Update password for the Opal disk.
180 @param[in, out] OpalDisk The disk to update password.
181 @param[in] Password The input password.
182 @param[in] PasswordLength The input password length.
186 OpalSupportUpdatePassword (
187 IN OUT OPAL_DISK
*OpalDisk
,
189 IN UINT32 PasswordLength
192 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
193 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
197 Extract device info from the device path.
199 @param[in] DevicePath Device path info for the device.
200 @param[out] DevInfoLength Device information length needed.
201 @param[out] DevInfo Device information extracted.
205 ExtractDeviceInfoFromDevicePath (
206 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
207 OUT UINT32
*DevInfoLength
,
208 OUT OPAL_DEVICE_LOCKBOX_DATA
*DevInfo OPTIONAL
211 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
212 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
213 PCI_DEVICE_PATH
*PciDevPath
;
216 OPAL_PCI_DEVICE
*PciDevice
;
218 ASSERT (DevicePath
!= NULL
);
219 ASSERT (DevInfoLength
!= NULL
);
221 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
224 TmpDevPath
= DevicePath
;
229 while (!IsDevicePathEnd (TmpDevPath
)) {
230 if ((TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
) &&
231 (TmpDevPath
->SubType
== MSG_SATA_DP
|| TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
232 if (DevInfo
!= NULL
) {
233 DevInfo
->DevicePathLength
= (UINT32
) GetDevicePathSize (DevicePath
);
234 CopyMem (DevInfo
->DevicePath
, DevicePath
, DevInfo
->DevicePathLength
);
237 DeviceType
= (TmpDevPath
->SubType
== MSG_SATA_DP
) ? OPAL_DEVICE_TYPE_ATA
: OPAL_DEVICE_TYPE_NVME
;
238 *DevInfoLength
= sizeof (OPAL_DEVICE_LOCKBOX_DATA
) + (UINT32
) GetDevicePathSize (DevicePath
);
241 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
248 TmpDevPath
= DevicePath
;
249 TmpDevPath2
= NextDevicePathNode (DevicePath
);
250 while (!IsDevicePathEnd (TmpDevPath2
)) {
251 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
252 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
253 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
) &&
254 (TmpDevPath2
->SubType
== MSG_SATA_DP
|| TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
255 if (DevInfo
!= NULL
) {
256 PciDevice
= &DevInfo
->Device
;
257 PciDevice
->Segment
= 0;
258 PciDevice
->Bus
= BusNum
;
259 PciDevice
->Device
= PciDevPath
->Device
;
260 PciDevice
->Function
= PciDevPath
->Function
;
263 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
264 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
269 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
270 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
273 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
278 Build OPAL device info and save them to LockBox.
282 BuildOpalDeviceInfo (
287 OPAL_DEVICE_LOCKBOX_DATA
*DevInfo
;
288 OPAL_DEVICE_LOCKBOX_DATA
*TempDevInfo
;
289 UINTN TotalDevInfoLength
;
290 UINT32 DevInfoLength
;
291 OPAL_DRIVER_DEVICE
*TmpDev
;
293 BOOLEAN S3InitDevicesExist
;
294 UINTN S3InitDevicesLength
;
295 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
296 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevicesBak
;
299 // Build OPAL device info and save them to LockBox.
301 TotalDevInfoLength
= 0;
302 TmpDev
= mOpalDriver
.DeviceList
;
303 while (TmpDev
!= NULL
) {
304 ExtractDeviceInfoFromDevicePath (
305 TmpDev
->OpalDisk
.OpalDevicePath
,
309 TotalDevInfoLength
+= DevInfoLength
;
310 TmpDev
= TmpDev
->Next
;
313 if (TotalDevInfoLength
== 0) {
317 S3InitDevicesLength
= sizeof (DummyData
);
318 Status
= RestoreLockBox (
319 &gS3StorageDeviceInitListGuid
,
323 ASSERT ((Status
== EFI_NOT_FOUND
) || (Status
== EFI_BUFFER_TOO_SMALL
));
324 if (Status
== EFI_NOT_FOUND
) {
325 S3InitDevices
= NULL
;
326 S3InitDevicesExist
= FALSE
;
327 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
328 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
329 ASSERT (S3InitDevices
!= NULL
);
330 if (S3InitDevices
== NULL
) {
334 Status
= RestoreLockBox (
335 &gS3StorageDeviceInitListGuid
,
339 ASSERT_EFI_ERROR (Status
);
340 S3InitDevicesExist
= TRUE
;
345 DevInfo
= AllocateZeroPool (TotalDevInfoLength
);
346 ASSERT (DevInfo
!= NULL
);
347 if (DevInfo
== NULL
) {
351 TempDevInfo
= DevInfo
;
352 TmpDev
= mOpalDriver
.DeviceList
;
353 while (TmpDev
!= NULL
) {
354 ExtractDeviceInfoFromDevicePath (
355 TmpDev
->OpalDisk
.OpalDevicePath
,
359 TempDevInfo
->Length
= DevInfoLength
;
360 TempDevInfo
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
362 TempDevInfo
->Password
,
363 TmpDev
->OpalDisk
.Password
,
364 TmpDev
->OpalDisk
.PasswordLength
366 TempDevInfo
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
368 S3InitDevicesBak
= S3InitDevices
;
369 S3InitDevices
= AppendDevicePathInstance (
371 TmpDev
->OpalDisk
.OpalDevicePath
373 if (S3InitDevicesBak
!= NULL
) {
374 FreePool (S3InitDevicesBak
);
376 ASSERT (S3InitDevices
!= NULL
);
377 if (S3InitDevices
== NULL
) {
381 TempDevInfo
= (OPAL_DEVICE_LOCKBOX_DATA
*) ((UINTN
) TempDevInfo
+ DevInfoLength
);
382 TmpDev
= TmpDev
->Next
;
385 Status
= SaveLockBox (
386 &mOpalDeviceLockBoxGuid
,
390 ASSERT_EFI_ERROR (Status
);
392 Status
= SetLockBoxAttributes (
393 &mOpalDeviceLockBoxGuid
,
394 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
396 ASSERT_EFI_ERROR (Status
);
398 S3InitDevicesLength
= GetDevicePathSize (S3InitDevices
);
399 if (S3InitDevicesExist
) {
400 Status
= UpdateLockBox (
401 &gS3StorageDeviceInitListGuid
,
406 ASSERT_EFI_ERROR (Status
);
408 Status
= SaveLockBox (
409 &gS3StorageDeviceInitListGuid
,
413 ASSERT_EFI_ERROR (Status
);
415 Status
= SetLockBoxAttributes (
416 &gS3StorageDeviceInitListGuid
,
417 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
419 ASSERT_EFI_ERROR (Status
);
422 ZeroMem (DevInfo
, TotalDevInfoLength
);
424 FreePool (S3InitDevices
);
428 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
430 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
432 @param Event Event whose notification function is being invoked.
433 @param Context Pointer to the notification function's context.
438 OpalEndOfDxeEventNotify (
443 OPAL_DRIVER_DEVICE
*TmpDev
;
445 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
447 mOpalEndOfDxe
= TRUE
;
449 if (mOpalRequestVariable
!= NULL
) {
451 // Free the OPAL request variable buffer here
452 // as the OPAL requests should have been processed.
454 FreePool (mOpalRequestVariable
);
455 mOpalRequestVariable
= NULL
;
456 mOpalRequestVariableSize
= 0;
460 // If no any device, return directly.
462 if (mOpalDriver
.DeviceList
== NULL
) {
463 gBS
->CloseEvent (Event
);
467 BuildOpalDeviceInfo ();
472 TmpDev
= mOpalDriver
.DeviceList
;
473 while (TmpDev
!= NULL
) {
474 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
475 TmpDev
= TmpDev
->Next
;
478 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
480 gBS
->CloseEvent (Event
);
484 Get Psid input from the popup window.
486 @param[in] Dev The device which need Psid to process Psid Revert
488 @param[in] PopUpString Pop up string.
489 @param[in] PopUpString2 Pop up string in line 2.
491 @param[out] PressEsc Whether user escape function through Press ESC.
493 @retval Psid string if success. NULL if failed.
497 OpalDriverPopUpPsidInput (
498 IN OPAL_DRIVER_DEVICE
*Dev
,
499 IN CHAR16
*PopUpString
,
500 IN CHAR16
*PopUpString2
,
501 OUT BOOLEAN
*PressEsc
504 EFI_INPUT_KEY InputKey
;
506 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
507 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
510 ZeroMem(Unicode
, sizeof(Unicode
));
511 ZeroMem(Mask
, sizeof(Mask
));
515 gST
->ConOut
->ClearScreen(gST
->ConOut
);
519 Mask
[InputLength
] = L
'_';
520 if (PopUpString2
== NULL
) {
522 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
525 L
"---------------------",
531 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
535 L
"---------------------",
544 if (InputKey
.ScanCode
== SCAN_NULL
) {
548 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
550 // Add the null terminator.
552 Unicode
[InputLength
] = 0;
553 Mask
[InputLength
] = 0;
555 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
556 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
557 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
562 // delete last key entered
564 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
565 if (InputLength
> 0) {
566 Unicode
[InputLength
] = 0;
567 Mask
[InputLength
] = 0;
572 // add Next key entry
574 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
575 Mask
[InputLength
] = InputKey
.UnicodeChar
;
577 if (InputLength
== PSID_CHARACTER_LENGTH
) {
579 // Add the null terminator.
581 Unicode
[InputLength
] = 0;
582 Mask
[InputLength
] = 0;
592 if (InputKey
.ScanCode
== SCAN_ESC
) {
598 gST
->ConOut
->ClearScreen(gST
->ConOut
);
600 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
601 ZeroMem (Unicode
, sizeof (Unicode
));
602 ZeroMem (Mask
, sizeof (Mask
));
606 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
608 ZeroMem (Unicode
, sizeof (Unicode
));
609 ZeroMem (Mask
, sizeof (Mask
));
613 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
614 ZeroMem (Unicode
, sizeof (Unicode
));
615 ZeroMem (Mask
, sizeof (Mask
));
622 Get password input from the popup window.
624 @param[in] Dev The device which need password to unlock or
625 process OPAL request.
626 @param[in] PopUpString1 Pop up string 1.
627 @param[in] PopUpString2 Pop up string 2.
628 @param[out] PressEsc Whether user escape function through Press ESC.
630 @retval Password string if success. NULL if failed.
634 OpalDriverPopUpPasswordInput (
635 IN OPAL_DRIVER_DEVICE
*Dev
,
636 IN CHAR16
*PopUpString1
,
637 IN CHAR16
*PopUpString2
,
638 OUT BOOLEAN
*PressEsc
641 EFI_INPUT_KEY InputKey
;
643 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
644 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
647 ZeroMem(Unicode
, sizeof(Unicode
));
648 ZeroMem(Mask
, sizeof(Mask
));
652 gST
->ConOut
->ClearScreen(gST
->ConOut
);
656 Mask
[InputLength
] = L
'_';
657 if (PopUpString2
== NULL
) {
659 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
662 L
"---------------------",
668 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
672 L
"---------------------",
681 if (InputKey
.ScanCode
== SCAN_NULL
) {
685 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
687 // Add the null terminator.
689 Unicode
[InputLength
] = 0;
690 Mask
[InputLength
] = 0;
692 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
693 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
694 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
699 // delete last key entered
701 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
702 if (InputLength
> 0) {
703 Unicode
[InputLength
] = 0;
704 Mask
[InputLength
] = 0;
709 // add Next key entry
711 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
712 Mask
[InputLength
] = L
'*';
714 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
716 // Add the null terminator.
718 Unicode
[InputLength
] = 0;
719 Mask
[InputLength
] = 0;
729 if (InputKey
.ScanCode
== SCAN_ESC
) {
735 gST
->ConOut
->ClearScreen(gST
->ConOut
);
737 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
738 ZeroMem (Unicode
, sizeof (Unicode
));
742 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
744 ZeroMem (Unicode
, sizeof (Unicode
));
748 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
749 ZeroMem (Unicode
, sizeof (Unicode
));
757 @param[in] Dev The OPAL device.
758 @param[in] RequestString Request string.
760 @return Pop up string.
765 IN OPAL_DRIVER_DEVICE
*Dev
,
766 IN CHAR16
*RequestString
769 if (Dev
->Name16
== NULL
) {
770 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
772 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
779 Check if disk is locked, show popup window and ask for password if it is.
781 @param[in] Dev The device which need to be unlocked.
782 @param[in] RequestString Request string.
786 OpalDriverRequestPassword (
787 IN OPAL_DRIVER_DEVICE
*Dev
,
788 IN CHAR16
*RequestString
796 OPAL_SESSION Session
;
806 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
808 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
812 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
814 ZeroMem(&Session
, sizeof(Session
));
815 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
816 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
817 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
819 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
821 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
825 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
826 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
830 // Current device in the lock status and
831 // User not input password and press ESC,
832 // keep device in lock status and continue boot.
836 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
838 L
"Press ENTER to skip the request and continue boot,",
839 L
"Press ESC to input password again",
842 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
844 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
845 gST
->ConOut
->ClearScreen(gST
->ConOut
);
847 // Keep lock and continue boot.
852 // Let user input password again.
858 // Current device in the unlock status and
859 // User not input password and press ESC,
860 // Shutdown the device.
864 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
866 L
"Press ENTER to shutdown, Press ESC to input password again",
869 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
871 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
872 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
875 // Let user input password again.
882 if (Password
== NULL
) {
886 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
889 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
891 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
892 if (Ret
== TcgResultSuccess
) {
893 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
897 if (Ret
== TcgResultSuccess
) {
898 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
899 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
901 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
904 if (Password
!= NULL
) {
905 ZeroMem (Password
, PasswordLen
);
909 if (Ret
== TcgResultSuccess
) {
914 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
915 // before accept new password.
917 if (Ret
== TcgResultFailureInvalidType
) {
918 Count
= MAX_PASSWORD_TRY_COUNT
;
926 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
928 L
"Invalid password.",
929 L
"Press ENTER to retry",
932 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
935 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
938 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
940 L
"Opal password retry count exceeds the limit. Must shutdown!",
941 L
"Press ENTER to shutdown",
944 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
946 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
952 Process Enable Feature OPAL request.
954 @param[in] Dev The device which has Enable Feature OPAL request.
955 @param[in] RequestString Request string.
959 ProcessOpalRequestEnableFeature (
960 IN OPAL_DRIVER_DEVICE
*Dev
,
961 IN CHAR16
*RequestString
967 CHAR8
*PasswordConfirm
;
968 UINT32 PasswordLenConfirm
;
969 OPAL_SESSION Session
;
979 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
981 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
985 ZeroMem(&Session
, sizeof(Session
));
986 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
987 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
988 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
990 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
991 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
995 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
997 L
"Press ENTER to skip the request and continue boot,",
998 L
"Press ESC to input password again",
1001 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1003 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1004 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1008 // Let user input password again.
1014 if (Password
== NULL
) {
1018 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1020 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1021 if (PasswordConfirm
== NULL
) {
1022 ZeroMem (Password
, PasswordLen
);
1023 FreePool (Password
);
1027 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1028 if ((PasswordLen
!= PasswordLenConfirm
) ||
1029 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1030 ZeroMem (Password
, PasswordLen
);
1031 FreePool (Password
);
1032 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1033 FreePool (PasswordConfirm
);
1036 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1038 L
"Passwords are not the same.",
1039 L
"Press ENTER to retry",
1042 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1047 if (PasswordConfirm
!= NULL
) {
1048 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1049 FreePool (PasswordConfirm
);
1052 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1053 if (Ret
== TcgResultSuccess
) {
1054 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1055 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1057 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1060 if (Password
!= NULL
) {
1061 ZeroMem (Password
, PasswordLen
);
1062 FreePool (Password
);
1065 if (Ret
== TcgResultSuccess
) {
1073 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1076 L
"Press ENTER to retry",
1079 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1082 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1085 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1087 L
"Opal password retry count exceeds the limit.",
1088 L
"Press ENTER to skip the request and continue boot",
1091 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1092 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1097 Process Disable User OPAL request.
1099 @param[in] Dev The device which has Disable User OPAL request.
1100 @param[in] RequestString Request string.
1104 ProcessOpalRequestDisableUser (
1105 IN OPAL_DRIVER_DEVICE
*Dev
,
1106 IN CHAR16
*RequestString
1112 OPAL_SESSION Session
;
1116 BOOLEAN PasswordFailed
;
1117 CHAR16
*PopUpString
;
1123 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1125 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1129 ZeroMem(&Session
, sizeof(Session
));
1130 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1131 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1132 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1134 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1135 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1139 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1141 L
"Press ENTER to skip the request and continue boot,",
1142 L
"Press ESC to input password again",
1145 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1147 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1148 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1152 // Let user input password again.
1158 if (Password
== NULL
) {
1162 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1164 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1165 if (Ret
== TcgResultSuccess
) {
1166 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1167 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1169 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1172 if (Password
!= NULL
) {
1173 ZeroMem (Password
, PasswordLen
);
1174 FreePool (Password
);
1177 if (Ret
== TcgResultSuccess
) {
1185 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1187 L
"Invalid password, request failed.",
1188 L
"Press ENTER to retry",
1191 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1194 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1197 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1199 L
"Opal password retry count exceeds the limit.",
1200 L
"Press ENTER to skip the request and continue boot",
1203 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1204 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1209 Process Psid Revert OPAL request.
1211 @param[in] Dev The device which has Psid Revert OPAL request.
1212 @param[in] RequestString Request string.
1216 ProcessOpalRequestPsidRevert (
1217 IN OPAL_DRIVER_DEVICE
*Dev
,
1218 IN CHAR16
*RequestString
1224 OPAL_SESSION Session
;
1228 CHAR16
*PopUpString
;
1229 CHAR16
*PopUpString2
;
1236 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1238 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1240 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1241 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1242 PopUpString2
= AllocateZeroPool (BufferSize
);
1243 ASSERT (PopUpString2
!= NULL
);
1247 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1248 Dev
->OpalDisk
.EstimateTimeCost
1251 PopUpString2
= NULL
;
1256 ZeroMem(&Session
, sizeof(Session
));
1257 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1258 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1259 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1261 while (Count
< MAX_PSID_TRY_COUNT
) {
1262 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1266 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1268 L
"Press ENTER to skip the request and continue boot,",
1269 L
"Press ESC to input Psid again",
1272 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1274 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1275 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1279 // Let user input Psid again.
1289 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1291 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1292 if (Ret
== TcgResultSuccess
) {
1293 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1295 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1299 ZeroMem (Psid
, PsidLen
);
1303 if (Ret
== TcgResultSuccess
) {
1311 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1313 L
"Invalid Psid, request failed.",
1314 L
"Press ENTER to retry",
1317 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1320 if (Count
>= MAX_PSID_TRY_COUNT
) {
1323 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1325 L
"Opal Psid retry count exceeds the limit.",
1326 L
"Press ENTER to skip the request and continue boot",
1329 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1330 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1334 if (PopUpString2
!= NULL
) {
1335 FreePool (PopUpString2
);
1340 Process Admin Revert OPAL request.
1342 @param[in] Dev The device which has Revert OPAL request.
1343 @param[in] KeepUserData Whether to keep user data or not.
1344 @param[in] RequestString Request string.
1348 ProcessOpalRequestRevert (
1349 IN OPAL_DRIVER_DEVICE
*Dev
,
1350 IN BOOLEAN KeepUserData
,
1351 IN CHAR16
*RequestString
1357 OPAL_SESSION Session
;
1361 BOOLEAN PasswordFailed
;
1362 CHAR16
*PopUpString
;
1363 CHAR16
*PopUpString2
;
1370 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1372 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1374 if ((!KeepUserData
) &&
1375 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1376 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1377 PopUpString2
= AllocateZeroPool (BufferSize
);
1378 ASSERT (PopUpString2
!= NULL
);
1382 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1383 Dev
->OpalDisk
.EstimateTimeCost
1386 PopUpString2
= NULL
;
1391 ZeroMem(&Session
, sizeof(Session
));
1392 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1393 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1394 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1396 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1397 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1401 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1403 L
"Press ENTER to skip the request and continue boot,",
1404 L
"Press ESC to input password again",
1407 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1409 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1410 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1414 // Let user input password again.
1420 if (Password
== NULL
) {
1424 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1426 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1427 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1429 // For pyrite type device which does not support media encryption,
1430 // it does not accept "Keep User Data" parameter.
1431 // So here hardcode a FALSE for this case.
1433 Ret
= OpalUtilRevert(
1440 Dev
->OpalDisk
.MsidLength
1443 Ret
= OpalUtilRevert(
1450 Dev
->OpalDisk
.MsidLength
1453 if (Ret
== TcgResultSuccess
) {
1454 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1455 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1457 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1460 if (Password
!= NULL
) {
1461 ZeroMem (Password
, PasswordLen
);
1462 FreePool (Password
);
1465 if (Ret
== TcgResultSuccess
) {
1473 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1475 L
"Invalid password, request failed.",
1476 L
"Press ENTER to retry",
1479 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1482 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1485 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1487 L
"Opal password retry count exceeds the limit.",
1488 L
"Press ENTER to skip the request and continue boot",
1491 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1492 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1496 if (PopUpString2
!= NULL
) {
1497 FreePool (PopUpString2
);
1502 Process Secure Erase OPAL request.
1504 @param[in] Dev The device which has Secure Erase OPAL request.
1505 @param[in] RequestString Request string.
1509 ProcessOpalRequestSecureErase (
1510 IN OPAL_DRIVER_DEVICE
*Dev
,
1511 IN CHAR16
*RequestString
1517 OPAL_SESSION Session
;
1521 BOOLEAN PasswordFailed
;
1522 CHAR16
*PopUpString
;
1528 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1530 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1534 ZeroMem(&Session
, sizeof(Session
));
1535 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1536 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1537 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1539 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1540 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1544 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1546 L
"Press ENTER to skip the request and continue boot,",
1547 L
"Press ESC to input password again",
1550 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1552 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1553 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1557 // Let user input password again.
1563 if (Password
== NULL
) {
1567 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1569 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1570 if (Ret
== TcgResultSuccess
) {
1571 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1572 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1574 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1577 if (Password
!= NULL
) {
1578 ZeroMem (Password
, PasswordLen
);
1579 FreePool (Password
);
1582 if (Ret
== TcgResultSuccess
) {
1590 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1592 L
"Invalid password, request failed.",
1593 L
"Press ENTER to retry",
1596 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1599 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1602 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1604 L
"Opal password retry count exceeds the limit.",
1605 L
"Press ENTER to skip the request and continue boot",
1608 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1609 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1614 Process Set Admin Pwd OPAL request.
1616 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1617 @param[in] RequestString Request string.
1621 ProcessOpalRequestSetUserPwd (
1622 IN OPAL_DRIVER_DEVICE
*Dev
,
1623 IN CHAR16
*RequestString
1628 UINT32 OldPasswordLen
;
1631 CHAR8
*PasswordConfirm
;
1632 UINT32 PasswordLenConfirm
;
1633 OPAL_SESSION Session
;
1637 CHAR16
*PopUpString
;
1643 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1645 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1649 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1650 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1654 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1656 L
"Press ENTER to skip the request and continue boot,",
1657 L
"Press ESC to input password again",
1660 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1662 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1663 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1667 // Let user input password again.
1673 if (OldPassword
== NULL
) {
1677 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1679 ZeroMem(&Session
, sizeof(Session
));
1680 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1681 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1682 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1683 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1684 if (Ret
== TcgResultSuccess
) {
1685 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1687 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1688 if (Ret
== TcgResultSuccess
) {
1689 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1691 ZeroMem (OldPassword
, OldPasswordLen
);
1692 FreePool (OldPassword
);
1693 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1696 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1698 L
"Incorrect password.",
1699 L
"Press ENTER to retry",
1702 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1708 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1709 if (Password
== NULL
) {
1710 ZeroMem (OldPassword
, OldPasswordLen
);
1711 FreePool (OldPassword
);
1715 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1717 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1718 if (PasswordConfirm
== NULL
) {
1719 ZeroMem (OldPassword
, OldPasswordLen
);
1720 FreePool (OldPassword
);
1721 ZeroMem (Password
, PasswordLen
);
1722 FreePool (Password
);
1726 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1727 if ((PasswordLen
!= PasswordLenConfirm
) ||
1728 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1729 ZeroMem (OldPassword
, OldPasswordLen
);
1730 FreePool (OldPassword
);
1731 ZeroMem (Password
, PasswordLen
);
1732 FreePool (Password
);
1733 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1734 FreePool (PasswordConfirm
);
1737 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1739 L
"Passwords are not the same.",
1740 L
"Press ENTER to retry",
1743 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1748 if (PasswordConfirm
!= NULL
) {
1749 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1750 FreePool (PasswordConfirm
);
1753 ZeroMem(&Session
, sizeof(Session
));
1754 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1755 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1756 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1757 Ret
= OpalUtilSetUserPassword(
1764 if (Ret
== TcgResultSuccess
) {
1765 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1766 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1768 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1771 if (OldPassword
!= NULL
) {
1772 ZeroMem (OldPassword
, OldPasswordLen
);
1773 FreePool (OldPassword
);
1776 if (Password
!= NULL
) {
1777 ZeroMem (Password
, PasswordLen
);
1778 FreePool (Password
);
1781 if (Ret
== TcgResultSuccess
) {
1789 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1792 L
"Press ENTER to retry",
1795 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1798 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1801 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1803 L
"Opal password retry count exceeds the limit.",
1804 L
"Press ENTER to skip the request and continue boot",
1807 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1808 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1813 Process Set Admin Pwd OPAL request.
1815 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1816 @param[in] RequestString Request string.
1820 ProcessOpalRequestSetAdminPwd (
1821 IN OPAL_DRIVER_DEVICE
*Dev
,
1822 IN CHAR16
*RequestString
1827 UINT32 OldPasswordLen
;
1830 CHAR8
*PasswordConfirm
;
1831 UINT32 PasswordLenConfirm
;
1832 OPAL_SESSION Session
;
1836 CHAR16
*PopUpString
;
1842 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1844 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1848 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1849 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1853 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1855 L
"Press ENTER to skip the request and continue boot,",
1856 L
"Press ESC to input password again",
1859 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1861 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1862 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1866 // Let user input password again.
1872 if (OldPassword
== NULL
) {
1876 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1878 ZeroMem(&Session
, sizeof(Session
));
1879 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1880 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1881 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1882 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1883 if (Ret
== TcgResultSuccess
) {
1884 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1886 ZeroMem (OldPassword
, OldPasswordLen
);
1887 FreePool (OldPassword
);
1888 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1891 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1893 L
"Incorrect password.",
1894 L
"Press ENTER to retry",
1897 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1902 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1903 if (Password
== NULL
) {
1904 ZeroMem (OldPassword
, OldPasswordLen
);
1905 FreePool (OldPassword
);
1909 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1911 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1912 if (PasswordConfirm
== NULL
) {
1913 ZeroMem (OldPassword
, OldPasswordLen
);
1914 FreePool (OldPassword
);
1915 ZeroMem (Password
, PasswordLen
);
1916 FreePool (Password
);
1920 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1921 if ((PasswordLen
!= PasswordLenConfirm
) ||
1922 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1923 ZeroMem (OldPassword
, OldPasswordLen
);
1924 FreePool (OldPassword
);
1925 ZeroMem (Password
, PasswordLen
);
1926 FreePool (Password
);
1927 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1928 FreePool (PasswordConfirm
);
1931 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1933 L
"Passwords are not the same.",
1934 L
"Press ENTER to retry",
1937 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1942 if (PasswordConfirm
!= NULL
) {
1943 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1944 FreePool (PasswordConfirm
);
1948 ZeroMem(&Session
, sizeof(Session
));
1949 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1950 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1951 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1952 Ret
= OpalUtilSetAdminPassword(
1959 if (Ret
== TcgResultSuccess
) {
1960 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1961 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1963 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1966 if (OldPassword
!= NULL
) {
1967 ZeroMem (OldPassword
, OldPasswordLen
);
1968 FreePool (OldPassword
);
1971 if (Password
!= NULL
) {
1972 ZeroMem (Password
, PasswordLen
);
1973 FreePool (Password
);
1976 if (Ret
== TcgResultSuccess
) {
1984 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1987 L
"Press ENTER to retry",
1990 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1993 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1996 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1998 L
"Opal password retry count exceeds the limit.",
1999 L
"Press ENTER to skip the request and continue boot",
2002 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2003 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2008 Process OPAL request.
2010 @param[in] Dev The device which has OPAL request.
2014 ProcessOpalRequest (
2015 IN OPAL_DRIVER_DEVICE
*Dev
2019 OPAL_REQUEST_VARIABLE
*TempVariable
;
2020 OPAL_REQUEST_VARIABLE
*Variable
;
2022 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2023 UINTN DevicePathSizeInVariable
;
2024 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2025 UINTN DevicePathSize
;
2026 BOOLEAN KeepUserData
;
2028 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2030 if (mOpalRequestVariable
== NULL
) {
2031 Status
= GetVariable2 (
2032 OPAL_REQUEST_VARIABLE_NAME
,
2033 &gHiiSetupVariableGuid
,
2034 (VOID
**) &Variable
,
2037 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2040 mOpalRequestVariable
= Variable
;
2041 mOpalRequestVariableSize
= VariableSize
;
2044 // Delete the OPAL request variable.
2046 Status
= gRT
->SetVariable (
2047 OPAL_REQUEST_VARIABLE_NAME
,
2048 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2053 ASSERT_EFI_ERROR (Status
);
2055 Variable
= mOpalRequestVariable
;
2056 VariableSize
= mOpalRequestVariableSize
;
2060 // Process the OPAL requests.
2062 TempVariable
= Variable
;
2063 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2064 (VariableSize
>= TempVariable
->Length
) &&
2065 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2066 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2067 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2068 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2069 DevicePathSize
= GetDevicePathSize (DevicePath
);
2070 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2071 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2073 // Found the node for the OPAL device.
2075 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2076 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2078 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2079 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2081 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2082 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2084 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2085 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2086 ProcessOpalRequestRevert (
2089 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2092 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2093 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2095 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2096 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2098 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2099 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2105 VariableSize
-= TempVariable
->Length
;
2106 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2109 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2113 Add new device to the global device list.
2115 @param Dev New create device.
2120 IN OPAL_DRIVER_DEVICE
*Dev
2123 OPAL_DRIVER_DEVICE
*TmpDev
;
2125 if (mOpalDriver
.DeviceList
== NULL
) {
2126 mOpalDriver
.DeviceList
= Dev
;
2128 TmpDev
= mOpalDriver
.DeviceList
;
2129 while (TmpDev
->Next
!= NULL
) {
2130 TmpDev
= TmpDev
->Next
;
2138 Remove one device in the global device list.
2140 @param Dev The device need to be removed.
2145 IN OPAL_DRIVER_DEVICE
*Dev
2148 OPAL_DRIVER_DEVICE
*TmpDev
;
2150 if (mOpalDriver
.DeviceList
== NULL
) {
2154 if (mOpalDriver
.DeviceList
== Dev
) {
2155 mOpalDriver
.DeviceList
= NULL
;
2159 TmpDev
= mOpalDriver
.DeviceList
;
2160 while (TmpDev
->Next
!= NULL
) {
2161 if (TmpDev
->Next
== Dev
) {
2162 TmpDev
->Next
= Dev
->Next
;
2169 Get current device count.
2171 @retval return the current created device count.
2180 OPAL_DRIVER_DEVICE
*TmpDev
;
2183 TmpDev
= mOpalDriver
.DeviceList
;
2185 while (TmpDev
!= NULL
) {
2187 TmpDev
= TmpDev
->Next
;
2194 Get devcie list info.
2196 @retval return the device list pointer.
2199 OpalDriverGetDeviceList(
2203 return mOpalDriver
.DeviceList
;
2207 ReadyToBoot callback to send BlockSid command.
2209 @param Event Pointer to this event
2210 @param Context Event handler private Data
2215 ReadyToBootCallback (
2220 OPAL_DRIVER_DEVICE
*Itr
;
2222 OPAL_SESSION Session
;
2223 UINT32 PpStorageFlag
;
2225 gBS
->CloseEvent (Event
);
2227 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2228 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2230 // Send BlockSID command to each Opal disk
2232 Itr
= mOpalDriver
.DeviceList
;
2233 while (Itr
!= NULL
) {
2234 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2235 ZeroMem(&Session
, sizeof(Session
));
2236 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2237 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2238 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2240 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2241 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2242 if (Result
!= TcgResultSuccess
) {
2243 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2254 Stop this Controller.
2256 @param Dev The device need to be stopped.
2260 OpalDriverStopDevice (
2261 OPAL_DRIVER_DEVICE
*Dev
2267 FreePool(Dev
->Name16
);
2270 // remove OPAL_DRIVER_DEVICE from the list
2271 // it updates the controllerList pointer
2276 // close protocols that were opened
2280 &gEfiStorageSecurityCommandProtocolGuid
,
2281 gOpalDriverBinding
.DriverBindingHandle
,
2287 &gEfiBlockIoProtocolGuid
,
2288 gOpalDriverBinding
.DriverBindingHandle
,
2296 Get devcie name through the component name protocol.
2298 @param[in] AllHandlesBuffer The handle buffer for current system.
2299 @param[in] NumAllHandles The number of handles for the handle buffer.
2300 @param[in] Dev The device which need to get name.
2301 @param[in] UseComp1 Whether use component name or name2 protocol.
2303 @retval TRUE Find the name for this device.
2304 @retval FALSE Not found the name for this device.
2307 OpalDriverGetDeviceNameByProtocol(
2308 EFI_HANDLE
*AllHandlesBuffer
,
2309 UINTN NumAllHandles
,
2310 OPAL_DRIVER_DEVICE
*Dev
,
2314 EFI_HANDLE
* ProtocolHandlesBuffer
;
2315 UINTN NumProtocolHandles
;
2317 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2320 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2323 EFI_HANDLE TmpHandle
;
2326 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2330 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2333 // Find all EFI_HANDLES with protocol
2335 Status
= gBS
->LocateHandleBuffer(
2339 &NumProtocolHandles
,
2340 &ProtocolHandlesBuffer
2342 if (EFI_ERROR(Status
)) {
2348 // Exit early if no supported devices
2350 if (NumProtocolHandles
== 0) {
2355 // Get printable name by iterating through all protocols
2356 // using the handle as the child, and iterate through all handles for the controller
2357 // exit loop early once found, if not found, then delete device
2358 // storage security protocol instances already exist, add them to internal list
2360 Status
= EFI_DEVICE_ERROR
;
2361 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2364 if (Dev
->Name16
!= NULL
) {
2368 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2370 Status
= gBS
->OpenProtocol(
2376 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2378 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2383 // Use all handles array as controller handle
2385 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2386 Status
= Cnp1_2
->GetControllerName(
2388 AllHandlesBuffer
[Index2
],
2390 LANGUAGE_ISO_639_2_ENGLISH
,
2393 if (EFI_ERROR(Status
)) {
2394 Status
= Cnp1_2
->GetControllerName(
2396 AllHandlesBuffer
[Index2
],
2398 LANGUAGE_RFC_3066_ENGLISH
,
2402 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2403 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2404 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2405 ASSERT (Dev
->Name16
!= NULL
);
2406 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2407 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2408 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2411 // Retrieve bridge BDF info and port number or namespace depending on type
2414 Status
= gBS
->OpenProtocol(
2416 &gEfiDevicePathProtocolGuid
,
2417 (VOID
**)&TmpDevPath
,
2420 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2422 if (!EFI_ERROR(Status
)) {
2423 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2427 if (Dev
->Name16
!= NULL
) {
2428 FreePool(Dev
->Name16
);
2431 if (Dev
->NameZ
!= NULL
) {
2432 FreePool(Dev
->NameZ
);
2443 Get devcie name through the component name protocol.
2445 @param[in] Dev The device which need to get name.
2447 @retval TRUE Find the name for this device.
2448 @retval FALSE Not found the name for this device.
2451 OpalDriverGetDriverDeviceName(
2452 OPAL_DRIVER_DEVICE
*Dev
2455 EFI_HANDLE
* AllHandlesBuffer
;
2456 UINTN NumAllHandles
;
2460 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2465 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2467 if (Dev
->Name16
== NULL
) {
2468 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2470 // Find all EFI_HANDLES
2472 Status
= gBS
->LocateHandleBuffer(
2479 if (EFI_ERROR(Status
)) {
2480 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2485 // Try component Name2
2487 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2488 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2489 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2490 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2500 Main entry for this driver.
2502 @param ImageHandle Image Handle this driver.
2503 @param SystemTable Pointer to SystemTable.
2505 @retval EFI_SUCESS This function always complete successfully.
2509 EfiDriverEntryPoint(
2510 IN EFI_HANDLE ImageHandle
,
2511 IN EFI_SYSTEM_TABLE
* SystemTable
2515 EFI_EVENT ReadyToBootEvent
;
2516 EFI_EVENT EndOfDxeEvent
;
2518 Status
= EfiLibInstallDriverBindingComponentName2 (
2521 &gOpalDriverBinding
,
2523 &gOpalComponentName
,
2524 &gOpalComponentName2
2527 if (EFI_ERROR(Status
)) {
2528 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2533 // Initialize Driver object
2535 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2536 mOpalDriver
.Handle
= ImageHandle
;
2538 Status
= gBS
->CreateEventEx (
2541 OpalEndOfDxeEventNotify
,
2543 &gEfiEndOfDxeEventGroupGuid
,
2546 ASSERT_EFI_ERROR (Status
);
2549 // register a ReadyToBoot event callback for sending BlockSid command
2551 Status
= EfiCreateEventReadyToBootEx (
2553 ReadyToBootCallback
,
2554 (VOID
*) &ImageHandle
,
2559 // Install Hii packages.
2567 Tests to see if this driver supports a given controller.
2569 This function checks to see if the controller contains an instance of the
2570 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2571 and returns EFI_SUCCESS if it does.
2573 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2574 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2575 must support a protocol interface that supplies
2576 an I/O abstraction to the driver.
2577 @param[in] RemainingDevicePath This parameter is ignored.
2579 @retval EFI_SUCCESS The device contains required protocols
2580 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2581 RemainingDevicePath is already being managed by the driver
2583 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2584 RemainingDevicePath is already being managed by a different
2585 driver or an application that requires exclusive access.
2586 Currently not implemented.
2587 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2592 OpalEfiDriverBindingSupported(
2593 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2594 IN EFI_HANDLE Controller
,
2595 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2599 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2600 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2602 if (mOpalEndOfDxe
) {
2603 return EFI_UNSUPPORTED
;
2607 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2609 Status
= gBS
->OpenProtocol(
2611 &gEfiStorageSecurityCommandProtocolGuid
,
2612 ( VOID
** )&SecurityCommand
,
2613 This
->DriverBindingHandle
,
2615 EFI_OPEN_PROTOCOL_BY_DRIVER
2618 if (Status
== EFI_ALREADY_STARTED
) {
2622 if (EFI_ERROR(Status
)) {
2627 // Close protocol and reopen in Start call
2631 &gEfiStorageSecurityCommandProtocolGuid
,
2632 This
->DriverBindingHandle
,
2637 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2640 Status
= gBS
->OpenProtocol(
2642 &gEfiBlockIoProtocolGuid
,
2644 This
->DriverBindingHandle
,
2646 EFI_OPEN_PROTOCOL_BY_DRIVER
2649 if (EFI_ERROR(Status
)) {
2650 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2655 // Close protocol and reopen in Start call
2659 &gEfiBlockIoProtocolGuid
,
2660 This
->DriverBindingHandle
,
2668 Enables Opal Management on a supported device if available.
2670 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2671 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2672 This function will complete the other necessary checks, such as verifying the device supports
2673 the correct version of Opal. Upon verification, it will add the device to the
2674 Opal HII list in order to expose Opal managmeent options.
2676 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2677 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2678 must support a protocol interface that supplies
2679 an I/O abstraction to the driver.
2680 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2681 parameter is ignored by device drivers, and is optional for bus
2682 drivers. For a bus driver, if this parameter is NULL, then handles
2683 for all the children of Controller are created by this driver.
2684 If this parameter is not NULL and the first Device Path Node is
2685 not the End of Device Path Node, then only the Handle for the
2686 child device specified by the first Device Path Node of
2687 RemainingDevicePath is created by this driver.
2688 If the first Device Path Node of RemainingDevicePath is
2689 the End of Device Path Node, no child Handle is created by this
2692 @retval EFI_SUCCESS Opal management was enabled.
2693 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2694 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2695 @retval Others The driver failed to start the device.
2700 OpalEfiDriverBindingStart(
2701 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2702 IN EFI_HANDLE Controller
,
2703 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2707 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2708 OPAL_DRIVER_DEVICE
*Dev
;
2709 OPAL_DRIVER_DEVICE
*Itr
;
2712 Itr
= mOpalDriver
.DeviceList
;
2713 while (Itr
!= NULL
) {
2714 if (Controller
== Itr
->Handle
) {
2721 // Create internal device for tracking. This allows all disks to be tracked
2724 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2726 return EFI_OUT_OF_RESOURCES
;
2728 Dev
->Handle
= Controller
;
2731 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2733 Status
= gBS
->OpenProtocol(
2735 &gEfiStorageSecurityCommandProtocolGuid
,
2736 (VOID
**)&Dev
->Sscp
,
2737 This
->DriverBindingHandle
,
2739 EFI_OPEN_PROTOCOL_BY_DRIVER
2741 if (EFI_ERROR(Status
)) {
2747 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2750 Status
= gBS
->OpenProtocol(
2752 &gEfiBlockIoProtocolGuid
,
2754 This
->DriverBindingHandle
,
2756 EFI_OPEN_PROTOCOL_BY_DRIVER
2758 if (EFI_ERROR(Status
)) {
2760 // Close storage security that was opened
2764 &gEfiStorageSecurityCommandProtocolGuid
,
2765 This
->DriverBindingHandle
,
2776 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2780 &gEfiBlockIoProtocolGuid
,
2781 This
->DriverBindingHandle
,
2786 // Acquire Ascii printable name of child, if not found, then ignore device
2788 Result
= OpalDriverGetDriverDeviceName (Dev
);
2793 Status
= OpalDiskInitialize (Dev
);
2794 if (EFI_ERROR (Status
)) {
2798 AddDeviceToTail(Dev
);
2801 // Check if device is locked and prompt for password.
2803 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2806 // Process OPAL request from last boot.
2808 ProcessOpalRequest (Dev
);
2814 // free device, close protocols and exit
2818 &gEfiStorageSecurityCommandProtocolGuid
,
2819 This
->DriverBindingHandle
,
2825 return EFI_DEVICE_ERROR
;
2829 Stop this driver on Controller.
2831 @param This Protocol instance pointer.
2832 @param Controller Handle of device to stop driver on
2833 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2834 children is zero stop the entire bus driver.
2835 @param ChildHandleBuffer List of Child Handles to Stop.
2837 @retval EFI_SUCCESS This driver is removed Controller.
2838 @retval other This driver could not be removed from this device.
2843 OpalEfiDriverBindingStop(
2844 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2845 EFI_HANDLE Controller
,
2846 UINTN NumberOfChildren
,
2847 EFI_HANDLE
* ChildHandleBuffer
2850 OPAL_DRIVER_DEVICE
* Itr
;
2852 Itr
= mOpalDriver
.DeviceList
;
2855 // does Controller match any of the devices we are managing for Opal
2857 while (Itr
!= NULL
) {
2858 if (Itr
->Handle
== Controller
) {
2859 OpalDriverStopDevice (Itr
);
2866 return EFI_NOT_FOUND
;
2871 Unloads UEFI Driver. Very useful for debugging and testing.
2873 @param ImageHandle Image Handle this driver.
2875 @retval EFI_SUCCESS This function always complete successfully.
2876 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2880 OpalEfiDriverUnload (
2881 IN EFI_HANDLE ImageHandle
2885 OPAL_DRIVER_DEVICE
*Itr
;
2887 Status
= EFI_SUCCESS
;
2889 if (ImageHandle
!= gImageHandle
) {
2890 return (EFI_INVALID_PARAMETER
);
2894 // Uninstall any interface added to each device by us
2896 while (mOpalDriver
.DeviceList
) {
2897 Itr
= mOpalDriver
.DeviceList
;
2899 // Remove OPAL_DRIVER_DEVICE from the list
2900 // it updates the controllerList pointer
2902 OpalDriverStopDevice(Itr
);
2906 // Uninstall the HII capability
2908 Status
= HiiUninstall();