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
);
429 Send BlockSid command if needed.
433 SendBlockSidCommand (
437 OPAL_DRIVER_DEVICE
*Itr
;
439 OPAL_SESSION Session
;
440 UINT32 PpStorageFlag
;
442 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
443 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
445 // Send BlockSID command to each Opal disk
447 Itr
= mOpalDriver
.DeviceList
;
448 while (Itr
!= NULL
) {
449 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
450 ZeroMem(&Session
, sizeof(Session
));
451 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
452 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
453 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
455 DEBUG ((DEBUG_INFO
, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));
456 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
457 if (Result
!= TcgResultSuccess
) {
458 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
463 // Record BlockSID command has been sent.
465 Itr
->OpalDisk
.SentBlockSID
= TRUE
;
474 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
476 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
478 @param Event Event whose notification function is being invoked.
479 @param Context Pointer to the notification function's context.
484 OpalEndOfDxeEventNotify (
489 OPAL_DRIVER_DEVICE
*TmpDev
;
491 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
493 mOpalEndOfDxe
= TRUE
;
495 if (mOpalRequestVariable
!= NULL
) {
497 // Free the OPAL request variable buffer here
498 // as the OPAL requests should have been processed.
500 FreePool (mOpalRequestVariable
);
501 mOpalRequestVariable
= NULL
;
502 mOpalRequestVariableSize
= 0;
506 // If no any device, return directly.
508 if (mOpalDriver
.DeviceList
== NULL
) {
509 gBS
->CloseEvent (Event
);
513 BuildOpalDeviceInfo ();
518 TmpDev
= mOpalDriver
.DeviceList
;
519 while (TmpDev
!= NULL
) {
520 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
521 TmpDev
= TmpDev
->Next
;
525 // Send BlockSid command if needed.
527 SendBlockSidCommand ();
529 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
531 gBS
->CloseEvent (Event
);
535 Get Psid input from the popup window.
537 @param[in] Dev The device which need Psid to process Psid Revert
539 @param[in] PopUpString Pop up string.
540 @param[in] PopUpString2 Pop up string in line 2.
541 @param[in] PopUpString3 Pop up string in line 3.
543 @param[out] PressEsc Whether user escape function through Press ESC.
545 @retval Psid string if success. NULL if failed.
549 OpalDriverPopUpPsidInput (
550 IN OPAL_DRIVER_DEVICE
*Dev
,
551 IN CHAR16
*PopUpString
,
552 IN CHAR16
*PopUpString2
,
553 IN CHAR16
*PopUpString3
,
554 OUT BOOLEAN
*PressEsc
557 EFI_INPUT_KEY InputKey
;
559 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
560 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
563 ZeroMem(Unicode
, sizeof(Unicode
));
564 ZeroMem(Mask
, sizeof(Mask
));
568 gST
->ConOut
->ClearScreen(gST
->ConOut
);
572 Mask
[InputLength
] = L
'_';
573 if (PopUpString2
== NULL
) {
575 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
578 L
"---------------------",
583 if (PopUpString3
== NULL
) {
585 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
589 L
"---------------------",
595 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
600 L
"---------------------",
610 if (InputKey
.ScanCode
== SCAN_NULL
) {
614 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
616 // Add the null terminator.
618 Unicode
[InputLength
] = 0;
619 Mask
[InputLength
] = 0;
621 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
622 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
623 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
628 // delete last key entered
630 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
631 if (InputLength
> 0) {
632 Unicode
[InputLength
] = 0;
633 Mask
[InputLength
] = 0;
638 // add Next key entry
640 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
641 Mask
[InputLength
] = InputKey
.UnicodeChar
;
643 if (InputLength
== PSID_CHARACTER_LENGTH
) {
645 // Add the null terminator.
647 Unicode
[InputLength
] = 0;
648 Mask
[InputLength
] = 0;
658 if (InputKey
.ScanCode
== SCAN_ESC
) {
664 gST
->ConOut
->ClearScreen(gST
->ConOut
);
666 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
667 ZeroMem (Unicode
, sizeof (Unicode
));
668 ZeroMem (Mask
, sizeof (Mask
));
672 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
674 ZeroMem (Unicode
, sizeof (Unicode
));
675 ZeroMem (Mask
, sizeof (Mask
));
679 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
680 ZeroMem (Unicode
, sizeof (Unicode
));
681 ZeroMem (Mask
, sizeof (Mask
));
688 Get password input from the popup window.
690 @param[in] Dev The device which need password to unlock or
691 process OPAL request.
692 @param[in] PopUpString1 Pop up string 1.
693 @param[in] PopUpString2 Pop up string 2.
694 @param[in] PopUpString3 Pop up string 3.
695 @param[out] PressEsc Whether user escape function through Press ESC.
697 @retval Password string if success. NULL if failed.
701 OpalDriverPopUpPasswordInput (
702 IN OPAL_DRIVER_DEVICE
*Dev
,
703 IN CHAR16
*PopUpString1
,
704 IN CHAR16
*PopUpString2
,
705 IN CHAR16
*PopUpString3
,
706 OUT BOOLEAN
*PressEsc
709 EFI_INPUT_KEY InputKey
;
711 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
712 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
715 ZeroMem(Unicode
, sizeof(Unicode
));
716 ZeroMem(Mask
, sizeof(Mask
));
720 gST
->ConOut
->ClearScreen(gST
->ConOut
);
724 Mask
[InputLength
] = L
'_';
725 if (PopUpString2
== NULL
) {
727 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
730 L
"---------------------",
735 if (PopUpString3
== NULL
) {
737 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
741 L
"---------------------",
747 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
752 L
"---------------------",
762 if (InputKey
.ScanCode
== SCAN_NULL
) {
766 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
768 // Add the null terminator.
770 Unicode
[InputLength
] = 0;
771 Mask
[InputLength
] = 0;
773 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
774 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
775 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
780 // delete last key entered
782 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
783 if (InputLength
> 0) {
784 Unicode
[InputLength
] = 0;
785 Mask
[InputLength
] = 0;
790 // add Next key entry
792 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
793 Mask
[InputLength
] = L
'*';
795 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
797 // Add the null terminator.
799 Unicode
[InputLength
] = 0;
800 Mask
[InputLength
] = 0;
810 if (InputKey
.ScanCode
== SCAN_ESC
) {
816 gST
->ConOut
->ClearScreen(gST
->ConOut
);
818 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
819 ZeroMem (Unicode
, sizeof (Unicode
));
823 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
825 ZeroMem (Unicode
, sizeof (Unicode
));
829 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
830 ZeroMem (Unicode
, sizeof (Unicode
));
838 @param[in] Dev The OPAL device.
839 @param[in] RequestString Request string.
841 @return Pop up string.
846 IN OPAL_DRIVER_DEVICE
*Dev
,
847 IN CHAR16
*RequestString
850 if (Dev
->Name16
== NULL
) {
851 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
853 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
860 Check if disk is locked, show popup window and ask for password if it is.
862 @param[in] Dev The device which need to be unlocked.
863 @param[in] RequestString Request string.
867 OpalDriverRequestPassword (
868 IN OPAL_DRIVER_DEVICE
*Dev
,
869 IN CHAR16
*RequestString
877 OPAL_SESSION Session
;
887 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
889 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
893 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
895 ZeroMem(&Session
, sizeof(Session
));
896 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
897 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
898 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
900 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
902 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
906 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
907 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
911 // Current device in the lock status and
912 // User not input password and press ESC,
913 // keep device in lock status and continue boot.
917 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
919 L
"Press ENTER to skip the request and continue boot,",
920 L
"Press ESC to input password again",
923 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
925 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
926 gST
->ConOut
->ClearScreen(gST
->ConOut
);
928 // Keep lock and continue boot.
933 // Let user input password again.
939 // Current device in the unlock status and
940 // User not input password and press ESC,
941 // Shutdown the device.
945 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
947 L
"Press ENTER to shutdown, Press ESC to input password again",
950 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
952 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
953 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
956 // Let user input password again.
963 if (Password
== NULL
) {
967 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
970 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
972 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
973 if (Ret
== TcgResultSuccess
) {
974 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
978 if (Ret
== TcgResultSuccess
) {
979 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
980 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
982 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
985 if (Password
!= NULL
) {
986 ZeroMem (Password
, PasswordLen
);
990 if (Ret
== TcgResultSuccess
) {
995 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
996 // before accept new password.
998 if (Ret
== TcgResultFailureInvalidType
) {
999 Count
= MAX_PASSWORD_TRY_COUNT
;
1007 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1009 L
"Invalid password.",
1010 L
"Press ENTER to retry",
1013 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1016 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1019 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1021 L
"Opal password retry count exceeds the limit. Must shutdown!",
1022 L
"Press ENTER to shutdown",
1025 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1027 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1033 Process Enable Feature OPAL request.
1035 @param[in] Dev The device which has Enable Feature OPAL request.
1036 @param[in] RequestString Request string.
1040 ProcessOpalRequestEnableFeature (
1041 IN OPAL_DRIVER_DEVICE
*Dev
,
1042 IN CHAR16
*RequestString
1048 CHAR8
*PasswordConfirm
;
1049 UINT32 PasswordLenConfirm
;
1050 OPAL_SESSION Session
;
1054 CHAR16
*PopUpString
;
1060 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1062 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1066 ZeroMem(&Session
, sizeof(Session
));
1067 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1068 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1069 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1071 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1072 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1076 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1078 L
"Press ENTER to skip the request and continue boot,",
1079 L
"Press ESC to input password again",
1082 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1084 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1085 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1089 // Let user input password again.
1095 if (Password
== NULL
) {
1099 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1101 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1102 if (PasswordConfirm
== NULL
) {
1103 ZeroMem (Password
, PasswordLen
);
1104 FreePool (Password
);
1108 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1109 if ((PasswordLen
!= PasswordLenConfirm
) ||
1110 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1111 ZeroMem (Password
, PasswordLen
);
1112 FreePool (Password
);
1113 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1114 FreePool (PasswordConfirm
);
1117 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1119 L
"Passwords are not the same.",
1120 L
"Press ENTER to retry",
1123 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1128 if (PasswordConfirm
!= NULL
) {
1129 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1130 FreePool (PasswordConfirm
);
1133 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1134 if (Ret
== TcgResultSuccess
) {
1135 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1136 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1138 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1141 if (Password
!= NULL
) {
1142 ZeroMem (Password
, PasswordLen
);
1143 FreePool (Password
);
1146 if (Ret
== TcgResultSuccess
) {
1154 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1157 L
"Press ENTER to retry",
1160 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1163 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1166 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1168 L
"Opal password retry count exceeds the limit.",
1169 L
"Press ENTER to skip the request and continue boot",
1172 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1173 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1178 Process Disable User OPAL request.
1180 @param[in] Dev The device which has Disable User OPAL request.
1181 @param[in] RequestString Request string.
1185 ProcessOpalRequestDisableUser (
1186 IN OPAL_DRIVER_DEVICE
*Dev
,
1187 IN CHAR16
*RequestString
1193 OPAL_SESSION Session
;
1197 BOOLEAN PasswordFailed
;
1198 CHAR16
*PopUpString
;
1204 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1206 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1210 ZeroMem(&Session
, sizeof(Session
));
1211 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1212 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1213 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1215 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1216 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
1220 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1222 L
"Press ENTER to skip the request and continue boot,",
1223 L
"Press ESC to input password again",
1226 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1228 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1229 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1233 // Let user input password again.
1239 if (Password
== NULL
) {
1243 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1245 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1246 if (Ret
== TcgResultSuccess
) {
1247 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1248 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1250 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1253 if (Password
!= NULL
) {
1254 ZeroMem (Password
, PasswordLen
);
1255 FreePool (Password
);
1258 if (Ret
== TcgResultSuccess
) {
1266 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1268 L
"Invalid password, request failed.",
1269 L
"Press ENTER to retry",
1272 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1275 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1278 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1280 L
"Opal password retry count exceeds the limit.",
1281 L
"Press ENTER to skip the request and continue boot",
1284 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1285 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1290 Process Psid Revert OPAL request.
1292 @param[in] Dev The device which has Psid Revert OPAL request.
1293 @param[in] RequestString Request string.
1297 ProcessOpalRequestPsidRevert (
1298 IN OPAL_DRIVER_DEVICE
*Dev
,
1299 IN CHAR16
*RequestString
1305 OPAL_SESSION Session
;
1309 CHAR16
*PopUpString
;
1310 CHAR16
*PopUpString2
;
1311 CHAR16
*PopUpString3
;
1318 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1320 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1322 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1323 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1324 PopUpString2
= AllocateZeroPool (BufferSize
);
1325 ASSERT (PopUpString2
!= NULL
);
1329 L
"WARNING: Revert action will take about %d seconds",
1330 Dev
->OpalDisk
.EstimateTimeCost
1332 PopUpString3
= L
"DO NOT power off system during the revert action!";
1334 PopUpString2
= NULL
;
1335 PopUpString3
= NULL
;
1340 ZeroMem(&Session
, sizeof(Session
));
1341 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1342 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1343 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1345 while (Count
< MAX_PSID_TRY_COUNT
) {
1346 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1350 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1352 L
"Press ENTER to skip the request and continue boot,",
1353 L
"Press ESC to input Psid again",
1356 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1358 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1359 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1363 // Let user input Psid again.
1373 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1375 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1376 if (Ret
== TcgResultSuccess
) {
1377 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1379 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1383 ZeroMem (Psid
, PsidLen
);
1387 if (Ret
== TcgResultSuccess
) {
1395 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1397 L
"Invalid Psid, request failed.",
1398 L
"Press ENTER to retry",
1401 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1404 if (Count
>= MAX_PSID_TRY_COUNT
) {
1407 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1409 L
"Opal Psid retry count exceeds the limit.",
1410 L
"Press ENTER to skip the request and continue boot",
1413 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1414 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1418 if (PopUpString2
!= NULL
) {
1419 FreePool (PopUpString2
);
1424 Process Admin Revert OPAL request.
1426 @param[in] Dev The device which has Revert OPAL request.
1427 @param[in] KeepUserData Whether to keep user data or not.
1428 @param[in] RequestString Request string.
1432 ProcessOpalRequestRevert (
1433 IN OPAL_DRIVER_DEVICE
*Dev
,
1434 IN BOOLEAN KeepUserData
,
1435 IN CHAR16
*RequestString
1441 OPAL_SESSION Session
;
1445 BOOLEAN PasswordFailed
;
1446 CHAR16
*PopUpString
;
1447 CHAR16
*PopUpString2
;
1448 CHAR16
*PopUpString3
;
1455 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1457 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1459 if ((!KeepUserData
) &&
1460 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1461 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1462 PopUpString2
= AllocateZeroPool (BufferSize
);
1463 ASSERT (PopUpString2
!= NULL
);
1467 L
"WARNING: Revert action will take about %d seconds",
1468 Dev
->OpalDisk
.EstimateTimeCost
1470 PopUpString3
= L
"DO NOT power off system during the revert action!";
1472 PopUpString2
= NULL
;
1473 PopUpString3
= NULL
;
1478 ZeroMem(&Session
, sizeof(Session
));
1479 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1480 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1481 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1483 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1484 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1488 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1490 L
"Press ENTER to skip the request and continue boot,",
1491 L
"Press ESC to input password again",
1494 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1496 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1497 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1501 // Let user input password again.
1507 if (Password
== NULL
) {
1511 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1513 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1514 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1516 // For pyrite type device which does not support media encryption,
1517 // it does not accept "Keep User Data" parameter.
1518 // So here hardcode a FALSE for this case.
1520 Ret
= OpalUtilRevert(
1527 Dev
->OpalDisk
.MsidLength
1530 Ret
= OpalUtilRevert(
1537 Dev
->OpalDisk
.MsidLength
1540 if (Ret
== TcgResultSuccess
) {
1541 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1542 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1544 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1547 if (Password
!= NULL
) {
1548 ZeroMem (Password
, PasswordLen
);
1549 FreePool (Password
);
1552 if (Ret
== TcgResultSuccess
) {
1560 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1562 L
"Invalid password, request failed.",
1563 L
"Press ENTER to retry",
1566 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1569 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1572 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1574 L
"Opal password retry count exceeds the limit.",
1575 L
"Press ENTER to skip the request and continue boot",
1578 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1579 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1583 if (PopUpString2
!= NULL
) {
1584 FreePool (PopUpString2
);
1589 Process Secure Erase OPAL request.
1591 @param[in] Dev The device which has Secure Erase OPAL request.
1592 @param[in] RequestString Request string.
1596 ProcessOpalRequestSecureErase (
1597 IN OPAL_DRIVER_DEVICE
*Dev
,
1598 IN CHAR16
*RequestString
1604 OPAL_SESSION Session
;
1608 BOOLEAN PasswordFailed
;
1609 CHAR16
*PopUpString
;
1610 CHAR16
*PopUpString2
;
1611 CHAR16
*PopUpString3
;
1618 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1620 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1622 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1623 BufferSize
= StrSize (L
"Warning: Secure erase action will take about ####### seconds");
1624 PopUpString2
= AllocateZeroPool (BufferSize
);
1625 ASSERT (PopUpString2
!= NULL
);
1629 L
"WARNING: Secure erase action will take about %d seconds",
1630 Dev
->OpalDisk
.EstimateTimeCost
1632 PopUpString3
= L
"DO NOT power off system during the action!";
1634 PopUpString2
= NULL
;
1635 PopUpString3
= NULL
;
1639 ZeroMem(&Session
, sizeof(Session
));
1640 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1641 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1642 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1644 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1645 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1649 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1651 L
"Press ENTER to skip the request and continue boot,",
1652 L
"Press ESC to input password again",
1655 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1657 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1658 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1662 // Let user input password again.
1668 if (Password
== NULL
) {
1672 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1674 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1675 if (Ret
== TcgResultSuccess
) {
1676 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1677 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1679 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1682 if (Password
!= NULL
) {
1683 ZeroMem (Password
, PasswordLen
);
1684 FreePool (Password
);
1687 if (Ret
== TcgResultSuccess
) {
1695 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1697 L
"Invalid password, request failed.",
1698 L
"Press ENTER to retry",
1701 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1704 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1707 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1709 L
"Opal password retry count exceeds the limit.",
1710 L
"Press ENTER to skip the request and continue boot",
1713 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1714 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1718 if (PopUpString2
!= NULL
) {
1719 FreePool (PopUpString2
);
1724 Process Set Admin Pwd OPAL request.
1726 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1727 @param[in] RequestString Request string.
1731 ProcessOpalRequestSetUserPwd (
1732 IN OPAL_DRIVER_DEVICE
*Dev
,
1733 IN CHAR16
*RequestString
1738 UINT32 OldPasswordLen
;
1741 CHAR8
*PasswordConfirm
;
1742 UINT32 PasswordLenConfirm
;
1743 OPAL_SESSION Session
;
1747 CHAR16
*PopUpString
;
1753 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1755 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1759 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1760 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1764 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1766 L
"Press ENTER to skip the request and continue boot,",
1767 L
"Press ESC to input password again",
1770 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1772 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1773 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1777 // Let user input password again.
1783 if (OldPassword
== NULL
) {
1787 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1789 ZeroMem(&Session
, sizeof(Session
));
1790 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1791 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1792 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1793 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1794 if (Ret
== TcgResultSuccess
) {
1795 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1797 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1798 if (Ret
== TcgResultSuccess
) {
1799 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1801 ZeroMem (OldPassword
, OldPasswordLen
);
1802 FreePool (OldPassword
);
1803 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1806 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1808 L
"Incorrect password.",
1809 L
"Press ENTER to retry",
1812 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1818 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1819 if (Password
== NULL
) {
1820 ZeroMem (OldPassword
, OldPasswordLen
);
1821 FreePool (OldPassword
);
1825 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1827 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1828 if (PasswordConfirm
== NULL
) {
1829 ZeroMem (OldPassword
, OldPasswordLen
);
1830 FreePool (OldPassword
);
1831 ZeroMem (Password
, PasswordLen
);
1832 FreePool (Password
);
1836 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1837 if ((PasswordLen
!= PasswordLenConfirm
) ||
1838 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1839 ZeroMem (OldPassword
, OldPasswordLen
);
1840 FreePool (OldPassword
);
1841 ZeroMem (Password
, PasswordLen
);
1842 FreePool (Password
);
1843 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1844 FreePool (PasswordConfirm
);
1847 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1849 L
"Passwords are not the same.",
1850 L
"Press ENTER to retry",
1853 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1858 if (PasswordConfirm
!= NULL
) {
1859 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1860 FreePool (PasswordConfirm
);
1863 ZeroMem(&Session
, sizeof(Session
));
1864 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1865 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1866 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1867 Ret
= OpalUtilSetUserPassword(
1874 if (Ret
== TcgResultSuccess
) {
1875 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1876 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1878 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1881 if (OldPassword
!= NULL
) {
1882 ZeroMem (OldPassword
, OldPasswordLen
);
1883 FreePool (OldPassword
);
1886 if (Password
!= NULL
) {
1887 ZeroMem (Password
, PasswordLen
);
1888 FreePool (Password
);
1891 if (Ret
== TcgResultSuccess
) {
1899 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1902 L
"Press ENTER to retry",
1905 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1908 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1911 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1913 L
"Opal password retry count exceeds the limit.",
1914 L
"Press ENTER to skip the request and continue boot",
1917 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1918 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1923 Process Set Admin Pwd OPAL request.
1925 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1926 @param[in] RequestString Request string.
1930 ProcessOpalRequestSetAdminPwd (
1931 IN OPAL_DRIVER_DEVICE
*Dev
,
1932 IN CHAR16
*RequestString
1937 UINT32 OldPasswordLen
;
1940 CHAR8
*PasswordConfirm
;
1941 UINT32 PasswordLenConfirm
;
1942 OPAL_SESSION Session
;
1946 CHAR16
*PopUpString
;
1952 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1954 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1958 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1959 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1963 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1965 L
"Press ENTER to skip the request and continue boot,",
1966 L
"Press ESC to input password again",
1969 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1971 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1972 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1976 // Let user input password again.
1982 if (OldPassword
== NULL
) {
1986 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1988 ZeroMem(&Session
, sizeof(Session
));
1989 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1990 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1991 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1992 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1993 if (Ret
== TcgResultSuccess
) {
1994 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1996 ZeroMem (OldPassword
, OldPasswordLen
);
1997 FreePool (OldPassword
);
1998 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2001 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2003 L
"Incorrect password.",
2004 L
"Press ENTER to retry",
2007 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2012 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
2013 if (Password
== NULL
) {
2014 ZeroMem (OldPassword
, OldPasswordLen
);
2015 FreePool (OldPassword
);
2019 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2021 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
2022 if (PasswordConfirm
== NULL
) {
2023 ZeroMem (OldPassword
, OldPasswordLen
);
2024 FreePool (OldPassword
);
2025 ZeroMem (Password
, PasswordLen
);
2026 FreePool (Password
);
2030 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2031 if ((PasswordLen
!= PasswordLenConfirm
) ||
2032 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2033 ZeroMem (OldPassword
, OldPasswordLen
);
2034 FreePool (OldPassword
);
2035 ZeroMem (Password
, PasswordLen
);
2036 FreePool (Password
);
2037 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2038 FreePool (PasswordConfirm
);
2041 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2043 L
"Passwords are not the same.",
2044 L
"Press ENTER to retry",
2047 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2052 if (PasswordConfirm
!= NULL
) {
2053 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2054 FreePool (PasswordConfirm
);
2058 ZeroMem(&Session
, sizeof(Session
));
2059 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2060 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2061 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2062 Ret
= OpalUtilSetAdminPassword(
2069 if (Ret
== TcgResultSuccess
) {
2070 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2071 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2073 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2076 if (OldPassword
!= NULL
) {
2077 ZeroMem (OldPassword
, OldPasswordLen
);
2078 FreePool (OldPassword
);
2081 if (Password
!= NULL
) {
2082 ZeroMem (Password
, PasswordLen
);
2083 FreePool (Password
);
2086 if (Ret
== TcgResultSuccess
) {
2094 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2097 L
"Press ENTER to retry",
2100 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2103 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2106 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2108 L
"Opal password retry count exceeds the limit.",
2109 L
"Press ENTER to skip the request and continue boot",
2112 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2113 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2118 Process OPAL request.
2120 @param[in] Dev The device which has OPAL request.
2124 ProcessOpalRequest (
2125 IN OPAL_DRIVER_DEVICE
*Dev
2129 OPAL_REQUEST_VARIABLE
*TempVariable
;
2130 OPAL_REQUEST_VARIABLE
*Variable
;
2132 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2133 UINTN DevicePathSizeInVariable
;
2134 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2135 UINTN DevicePathSize
;
2136 BOOLEAN KeepUserData
;
2138 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2140 if (mOpalRequestVariable
== NULL
) {
2141 Status
= GetVariable2 (
2142 OPAL_REQUEST_VARIABLE_NAME
,
2143 &gHiiSetupVariableGuid
,
2144 (VOID
**) &Variable
,
2147 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2150 mOpalRequestVariable
= Variable
;
2151 mOpalRequestVariableSize
= VariableSize
;
2154 // Delete the OPAL request variable.
2156 Status
= gRT
->SetVariable (
2157 OPAL_REQUEST_VARIABLE_NAME
,
2158 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2163 ASSERT_EFI_ERROR (Status
);
2165 Variable
= mOpalRequestVariable
;
2166 VariableSize
= mOpalRequestVariableSize
;
2170 // Process the OPAL requests.
2172 TempVariable
= Variable
;
2173 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2174 (VariableSize
>= TempVariable
->Length
) &&
2175 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2176 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2177 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2178 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2179 DevicePathSize
= GetDevicePathSize (DevicePath
);
2180 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2181 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2183 // Found the node for the OPAL device.
2185 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2186 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2188 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2189 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2191 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2192 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2194 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2195 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2196 ProcessOpalRequestRevert (
2199 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2202 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2203 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2205 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2206 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2208 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2209 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2213 // Update Device ownership.
2214 // Later BlockSID command may block the update.
2216 OpalDiskUpdateOwnerShip (&Dev
->OpalDisk
);
2221 VariableSize
-= TempVariable
->Length
;
2222 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2225 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2229 Add new device to the global device list.
2231 @param Dev New create device.
2236 IN OPAL_DRIVER_DEVICE
*Dev
2239 OPAL_DRIVER_DEVICE
*TmpDev
;
2241 if (mOpalDriver
.DeviceList
== NULL
) {
2242 mOpalDriver
.DeviceList
= Dev
;
2244 TmpDev
= mOpalDriver
.DeviceList
;
2245 while (TmpDev
->Next
!= NULL
) {
2246 TmpDev
= TmpDev
->Next
;
2254 Remove one device in the global device list.
2256 @param Dev The device need to be removed.
2261 IN OPAL_DRIVER_DEVICE
*Dev
2264 OPAL_DRIVER_DEVICE
*TmpDev
;
2266 if (mOpalDriver
.DeviceList
== NULL
) {
2270 if (mOpalDriver
.DeviceList
== Dev
) {
2271 mOpalDriver
.DeviceList
= NULL
;
2275 TmpDev
= mOpalDriver
.DeviceList
;
2276 while (TmpDev
->Next
!= NULL
) {
2277 if (TmpDev
->Next
== Dev
) {
2278 TmpDev
->Next
= Dev
->Next
;
2285 Get current device count.
2287 @retval return the current created device count.
2296 OPAL_DRIVER_DEVICE
*TmpDev
;
2299 TmpDev
= mOpalDriver
.DeviceList
;
2301 while (TmpDev
!= NULL
) {
2303 TmpDev
= TmpDev
->Next
;
2310 Get devcie list info.
2312 @retval return the device list pointer.
2315 OpalDriverGetDeviceList(
2319 return mOpalDriver
.DeviceList
;
2323 Stop this Controller.
2325 @param Dev The device need to be stopped.
2329 OpalDriverStopDevice (
2330 OPAL_DRIVER_DEVICE
*Dev
2336 FreePool(Dev
->Name16
);
2339 // remove OPAL_DRIVER_DEVICE from the list
2340 // it updates the controllerList pointer
2345 // close protocols that were opened
2349 &gEfiStorageSecurityCommandProtocolGuid
,
2350 gOpalDriverBinding
.DriverBindingHandle
,
2356 &gEfiBlockIoProtocolGuid
,
2357 gOpalDriverBinding
.DriverBindingHandle
,
2365 Get devcie name through the component name protocol.
2367 @param[in] AllHandlesBuffer The handle buffer for current system.
2368 @param[in] NumAllHandles The number of handles for the handle buffer.
2369 @param[in] Dev The device which need to get name.
2370 @param[in] UseComp1 Whether use component name or name2 protocol.
2372 @retval TRUE Find the name for this device.
2373 @retval FALSE Not found the name for this device.
2376 OpalDriverGetDeviceNameByProtocol(
2377 EFI_HANDLE
*AllHandlesBuffer
,
2378 UINTN NumAllHandles
,
2379 OPAL_DRIVER_DEVICE
*Dev
,
2383 EFI_HANDLE
* ProtocolHandlesBuffer
;
2384 UINTN NumProtocolHandles
;
2386 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2389 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2392 EFI_HANDLE TmpHandle
;
2395 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2399 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2402 // Find all EFI_HANDLES with protocol
2404 Status
= gBS
->LocateHandleBuffer(
2408 &NumProtocolHandles
,
2409 &ProtocolHandlesBuffer
2411 if (EFI_ERROR(Status
)) {
2417 // Exit early if no supported devices
2419 if (NumProtocolHandles
== 0) {
2424 // Get printable name by iterating through all protocols
2425 // using the handle as the child, and iterate through all handles for the controller
2426 // exit loop early once found, if not found, then delete device
2427 // storage security protocol instances already exist, add them to internal list
2429 Status
= EFI_DEVICE_ERROR
;
2430 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2433 if (Dev
->Name16
!= NULL
) {
2437 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2439 Status
= gBS
->OpenProtocol(
2445 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2447 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2452 // Use all handles array as controller handle
2454 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2455 Status
= Cnp1_2
->GetControllerName(
2457 AllHandlesBuffer
[Index2
],
2459 LANGUAGE_ISO_639_2_ENGLISH
,
2462 if (EFI_ERROR(Status
)) {
2463 Status
= Cnp1_2
->GetControllerName(
2465 AllHandlesBuffer
[Index2
],
2467 LANGUAGE_RFC_3066_ENGLISH
,
2471 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2472 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2473 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2474 ASSERT (Dev
->Name16
!= NULL
);
2475 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2476 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2477 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2480 // Retrieve bridge BDF info and port number or namespace depending on type
2483 Status
= gBS
->OpenProtocol(
2485 &gEfiDevicePathProtocolGuid
,
2486 (VOID
**)&TmpDevPath
,
2489 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2491 if (!EFI_ERROR(Status
)) {
2492 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2496 if (Dev
->Name16
!= NULL
) {
2497 FreePool(Dev
->Name16
);
2500 if (Dev
->NameZ
!= NULL
) {
2501 FreePool(Dev
->NameZ
);
2512 Get devcie name through the component name protocol.
2514 @param[in] Dev The device which need to get name.
2516 @retval TRUE Find the name for this device.
2517 @retval FALSE Not found the name for this device.
2520 OpalDriverGetDriverDeviceName(
2521 OPAL_DRIVER_DEVICE
*Dev
2524 EFI_HANDLE
* AllHandlesBuffer
;
2525 UINTN NumAllHandles
;
2529 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2534 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2536 if (Dev
->Name16
== NULL
) {
2537 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2539 // Find all EFI_HANDLES
2541 Status
= gBS
->LocateHandleBuffer(
2548 if (EFI_ERROR(Status
)) {
2549 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2554 // Try component Name2
2556 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2557 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2558 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2559 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2569 Main entry for this driver.
2571 @param ImageHandle Image Handle this driver.
2572 @param SystemTable Pointer to SystemTable.
2574 @retval EFI_SUCESS This function always complete successfully.
2578 EfiDriverEntryPoint(
2579 IN EFI_HANDLE ImageHandle
,
2580 IN EFI_SYSTEM_TABLE
* SystemTable
2584 EFI_EVENT EndOfDxeEvent
;
2586 Status
= EfiLibInstallDriverBindingComponentName2 (
2589 &gOpalDriverBinding
,
2591 &gOpalComponentName
,
2592 &gOpalComponentName2
2595 if (EFI_ERROR(Status
)) {
2596 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2601 // Initialize Driver object
2603 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2604 mOpalDriver
.Handle
= ImageHandle
;
2606 Status
= gBS
->CreateEventEx (
2609 OpalEndOfDxeEventNotify
,
2611 &gEfiEndOfDxeEventGroupGuid
,
2614 ASSERT_EFI_ERROR (Status
);
2617 // Install Hii packages.
2625 Tests to see if this driver supports a given controller.
2627 This function checks to see if the controller contains an instance of the
2628 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2629 and returns EFI_SUCCESS if it does.
2631 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2632 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2633 must support a protocol interface that supplies
2634 an I/O abstraction to the driver.
2635 @param[in] RemainingDevicePath This parameter is ignored.
2637 @retval EFI_SUCCESS The device contains required protocols
2638 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2639 RemainingDevicePath is already being managed by the driver
2641 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2642 RemainingDevicePath is already being managed by a different
2643 driver or an application that requires exclusive access.
2644 Currently not implemented.
2645 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2650 OpalEfiDriverBindingSupported(
2651 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2652 IN EFI_HANDLE Controller
,
2653 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2657 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2658 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2660 if (mOpalEndOfDxe
) {
2661 return EFI_UNSUPPORTED
;
2665 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2667 Status
= gBS
->OpenProtocol(
2669 &gEfiStorageSecurityCommandProtocolGuid
,
2670 ( VOID
** )&SecurityCommand
,
2671 This
->DriverBindingHandle
,
2673 EFI_OPEN_PROTOCOL_BY_DRIVER
2676 if (Status
== EFI_ALREADY_STARTED
) {
2680 if (EFI_ERROR(Status
)) {
2685 // Close protocol and reopen in Start call
2689 &gEfiStorageSecurityCommandProtocolGuid
,
2690 This
->DriverBindingHandle
,
2695 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2698 Status
= gBS
->OpenProtocol(
2700 &gEfiBlockIoProtocolGuid
,
2702 This
->DriverBindingHandle
,
2704 EFI_OPEN_PROTOCOL_BY_DRIVER
2707 if (EFI_ERROR(Status
)) {
2708 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2713 // Close protocol and reopen in Start call
2717 &gEfiBlockIoProtocolGuid
,
2718 This
->DriverBindingHandle
,
2726 Enables Opal Management on a supported device if available.
2728 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2729 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2730 This function will complete the other necessary checks, such as verifying the device supports
2731 the correct version of Opal. Upon verification, it will add the device to the
2732 Opal HII list in order to expose Opal managmeent options.
2734 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2735 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2736 must support a protocol interface that supplies
2737 an I/O abstraction to the driver.
2738 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2739 parameter is ignored by device drivers, and is optional for bus
2740 drivers. For a bus driver, if this parameter is NULL, then handles
2741 for all the children of Controller are created by this driver.
2742 If this parameter is not NULL and the first Device Path Node is
2743 not the End of Device Path Node, then only the Handle for the
2744 child device specified by the first Device Path Node of
2745 RemainingDevicePath is created by this driver.
2746 If the first Device Path Node of RemainingDevicePath is
2747 the End of Device Path Node, no child Handle is created by this
2750 @retval EFI_SUCCESS Opal management was enabled.
2751 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2752 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2753 @retval Others The driver failed to start the device.
2758 OpalEfiDriverBindingStart(
2759 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2760 IN EFI_HANDLE Controller
,
2761 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2765 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2766 OPAL_DRIVER_DEVICE
*Dev
;
2767 OPAL_DRIVER_DEVICE
*Itr
;
2770 Itr
= mOpalDriver
.DeviceList
;
2771 while (Itr
!= NULL
) {
2772 if (Controller
== Itr
->Handle
) {
2779 // Create internal device for tracking. This allows all disks to be tracked
2782 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2784 return EFI_OUT_OF_RESOURCES
;
2786 Dev
->Handle
= Controller
;
2789 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2791 Status
= gBS
->OpenProtocol(
2793 &gEfiStorageSecurityCommandProtocolGuid
,
2794 (VOID
**)&Dev
->Sscp
,
2795 This
->DriverBindingHandle
,
2797 EFI_OPEN_PROTOCOL_BY_DRIVER
2799 if (EFI_ERROR(Status
)) {
2805 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2808 Status
= gBS
->OpenProtocol(
2810 &gEfiBlockIoProtocolGuid
,
2812 This
->DriverBindingHandle
,
2814 EFI_OPEN_PROTOCOL_BY_DRIVER
2816 if (EFI_ERROR(Status
)) {
2818 // Close storage security that was opened
2822 &gEfiStorageSecurityCommandProtocolGuid
,
2823 This
->DriverBindingHandle
,
2834 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2838 &gEfiBlockIoProtocolGuid
,
2839 This
->DriverBindingHandle
,
2844 // Acquire Ascii printable name of child, if not found, then ignore device
2846 Result
= OpalDriverGetDriverDeviceName (Dev
);
2851 Status
= OpalDiskInitialize (Dev
);
2852 if (EFI_ERROR (Status
)) {
2856 AddDeviceToTail(Dev
);
2859 // Check if device is locked and prompt for password.
2861 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2864 // Process OPAL request from last boot.
2866 ProcessOpalRequest (Dev
);
2872 // free device, close protocols and exit
2876 &gEfiStorageSecurityCommandProtocolGuid
,
2877 This
->DriverBindingHandle
,
2883 return EFI_DEVICE_ERROR
;
2887 Stop this driver on Controller.
2889 @param This Protocol instance pointer.
2890 @param Controller Handle of device to stop driver on
2891 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2892 children is zero stop the entire bus driver.
2893 @param ChildHandleBuffer List of Child Handles to Stop.
2895 @retval EFI_SUCCESS This driver is removed Controller.
2896 @retval other This driver could not be removed from this device.
2901 OpalEfiDriverBindingStop(
2902 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2903 EFI_HANDLE Controller
,
2904 UINTN NumberOfChildren
,
2905 EFI_HANDLE
* ChildHandleBuffer
2908 OPAL_DRIVER_DEVICE
* Itr
;
2910 Itr
= mOpalDriver
.DeviceList
;
2913 // does Controller match any of the devices we are managing for Opal
2915 while (Itr
!= NULL
) {
2916 if (Itr
->Handle
== Controller
) {
2917 OpalDriverStopDevice (Itr
);
2924 return EFI_NOT_FOUND
;
2929 Unloads UEFI Driver. Very useful for debugging and testing.
2931 @param ImageHandle Image Handle this driver.
2933 @retval EFI_SUCCESS This function always complete successfully.
2934 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2938 OpalEfiDriverUnload (
2939 IN EFI_HANDLE ImageHandle
2943 OPAL_DRIVER_DEVICE
*Itr
;
2945 Status
= EFI_SUCCESS
;
2947 if (ImageHandle
!= gImageHandle
) {
2948 return (EFI_INVALID_PARAMETER
);
2952 // Uninstall any interface added to each device by us
2954 while (mOpalDriver
.DeviceList
) {
2955 Itr
= mOpalDriver
.DeviceList
;
2957 // Remove OPAL_DRIVER_DEVICE from the list
2958 // it updates the controllerList pointer
2960 OpalDriverStopDevice(Itr
);
2964 // Uninstall the HII capability
2966 Status
= HiiUninstall();