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
) {
79 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
80 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
81 // intact and accessible
83 AvalDiskActions
->PsidRevert
= 1;
84 AvalDiskActions
->RevertKeepDataForced
= 0;
87 // Secure erase is performed by generating a new encryption key
88 // this is only available if encryption is supported
90 AvalDiskActions
->SecureErase
= 1;
92 AvalDiskActions
->PsidRevert
= 0;
93 AvalDiskActions
->SecureErase
= 0;
96 // If no media encryption is supported, then a revert (using password) will not
97 // erase the Data (since you can't generate a new encryption key)
99 AvalDiskActions
->RevertKeepDataForced
= 1;
102 if (LockingFeature
->Locked
) {
103 AvalDiskActions
->Unlock
= 1;
105 AvalDiskActions
->Unlock
= 0;
109 // Only allow user to set password if an admin password exists
111 ExistingPassword
= OpalUtilAdminPasswordExists (OwnerShip
, LockingFeature
);
112 AvalDiskActions
->UserPass
= ExistingPassword
;
115 // This will still show up even if there isn't a user, which is fine
117 AvalDiskActions
->DisableUser
= ExistingPassword
;
119 return TcgResultSuccess
;
123 Enable Opal Feature for the input device.
125 @param[in] Session The opal session for the opal device.
127 @param[in] MsidLength Msid Length
128 @param[in] Password Admin password
129 @param[in] PassLength Length of password in bytes
134 OpalSupportEnableOpalFeature (
135 IN OPAL_SESSION
*Session
,
137 IN UINT32 MsidLength
,
144 NULL_CHECK (Session
);
146 NULL_CHECK (Password
);
148 Ret
= OpalUtilSetAdminPasswordAsSid (
155 if (Ret
== TcgResultSuccess
) {
157 // Enable global locking range
159 Ret
= OpalUtilSetOpalLockingRange (
163 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
177 Update password for the Opal disk.
179 @param[in, out] OpalDisk The disk to update password.
180 @param[in] Password The input password.
181 @param[in] PasswordLength The input password length.
185 OpalSupportUpdatePassword (
186 IN OUT OPAL_DISK
*OpalDisk
,
188 IN UINT32 PasswordLength
191 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
192 OpalDisk
->PasswordLength
= (UINT8
)PasswordLength
;
196 Extract device info from the device path.
198 @param[in] DevicePath Device path info for the device.
199 @param[out] DevInfoLength Device information length needed.
200 @param[out] DevInfo Device information extracted.
204 ExtractDeviceInfoFromDevicePath (
205 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
206 OUT UINT32
*DevInfoLength
,
207 OUT OPAL_DEVICE_LOCKBOX_DATA
*DevInfo OPTIONAL
210 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
211 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
212 PCI_DEVICE_PATH
*PciDevPath
;
215 OPAL_PCI_DEVICE
*PciDevice
;
217 ASSERT (DevicePath
!= NULL
);
218 ASSERT (DevInfoLength
!= NULL
);
220 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
223 TmpDevPath
= DevicePath
;
228 while (!IsDevicePathEnd (TmpDevPath
)) {
229 if ((TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
) &&
230 ((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
);
242 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
249 TmpDevPath
= DevicePath
;
250 TmpDevPath2
= NextDevicePathNode (DevicePath
);
251 while (!IsDevicePathEnd (TmpDevPath2
)) {
252 if ((TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
) && (TmpDevPath
->SubType
== HW_PCI_DP
)) {
253 PciDevPath
= (PCI_DEVICE_PATH
*)TmpDevPath
;
254 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
) &&
255 ((TmpDevPath2
->SubType
== MSG_SATA_DP
) || (TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)))
257 if (DevInfo
!= NULL
) {
258 PciDevice
= &DevInfo
->Device
;
259 PciDevice
->Segment
= 0;
260 PciDevice
->Bus
= BusNum
;
261 PciDevice
->Device
= PciDevPath
->Device
;
262 PciDevice
->Function
= PciDevPath
->Function
;
265 if ((TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
) && (TmpDevPath2
->SubType
== HW_PCI_DP
)) {
266 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
271 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
272 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
275 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
280 Build OPAL device info and save them to LockBox.
284 BuildOpalDeviceInfo (
289 OPAL_DEVICE_LOCKBOX_DATA
*DevInfo
;
290 OPAL_DEVICE_LOCKBOX_DATA
*TempDevInfo
;
291 UINTN TotalDevInfoLength
;
292 UINT32 DevInfoLength
;
293 OPAL_DRIVER_DEVICE
*TmpDev
;
295 BOOLEAN S3InitDevicesExist
;
296 UINTN S3InitDevicesLength
;
297 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
298 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevicesBak
;
301 // Build OPAL device info and save them to LockBox.
303 TotalDevInfoLength
= 0;
304 TmpDev
= mOpalDriver
.DeviceList
;
305 while (TmpDev
!= NULL
) {
306 ExtractDeviceInfoFromDevicePath (
307 TmpDev
->OpalDisk
.OpalDevicePath
,
311 TotalDevInfoLength
+= DevInfoLength
;
312 TmpDev
= TmpDev
->Next
;
315 if (TotalDevInfoLength
== 0) {
319 S3InitDevicesLength
= sizeof (DummyData
);
320 Status
= RestoreLockBox (
321 &gS3StorageDeviceInitListGuid
,
325 ASSERT ((Status
== EFI_NOT_FOUND
) || (Status
== EFI_BUFFER_TOO_SMALL
));
326 if (Status
== EFI_NOT_FOUND
) {
327 S3InitDevices
= NULL
;
328 S3InitDevicesExist
= FALSE
;
329 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
330 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
331 ASSERT (S3InitDevices
!= NULL
);
332 if (S3InitDevices
== NULL
) {
336 Status
= RestoreLockBox (
337 &gS3StorageDeviceInitListGuid
,
341 ASSERT_EFI_ERROR (Status
);
342 S3InitDevicesExist
= TRUE
;
347 DevInfo
= AllocateZeroPool (TotalDevInfoLength
);
348 ASSERT (DevInfo
!= NULL
);
349 if (DevInfo
== NULL
) {
353 TempDevInfo
= DevInfo
;
354 TmpDev
= mOpalDriver
.DeviceList
;
355 while (TmpDev
!= NULL
) {
356 ExtractDeviceInfoFromDevicePath (
357 TmpDev
->OpalDisk
.OpalDevicePath
,
361 TempDevInfo
->Length
= DevInfoLength
;
362 TempDevInfo
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
364 TempDevInfo
->Password
,
365 TmpDev
->OpalDisk
.Password
,
366 TmpDev
->OpalDisk
.PasswordLength
368 TempDevInfo
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
370 S3InitDevicesBak
= S3InitDevices
;
371 S3InitDevices
= AppendDevicePathInstance (
373 TmpDev
->OpalDisk
.OpalDevicePath
375 if (S3InitDevicesBak
!= NULL
) {
376 FreePool (S3InitDevicesBak
);
379 ASSERT (S3InitDevices
!= NULL
);
380 if (S3InitDevices
== NULL
) {
384 TempDevInfo
= (OPAL_DEVICE_LOCKBOX_DATA
*)((UINTN
)TempDevInfo
+ DevInfoLength
);
385 TmpDev
= TmpDev
->Next
;
388 Status
= SaveLockBox (
389 &mOpalDeviceLockBoxGuid
,
393 ASSERT_EFI_ERROR (Status
);
395 Status
= SetLockBoxAttributes (
396 &mOpalDeviceLockBoxGuid
,
397 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
399 ASSERT_EFI_ERROR (Status
);
401 S3InitDevicesLength
= GetDevicePathSize (S3InitDevices
);
402 if (S3InitDevicesExist
) {
403 Status
= UpdateLockBox (
404 &gS3StorageDeviceInitListGuid
,
409 ASSERT_EFI_ERROR (Status
);
411 Status
= SaveLockBox (
412 &gS3StorageDeviceInitListGuid
,
416 ASSERT_EFI_ERROR (Status
);
418 Status
= SetLockBoxAttributes (
419 &gS3StorageDeviceInitListGuid
,
420 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
422 ASSERT_EFI_ERROR (Status
);
425 ZeroMem (DevInfo
, TotalDevInfoLength
);
427 FreePool (S3InitDevices
);
432 Send BlockSid command if needed.
436 SendBlockSidCommand (
440 OPAL_DRIVER_DEVICE
*Itr
;
442 OPAL_SESSION Session
;
443 UINT32 PpStorageFlag
;
445 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
446 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
448 // Send BlockSID command to each Opal disk
450 Itr
= mOpalDriver
.DeviceList
;
451 while (Itr
!= NULL
) {
452 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
453 ZeroMem (&Session
, sizeof (Session
));
454 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
455 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
456 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
458 DEBUG ((DEBUG_INFO
, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));
459 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
460 if (Result
!= TcgResultSuccess
) {
461 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
466 // Record BlockSID command has been sent.
468 Itr
->OpalDisk
.SentBlockSID
= TRUE
;
477 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
479 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
481 @param Event Event whose notification function is being invoked.
482 @param Context Pointer to the notification function's context.
487 OpalEndOfDxeEventNotify (
492 OPAL_DRIVER_DEVICE
*TmpDev
;
494 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
496 mOpalEndOfDxe
= TRUE
;
498 if (mOpalRequestVariable
!= NULL
) {
500 // Free the OPAL request variable buffer here
501 // as the OPAL requests should have been processed.
503 FreePool (mOpalRequestVariable
);
504 mOpalRequestVariable
= NULL
;
505 mOpalRequestVariableSize
= 0;
509 // If no any device, return directly.
511 if (mOpalDriver
.DeviceList
== NULL
) {
512 gBS
->CloseEvent (Event
);
516 BuildOpalDeviceInfo ();
521 TmpDev
= mOpalDriver
.DeviceList
;
522 while (TmpDev
!= NULL
) {
523 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
524 TmpDev
= TmpDev
->Next
;
528 // Send BlockSid command if needed.
530 SendBlockSidCommand ();
532 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
534 gBS
->CloseEvent (Event
);
538 Get Psid input from the popup window.
540 @param[in] Dev The device which need Psid to process Psid Revert
542 @param[in] PopUpString Pop up string.
543 @param[in] PopUpString2 Pop up string in line 2.
544 @param[in] PopUpString3 Pop up string in line 3.
546 @param[out] PressEsc Whether user escape function through Press ESC.
548 @retval Psid string if success. NULL if failed.
552 OpalDriverPopUpPsidInput (
553 IN OPAL_DRIVER_DEVICE
*Dev
,
554 IN CHAR16
*PopUpString
,
555 IN CHAR16
*PopUpString2
,
556 IN CHAR16
*PopUpString3
,
557 OUT BOOLEAN
*PressEsc
560 EFI_INPUT_KEY InputKey
;
562 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
563 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
566 ZeroMem (Unicode
, sizeof (Unicode
));
567 ZeroMem (Mask
, sizeof (Mask
));
571 gST
->ConOut
->ClearScreen (gST
->ConOut
);
575 Mask
[InputLength
] = L
'_';
576 if (PopUpString2
== NULL
) {
578 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
581 L
"---------------------",
586 if (PopUpString3
== NULL
) {
588 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
592 L
"---------------------",
598 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
603 L
"---------------------",
613 if (InputKey
.ScanCode
== SCAN_NULL
) {
617 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
619 // Add the null terminator.
621 Unicode
[InputLength
] = 0;
622 Mask
[InputLength
] = 0;
624 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
625 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
626 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
632 // delete last key entered
634 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
635 if (InputLength
> 0) {
636 Unicode
[InputLength
] = 0;
637 Mask
[InputLength
] = 0;
642 // add Next key entry
644 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
645 Mask
[InputLength
] = InputKey
.UnicodeChar
;
647 if (InputLength
== PSID_CHARACTER_LENGTH
) {
649 // Add the null terminator.
651 Unicode
[InputLength
] = 0;
652 Mask
[InputLength
] = 0;
662 if (InputKey
.ScanCode
== SCAN_ESC
) {
668 gST
->ConOut
->ClearScreen (gST
->ConOut
);
670 if ((InputLength
== 0) || (InputKey
.ScanCode
== SCAN_ESC
)) {
671 ZeroMem (Unicode
, sizeof (Unicode
));
672 ZeroMem (Mask
, sizeof (Mask
));
676 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
678 ZeroMem (Unicode
, sizeof (Unicode
));
679 ZeroMem (Mask
, sizeof (Mask
));
683 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
684 ZeroMem (Unicode
, sizeof (Unicode
));
685 ZeroMem (Mask
, sizeof (Mask
));
691 Get password input from the popup window.
693 @param[in] Dev The device which need password to unlock or
694 process OPAL request.
695 @param[in] PopUpString1 Pop up string 1.
696 @param[in] PopUpString2 Pop up string 2.
697 @param[in] PopUpString3 Pop up string 3.
698 @param[out] PressEsc Whether user escape function through Press ESC.
700 @retval Password string if success. NULL if failed.
704 OpalDriverPopUpPasswordInput (
705 IN OPAL_DRIVER_DEVICE
*Dev
,
706 IN CHAR16
*PopUpString1
,
707 IN CHAR16
*PopUpString2
,
708 IN CHAR16
*PopUpString3
,
709 OUT BOOLEAN
*PressEsc
712 EFI_INPUT_KEY InputKey
;
714 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
715 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
718 ZeroMem (Unicode
, sizeof (Unicode
));
719 ZeroMem (Mask
, sizeof (Mask
));
723 gST
->ConOut
->ClearScreen (gST
->ConOut
);
727 Mask
[InputLength
] = L
'_';
728 if (PopUpString2
== NULL
) {
730 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
733 L
"---------------------",
738 if (PopUpString3
== NULL
) {
740 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
744 L
"---------------------",
750 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
755 L
"---------------------",
765 if (InputKey
.ScanCode
== SCAN_NULL
) {
769 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
771 // Add the null terminator.
773 Unicode
[InputLength
] = 0;
774 Mask
[InputLength
] = 0;
776 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
777 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
778 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
784 // delete last key entered
786 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
787 if (InputLength
> 0) {
788 Unicode
[InputLength
] = 0;
789 Mask
[InputLength
] = 0;
794 // add Next key entry
796 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
797 Mask
[InputLength
] = L
'*';
799 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
801 // Add the null terminator.
803 Unicode
[InputLength
] = 0;
804 Mask
[InputLength
] = 0;
814 if (InputKey
.ScanCode
== SCAN_ESC
) {
820 gST
->ConOut
->ClearScreen (gST
->ConOut
);
822 if ((InputLength
== 0) || (InputKey
.ScanCode
== SCAN_ESC
)) {
823 ZeroMem (Unicode
, sizeof (Unicode
));
827 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
829 ZeroMem (Unicode
, sizeof (Unicode
));
833 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
834 ZeroMem (Unicode
, sizeof (Unicode
));
842 @param[in] Dev The OPAL device.
843 @param[in] RequestString Request string.
845 @return Pop up string.
850 IN OPAL_DRIVER_DEVICE
*Dev
,
851 IN CHAR16
*RequestString
854 if (Dev
->Name16
== NULL
) {
855 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
857 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
864 Check if disk is locked, show popup window and ask for password if it is.
866 @param[in] Dev The device which need to be unlocked.
867 @param[in] RequestString Request string.
871 OpalDriverRequestPassword (
872 IN OPAL_DRIVER_DEVICE
*Dev
,
873 IN CHAR16
*RequestString
881 OPAL_SESSION Session
;
891 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
893 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
897 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
899 ZeroMem (&Session
, sizeof (Session
));
900 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
901 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
902 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
904 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
907 // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.
908 // Due to board design, device may not power off during system warm boot, which result in
909 // security status remain unlocked status, hence we add device security status check here.
911 // If device is in the locked status, device keeps locked and system continues booting.
912 // If device is in the unlocked status, system is forced shutdown to support security requirement.
914 if (PcdGetBool (PcdSkipOpalPasswordPrompt
)) {
918 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
922 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
923 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
927 // Current device in the lock status and
928 // User not input password and press ESC,
929 // keep device in lock status and continue boot.
933 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
935 L
"Press ENTER to skip the request and continue boot,",
936 L
"Press ESC to input password again",
939 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
941 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
942 gST
->ConOut
->ClearScreen (gST
->ConOut
);
944 // Keep lock and continue boot.
949 // Let user input password again.
955 // Current device in the unlock status and
956 // User not input password and press ESC,
957 // Shutdown the device.
961 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
963 L
"Press ENTER to shutdown, Press ESC to input password again",
966 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
968 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
969 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
972 // Let user input password again.
979 if (Password
== NULL
) {
984 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
987 Ret
= OpalUtilUpdateGlobalLockingRange (&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
989 Ret
= OpalUtilUpdateGlobalLockingRange (&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
990 if (Ret
== TcgResultSuccess
) {
991 Ret
= OpalUtilUpdateGlobalLockingRange (&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
995 if (Ret
== TcgResultSuccess
) {
996 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
997 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
999 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1002 if (Password
!= NULL
) {
1003 ZeroMem (Password
, PasswordLen
);
1004 FreePool (Password
);
1007 if (Ret
== TcgResultSuccess
) {
1012 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
1013 // before accept new password.
1015 if (Ret
== TcgResultFailureInvalidType
) {
1016 Count
= MAX_PASSWORD_TRY_COUNT
;
1024 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1026 L
"Invalid password.",
1027 L
"Press ENTER to retry",
1030 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1033 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1036 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1038 L
"Opal password retry count exceeds the limit. Must shutdown!",
1039 L
"Press ENTER to shutdown",
1042 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1044 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1050 Process Enable Feature OPAL request.
1052 @param[in] Dev The device which has Enable Feature OPAL request.
1053 @param[in] RequestString Request string.
1057 ProcessOpalRequestEnableFeature (
1058 IN OPAL_DRIVER_DEVICE
*Dev
,
1059 IN CHAR16
*RequestString
1065 CHAR8
*PasswordConfirm
;
1066 UINT32 PasswordLenConfirm
;
1067 OPAL_SESSION Session
;
1071 CHAR16
*PopUpString
;
1077 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1079 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1083 ZeroMem (&Session
, sizeof (Session
));
1084 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1085 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1086 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1088 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1089 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1093 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1095 L
"Press ENTER to skip the request and continue boot,",
1096 L
"Press ESC to input password again",
1099 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1101 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1102 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1106 // Let user input password again.
1112 if (Password
== NULL
) {
1117 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
1119 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1120 if (PasswordConfirm
== NULL
) {
1121 ZeroMem (Password
, PasswordLen
);
1122 FreePool (Password
);
1127 PasswordLenConfirm
= (UINT32
)AsciiStrLen (PasswordConfirm
);
1128 if ((PasswordLen
!= PasswordLenConfirm
) ||
1129 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0))
1131 ZeroMem (Password
, PasswordLen
);
1132 FreePool (Password
);
1133 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1134 FreePool (PasswordConfirm
);
1137 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1139 L
"Passwords are not the same.",
1140 L
"Press ENTER to retry",
1143 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1149 if (PasswordConfirm
!= NULL
) {
1150 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1151 FreePool (PasswordConfirm
);
1154 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1155 if (Ret
== TcgResultSuccess
) {
1156 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1157 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1159 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1162 if (Password
!= NULL
) {
1163 ZeroMem (Password
, PasswordLen
);
1164 FreePool (Password
);
1167 if (Ret
== TcgResultSuccess
) {
1175 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1178 L
"Press ENTER to retry",
1181 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1184 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1187 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1189 L
"Opal password retry count exceeds the limit.",
1190 L
"Press ENTER to skip the request and continue boot",
1193 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1195 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1200 Process Disable User OPAL request.
1202 @param[in] Dev The device which has Disable User OPAL request.
1203 @param[in] RequestString Request string.
1207 ProcessOpalRequestDisableUser (
1208 IN OPAL_DRIVER_DEVICE
*Dev
,
1209 IN CHAR16
*RequestString
1215 OPAL_SESSION Session
;
1219 BOOLEAN PasswordFailed
;
1220 CHAR16
*PopUpString
;
1226 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1228 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1232 ZeroMem (&Session
, sizeof (Session
));
1233 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1234 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1235 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1237 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1238 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
1242 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1244 L
"Press ENTER to skip the request and continue boot,",
1245 L
"Press ESC to input password again",
1248 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1250 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1251 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1255 // Let user input password again.
1261 if (Password
== NULL
) {
1266 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
1268 Ret
= OpalUtilDisableUser (&Session
, Password
, PasswordLen
, &PasswordFailed
);
1269 if (Ret
== TcgResultSuccess
) {
1270 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1271 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1273 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1276 if (Password
!= NULL
) {
1277 ZeroMem (Password
, PasswordLen
);
1278 FreePool (Password
);
1281 if (Ret
== TcgResultSuccess
) {
1289 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1291 L
"Invalid password, request failed.",
1292 L
"Press ENTER to retry",
1295 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1298 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1301 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1303 L
"Opal password retry count exceeds the limit.",
1304 L
"Press ENTER to skip the request and continue boot",
1307 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1309 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1314 Process Psid Revert OPAL request.
1316 @param[in] Dev The device which has Psid Revert OPAL request.
1317 @param[in] RequestString Request string.
1321 ProcessOpalRequestPsidRevert (
1322 IN OPAL_DRIVER_DEVICE
*Dev
,
1323 IN CHAR16
*RequestString
1329 OPAL_SESSION Session
;
1333 CHAR16
*PopUpString
;
1334 CHAR16
*PopUpString2
;
1335 CHAR16
*PopUpString3
;
1342 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1344 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1346 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1347 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1348 PopUpString2
= AllocateZeroPool (BufferSize
);
1349 ASSERT (PopUpString2
!= NULL
);
1353 L
"WARNING: Revert action will take about %d seconds",
1354 Dev
->OpalDisk
.EstimateTimeCost
1356 PopUpString3
= L
"DO NOT power off system during the revert action!";
1358 PopUpString2
= NULL
;
1359 PopUpString3
= NULL
;
1364 ZeroMem (&Session
, sizeof (Session
));
1365 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1366 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1367 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1369 while (Count
< MAX_PSID_TRY_COUNT
) {
1370 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1374 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1376 L
"Press ENTER to skip the request and continue boot,",
1377 L
"Press ESC to input Psid again",
1380 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1382 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1383 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1387 // Let user input Psid again.
1398 PsidLen
= (UINT32
)AsciiStrLen (Psid
);
1400 Ret
= OpalUtilPsidRevert (&Session
, Psid
, PsidLen
);
1401 if (Ret
== TcgResultSuccess
) {
1402 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1404 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1408 ZeroMem (Psid
, PsidLen
);
1412 if (Ret
== TcgResultSuccess
) {
1420 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1422 L
"Invalid Psid, request failed.",
1423 L
"Press ENTER to retry",
1426 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1429 if (Count
>= MAX_PSID_TRY_COUNT
) {
1432 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1434 L
"Opal Psid retry count exceeds the limit.",
1435 L
"Press ENTER to skip the request and continue boot",
1438 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1440 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1444 if (PopUpString2
!= NULL
) {
1445 FreePool (PopUpString2
);
1450 Process Admin Revert OPAL request.
1452 @param[in] Dev The device which has Revert OPAL request.
1453 @param[in] KeepUserData Whether to keep user data or not.
1454 @param[in] RequestString Request string.
1458 ProcessOpalRequestRevert (
1459 IN OPAL_DRIVER_DEVICE
*Dev
,
1460 IN BOOLEAN KeepUserData
,
1461 IN CHAR16
*RequestString
1467 OPAL_SESSION Session
;
1471 BOOLEAN PasswordFailed
;
1472 CHAR16
*PopUpString
;
1473 CHAR16
*PopUpString2
;
1474 CHAR16
*PopUpString3
;
1481 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1483 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1485 if ((!KeepUserData
) &&
1486 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
))
1488 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1489 PopUpString2
= AllocateZeroPool (BufferSize
);
1490 ASSERT (PopUpString2
!= NULL
);
1494 L
"WARNING: Revert action will take about %d seconds",
1495 Dev
->OpalDisk
.EstimateTimeCost
1497 PopUpString3
= L
"DO NOT power off system during the revert action!";
1499 PopUpString2
= NULL
;
1500 PopUpString3
= NULL
;
1505 ZeroMem (&Session
, sizeof (Session
));
1506 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1507 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1508 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1510 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1511 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1515 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1517 L
"Press ENTER to skip the request and continue boot,",
1518 L
"Press ESC to input password again",
1521 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1523 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1524 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1528 // Let user input password again.
1534 if (Password
== NULL
) {
1539 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
1541 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1542 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0))
1545 // For pyrite type device which does not support media encryption,
1546 // it does not accept "Keep User Data" parameter.
1547 // So here hardcode a FALSE for this case.
1549 Ret
= OpalUtilRevert (
1556 Dev
->OpalDisk
.MsidLength
1559 Ret
= OpalUtilRevert (
1566 Dev
->OpalDisk
.MsidLength
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
);
1610 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1614 if (PopUpString2
!= NULL
) {
1615 FreePool (PopUpString2
);
1620 Process Secure Erase OPAL request.
1622 @param[in] Dev The device which has Secure Erase OPAL request.
1623 @param[in] RequestString Request string.
1627 ProcessOpalRequestSecureErase (
1628 IN OPAL_DRIVER_DEVICE
*Dev
,
1629 IN CHAR16
*RequestString
1635 OPAL_SESSION Session
;
1639 BOOLEAN PasswordFailed
;
1640 CHAR16
*PopUpString
;
1641 CHAR16
*PopUpString2
;
1642 CHAR16
*PopUpString3
;
1649 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1651 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1653 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1654 BufferSize
= StrSize (L
"Warning: Secure erase action will take about ####### seconds");
1655 PopUpString2
= AllocateZeroPool (BufferSize
);
1656 ASSERT (PopUpString2
!= NULL
);
1660 L
"WARNING: Secure erase action will take about %d seconds",
1661 Dev
->OpalDisk
.EstimateTimeCost
1663 PopUpString3
= L
"DO NOT power off system during the action!";
1665 PopUpString2
= NULL
;
1666 PopUpString3
= NULL
;
1671 ZeroMem (&Session
, sizeof (Session
));
1672 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1673 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1674 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1676 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1677 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1681 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1683 L
"Press ENTER to skip the request and continue boot,",
1684 L
"Press ESC to input password again",
1687 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1689 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1690 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1694 // Let user input password again.
1700 if (Password
== NULL
) {
1705 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
1707 Ret
= OpalUtilSecureErase (&Session
, Password
, PasswordLen
, &PasswordFailed
);
1708 if (Ret
== TcgResultSuccess
) {
1709 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1710 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1712 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1715 if (Password
!= NULL
) {
1716 ZeroMem (Password
, PasswordLen
);
1717 FreePool (Password
);
1720 if (Ret
== TcgResultSuccess
) {
1728 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1730 L
"Invalid password, request failed.",
1731 L
"Press ENTER to retry",
1734 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1737 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1740 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1742 L
"Opal password retry count exceeds the limit.",
1743 L
"Press ENTER to skip the request and continue boot",
1746 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1748 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1752 if (PopUpString2
!= NULL
) {
1753 FreePool (PopUpString2
);
1758 Process Set Admin Pwd OPAL request.
1760 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1761 @param[in] RequestString Request string.
1765 ProcessOpalRequestSetUserPwd (
1766 IN OPAL_DRIVER_DEVICE
*Dev
,
1767 IN CHAR16
*RequestString
1772 UINT32 OldPasswordLen
;
1775 CHAR8
*PasswordConfirm
;
1776 UINT32 PasswordLenConfirm
;
1777 OPAL_SESSION Session
;
1781 CHAR16
*PopUpString
;
1787 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1789 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1793 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1794 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1798 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1800 L
"Press ENTER to skip the request and continue boot,",
1801 L
"Press ESC to input password again",
1804 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1806 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1807 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1811 // Let user input password again.
1817 if (OldPassword
== NULL
) {
1822 OldPasswordLen
= (UINT32
)AsciiStrLen (OldPassword
);
1824 ZeroMem (&Session
, sizeof (Session
));
1825 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1826 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1827 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1828 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1829 if (Ret
== TcgResultSuccess
) {
1830 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1832 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1833 if (Ret
== TcgResultSuccess
) {
1834 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1836 ZeroMem (OldPassword
, OldPasswordLen
);
1837 FreePool (OldPassword
);
1838 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1841 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1843 L
"Incorrect password.",
1844 L
"Press ENTER to retry",
1847 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1854 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1855 if (Password
== NULL
) {
1856 ZeroMem (OldPassword
, OldPasswordLen
);
1857 FreePool (OldPassword
);
1862 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
1864 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1865 if (PasswordConfirm
== NULL
) {
1866 ZeroMem (OldPassword
, OldPasswordLen
);
1867 FreePool (OldPassword
);
1868 ZeroMem (Password
, PasswordLen
);
1869 FreePool (Password
);
1874 PasswordLenConfirm
= (UINT32
)AsciiStrLen (PasswordConfirm
);
1875 if ((PasswordLen
!= PasswordLenConfirm
) ||
1876 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0))
1878 ZeroMem (OldPassword
, OldPasswordLen
);
1879 FreePool (OldPassword
);
1880 ZeroMem (Password
, PasswordLen
);
1881 FreePool (Password
);
1882 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1883 FreePool (PasswordConfirm
);
1886 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1888 L
"Passwords are not the same.",
1889 L
"Press ENTER to retry",
1892 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1898 if (PasswordConfirm
!= NULL
) {
1899 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1900 FreePool (PasswordConfirm
);
1903 ZeroMem (&Session
, sizeof (Session
));
1904 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1905 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1906 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1907 Ret
= OpalUtilSetUserPassword (
1914 if (Ret
== TcgResultSuccess
) {
1915 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1916 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1918 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1921 if (OldPassword
!= NULL
) {
1922 ZeroMem (OldPassword
, OldPasswordLen
);
1923 FreePool (OldPassword
);
1926 if (Password
!= NULL
) {
1927 ZeroMem (Password
, PasswordLen
);
1928 FreePool (Password
);
1931 if (Ret
== TcgResultSuccess
) {
1939 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1942 L
"Press ENTER to retry",
1945 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1948 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1951 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1953 L
"Opal password retry count exceeds the limit.",
1954 L
"Press ENTER to skip the request and continue boot",
1957 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1959 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1964 Process Set Admin Pwd OPAL request.
1966 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1967 @param[in] RequestString Request string.
1971 ProcessOpalRequestSetAdminPwd (
1972 IN OPAL_DRIVER_DEVICE
*Dev
,
1973 IN CHAR16
*RequestString
1978 UINT32 OldPasswordLen
;
1981 CHAR8
*PasswordConfirm
;
1982 UINT32 PasswordLenConfirm
;
1983 OPAL_SESSION Session
;
1987 CHAR16
*PopUpString
;
1993 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1995 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1999 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
2000 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
2004 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2006 L
"Press ENTER to skip the request and continue boot,",
2007 L
"Press ESC to input password again",
2010 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
2012 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2013 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2017 // Let user input password again.
2023 if (OldPassword
== NULL
) {
2028 OldPasswordLen
= (UINT32
)AsciiStrLen (OldPassword
);
2030 ZeroMem (&Session
, sizeof (Session
));
2031 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2032 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2033 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2034 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2035 if (Ret
== TcgResultSuccess
) {
2036 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2038 ZeroMem (OldPassword
, OldPasswordLen
);
2039 FreePool (OldPassword
);
2040 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2043 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2045 L
"Incorrect password.",
2046 L
"Press ENTER to retry",
2049 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2055 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
2056 if (Password
== NULL
) {
2057 ZeroMem (OldPassword
, OldPasswordLen
);
2058 FreePool (OldPassword
);
2063 PasswordLen
= (UINT32
)AsciiStrLen (Password
);
2065 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
2066 if (PasswordConfirm
== NULL
) {
2067 ZeroMem (OldPassword
, OldPasswordLen
);
2068 FreePool (OldPassword
);
2069 ZeroMem (Password
, PasswordLen
);
2070 FreePool (Password
);
2075 PasswordLenConfirm
= (UINT32
)AsciiStrLen (PasswordConfirm
);
2076 if ((PasswordLen
!= PasswordLenConfirm
) ||
2077 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0))
2079 ZeroMem (OldPassword
, OldPasswordLen
);
2080 FreePool (OldPassword
);
2081 ZeroMem (Password
, PasswordLen
);
2082 FreePool (Password
);
2083 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2084 FreePool (PasswordConfirm
);
2087 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2089 L
"Passwords are not the same.",
2090 L
"Press ENTER to retry",
2093 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2099 if (PasswordConfirm
!= NULL
) {
2100 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2101 FreePool (PasswordConfirm
);
2104 ZeroMem (&Session
, sizeof (Session
));
2105 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2106 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2107 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2108 Ret
= OpalUtilSetAdminPassword (
2115 if (Ret
== TcgResultSuccess
) {
2116 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2117 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2119 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2122 if (OldPassword
!= NULL
) {
2123 ZeroMem (OldPassword
, OldPasswordLen
);
2124 FreePool (OldPassword
);
2127 if (Password
!= NULL
) {
2128 ZeroMem (Password
, PasswordLen
);
2129 FreePool (Password
);
2132 if (Ret
== TcgResultSuccess
) {
2140 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2143 L
"Press ENTER to retry",
2146 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2149 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2152 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2154 L
"Opal password retry count exceeds the limit.",
2155 L
"Press ENTER to skip the request and continue boot",
2158 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2160 gST
->ConOut
->ClearScreen (gST
->ConOut
);
2165 Process OPAL request.
2167 @param[in] Dev The device which has OPAL request.
2171 ProcessOpalRequest (
2172 IN OPAL_DRIVER_DEVICE
*Dev
2176 OPAL_REQUEST_VARIABLE
*TempVariable
;
2177 OPAL_REQUEST_VARIABLE
*Variable
;
2179 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2180 UINTN DevicePathSizeInVariable
;
2181 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2182 UINTN DevicePathSize
;
2183 BOOLEAN KeepUserData
;
2185 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2187 if (mOpalRequestVariable
== NULL
) {
2188 Status
= GetVariable2 (
2189 OPAL_REQUEST_VARIABLE_NAME
,
2190 &gHiiSetupVariableGuid
,
2194 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2198 mOpalRequestVariable
= Variable
;
2199 mOpalRequestVariableSize
= VariableSize
;
2202 // Delete the OPAL request variable.
2204 Status
= gRT
->SetVariable (
2205 OPAL_REQUEST_VARIABLE_NAME
,
2206 (EFI_GUID
*)&gHiiSetupVariableGuid
,
2211 ASSERT_EFI_ERROR (Status
);
2213 Variable
= mOpalRequestVariable
;
2214 VariableSize
= mOpalRequestVariableSize
;
2218 // Process the OPAL requests.
2220 TempVariable
= Variable
;
2221 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2222 (VariableSize
>= TempVariable
->Length
) &&
2223 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
)))
2225 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*)((UINTN
)TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2226 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2227 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2228 DevicePathSize
= GetDevicePathSize (DevicePath
);
2229 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2230 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0))
2233 // Found the node for the OPAL device.
2235 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2236 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2239 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2240 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2243 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2244 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2247 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2248 KeepUserData
= (BOOLEAN
)TempVariable
->OpalRequest
.KeepUserData
;
2249 ProcessOpalRequestRevert (
2252 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2256 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2257 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2260 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2261 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2264 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2265 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2269 // Update Device ownership.
2270 // Later BlockSID command may block the update.
2272 OpalDiskUpdateOwnerShip (&Dev
->OpalDisk
);
2277 VariableSize
-= TempVariable
->Length
;
2278 TempVariable
= (OPAL_REQUEST_VARIABLE
*)((UINTN
)TempVariable
+ TempVariable
->Length
);
2281 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2285 Add new device to the global device list.
2287 @param Dev New create device.
2292 IN OPAL_DRIVER_DEVICE
*Dev
2295 OPAL_DRIVER_DEVICE
*TmpDev
;
2297 if (mOpalDriver
.DeviceList
== NULL
) {
2298 mOpalDriver
.DeviceList
= Dev
;
2300 TmpDev
= mOpalDriver
.DeviceList
;
2301 while (TmpDev
->Next
!= NULL
) {
2302 TmpDev
= TmpDev
->Next
;
2310 Remove one device in the global device list.
2312 @param Dev The device need to be removed.
2317 IN OPAL_DRIVER_DEVICE
*Dev
2320 OPAL_DRIVER_DEVICE
*TmpDev
;
2322 if (mOpalDriver
.DeviceList
== NULL
) {
2326 if (mOpalDriver
.DeviceList
== Dev
) {
2327 mOpalDriver
.DeviceList
= NULL
;
2331 TmpDev
= mOpalDriver
.DeviceList
;
2332 while (TmpDev
->Next
!= NULL
) {
2333 if (TmpDev
->Next
== Dev
) {
2334 TmpDev
->Next
= Dev
->Next
;
2341 Get current device count.
2343 @retval return the current created device count.
2352 OPAL_DRIVER_DEVICE
*TmpDev
;
2355 TmpDev
= mOpalDriver
.DeviceList
;
2357 while (TmpDev
!= NULL
) {
2359 TmpDev
= TmpDev
->Next
;
2366 Get devcie list info.
2368 @retval return the device list pointer.
2370 OPAL_DRIVER_DEVICE
*
2371 OpalDriverGetDeviceList (
2375 return mOpalDriver
.DeviceList
;
2379 Stop this Controller.
2381 @param Dev The device need to be stopped.
2385 OpalDriverStopDevice (
2386 OPAL_DRIVER_DEVICE
*Dev
2392 FreePool (Dev
->Name16
);
2395 // remove OPAL_DRIVER_DEVICE from the list
2396 // it updates the controllerList pointer
2401 // close protocols that were opened
2403 gBS
->CloseProtocol (
2405 &gEfiStorageSecurityCommandProtocolGuid
,
2406 gOpalDriverBinding
.DriverBindingHandle
,
2410 gBS
->CloseProtocol (
2412 &gEfiBlockIoProtocolGuid
,
2413 gOpalDriverBinding
.DriverBindingHandle
,
2421 Get devcie name through the component name protocol.
2423 @param[in] AllHandlesBuffer The handle buffer for current system.
2424 @param[in] NumAllHandles The number of handles for the handle buffer.
2425 @param[in] Dev The device which need to get name.
2426 @param[in] UseComp1 Whether use component name or name2 protocol.
2428 @retval TRUE Find the name for this device.
2429 @retval FALSE Not found the name for this device.
2432 OpalDriverGetDeviceNameByProtocol (
2433 EFI_HANDLE
*AllHandlesBuffer
,
2434 UINTN NumAllHandles
,
2435 OPAL_DRIVER_DEVICE
*Dev
,
2439 EFI_HANDLE
*ProtocolHandlesBuffer
;
2440 UINTN NumProtocolHandles
;
2442 EFI_COMPONENT_NAME2_PROTOCOL
*Cnp1_2
; // efi component name and componentName2 have same layout
2445 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
2448 EFI_HANDLE TmpHandle
;
2451 if ((Dev
== NULL
) || (AllHandlesBuffer
== NULL
) || (NumAllHandles
== 0)) {
2455 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2458 // Find all EFI_HANDLES with protocol
2460 Status
= gBS
->LocateHandleBuffer (
2464 &NumProtocolHandles
,
2465 &ProtocolHandlesBuffer
2467 if (EFI_ERROR (Status
)) {
2472 // Exit early if no supported devices
2474 if (NumProtocolHandles
== 0) {
2479 // Get printable name by iterating through all protocols
2480 // using the handle as the child, and iterate through all handles for the controller
2481 // exit loop early once found, if not found, then delete device
2482 // storage security protocol instances already exist, add them to internal list
2484 Status
= EFI_DEVICE_ERROR
;
2485 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2488 if (Dev
->Name16
!= NULL
) {
2492 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2494 Status
= gBS
->OpenProtocol (
2500 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2502 if (EFI_ERROR (Status
) || (Cnp1_2
== NULL
)) {
2507 // Use all handles array as controller handle
2509 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2510 Status
= Cnp1_2
->GetControllerName (
2512 AllHandlesBuffer
[Index2
],
2514 LANGUAGE_ISO_639_2_ENGLISH
,
2517 if (EFI_ERROR (Status
)) {
2518 Status
= Cnp1_2
->GetControllerName (
2520 AllHandlesBuffer
[Index2
],
2522 LANGUAGE_RFC_3066_ENGLISH
,
2527 if (!EFI_ERROR (Status
) && (DevName
!= NULL
)) {
2528 StrLength
= StrLen (DevName
) + 1; // Add one for NULL terminator
2529 Dev
->Name16
= AllocateZeroPool (StrLength
* sizeof (CHAR16
));
2530 ASSERT (Dev
->Name16
!= NULL
);
2531 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2532 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool (StrLength
);
2533 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2536 // Retrieve bridge BDF info and port number or namespace depending on type
2539 Status
= gBS
->OpenProtocol (
2541 &gEfiDevicePathProtocolGuid
,
2542 (VOID
**)&TmpDevPath
,
2545 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2547 if (!EFI_ERROR (Status
)) {
2548 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2552 if (Dev
->Name16
!= NULL
) {
2553 FreePool (Dev
->Name16
);
2557 if (Dev
->NameZ
!= NULL
) {
2558 FreePool (Dev
->NameZ
);
2569 Get devcie name through the component name protocol.
2571 @param[in] Dev The device which need to get name.
2573 @retval TRUE Find the name for this device.
2574 @retval FALSE Not found the name for this device.
2577 OpalDriverGetDriverDeviceName (
2578 OPAL_DRIVER_DEVICE
*Dev
2581 EFI_HANDLE
*AllHandlesBuffer
;
2582 UINTN NumAllHandles
;
2586 DEBUG ((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2591 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2593 if (Dev
->Name16
== NULL
) {
2594 DEBUG ((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2596 // Find all EFI_HANDLES
2598 Status
= gBS
->LocateHandleBuffer (
2605 if (EFI_ERROR (Status
)) {
2606 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2611 // Try component Name2
2613 if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2614 DEBUG ((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2615 if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2616 DEBUG ((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2626 Main entry for this driver.
2628 @param ImageHandle Image Handle this driver.
2629 @param SystemTable Pointer to SystemTable.
2631 @retval EFI_SUCCESS This function always complete successfully.
2635 EfiDriverEntryPoint (
2636 IN EFI_HANDLE ImageHandle
,
2637 IN EFI_SYSTEM_TABLE
*SystemTable
2641 EFI_EVENT EndOfDxeEvent
;
2643 Status
= EfiLibInstallDriverBindingComponentName2 (
2646 &gOpalDriverBinding
,
2648 &gOpalComponentName
,
2649 &gOpalComponentName2
2652 if (EFI_ERROR (Status
)) {
2653 DEBUG ((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2658 // Initialize Driver object
2660 ZeroMem (&mOpalDriver
, sizeof (mOpalDriver
));
2661 mOpalDriver
.Handle
= ImageHandle
;
2663 Status
= gBS
->CreateEventEx (
2666 OpalEndOfDxeEventNotify
,
2668 &gEfiEndOfDxeEventGroupGuid
,
2671 ASSERT_EFI_ERROR (Status
);
2674 // Install Hii packages.
2682 Tests to see if this driver supports a given controller.
2684 This function checks to see if the controller contains an instance of the
2685 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCOL
2686 and returns EFI_SUCCESS if it does.
2688 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2689 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2690 must support a protocol interface that supplies
2691 an I/O abstraction to the driver.
2692 @param[in] RemainingDevicePath This parameter is ignored.
2694 @retval EFI_SUCCESS The device contains required protocols
2695 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2696 RemainingDevicePath is already being managed by the driver
2698 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2699 RemainingDevicePath is already being managed by a different
2700 driver or an application that requires exclusive access.
2701 Currently not implemented.
2702 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2707 OpalEfiDriverBindingSupported (
2708 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2709 IN EFI_HANDLE Controller
,
2710 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
2714 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*SecurityCommand
;
2716 if (mOpalEndOfDxe
) {
2717 return EFI_UNSUPPORTED
;
2721 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2723 Status
= gBS
->OpenProtocol (
2725 &gEfiStorageSecurityCommandProtocolGuid
,
2726 (VOID
**)&SecurityCommand
,
2727 This
->DriverBindingHandle
,
2729 EFI_OPEN_PROTOCOL_BY_DRIVER
2732 if (Status
== EFI_ALREADY_STARTED
) {
2736 if (EFI_ERROR (Status
)) {
2741 // Close protocol and reopen in Start call
2743 gBS
->CloseProtocol (
2745 &gEfiStorageSecurityCommandProtocolGuid
,
2746 This
->DriverBindingHandle
,
2754 Enables Opal Management on a supported device if available.
2756 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2757 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2758 This function will complete the other necessary checks, such as verifying the device supports
2759 the correct version of Opal. Upon verification, it will add the device to the
2760 Opal HII list in order to expose Opal management options.
2762 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2763 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2764 must support a protocol interface that supplies
2765 an I/O abstraction to the driver.
2766 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2767 parameter is ignored by device drivers, and is optional for bus
2768 drivers. For a bus driver, if this parameter is NULL, then handles
2769 for all the children of Controller are created by this driver.
2770 If this parameter is not NULL and the first Device Path Node is
2771 not the End of Device Path Node, then only the Handle for the
2772 child device specified by the first Device Path Node of
2773 RemainingDevicePath is created by this driver.
2774 If the first Device Path Node of RemainingDevicePath is
2775 the End of Device Path Node, no child Handle is created by this
2778 @retval EFI_SUCCESS Opal management was enabled.
2779 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2780 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2781 @retval Others The driver failed to start the device.
2786 OpalEfiDriverBindingStart (
2787 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2788 IN EFI_HANDLE Controller
,
2789 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
2793 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2794 OPAL_DRIVER_DEVICE
*Dev
;
2795 OPAL_DRIVER_DEVICE
*Itr
;
2798 Itr
= mOpalDriver
.DeviceList
;
2799 while (Itr
!= NULL
) {
2800 if (Controller
== Itr
->Handle
) {
2808 // Create internal device for tracking. This allows all disks to be tracked
2811 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool (sizeof (OPAL_DRIVER_DEVICE
));
2813 return EFI_OUT_OF_RESOURCES
;
2816 Dev
->Handle
= Controller
;
2819 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2821 Status
= gBS
->OpenProtocol (
2823 &gEfiStorageSecurityCommandProtocolGuid
,
2824 (VOID
**)&Dev
->Sscp
,
2825 This
->DriverBindingHandle
,
2827 EFI_OPEN_PROTOCOL_BY_DRIVER
2829 if (EFI_ERROR (Status
)) {
2835 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2838 Status
= gBS
->OpenProtocol (
2840 &gEfiBlockIoProtocolGuid
,
2842 This
->DriverBindingHandle
,
2844 EFI_OPEN_PROTOCOL_BY_DRIVER
2846 if (EFI_ERROR (Status
)) {
2848 // Block_IO not supported on handle
2850 if (Status
== EFI_UNSUPPORTED
) {
2854 // Close storage security that was opened
2856 gBS
->CloseProtocol (
2858 &gEfiStorageSecurityCommandProtocolGuid
,
2859 This
->DriverBindingHandle
,
2871 if (BlkIo
== NULL
) {
2872 // If no Block IO present, use defined MediaId value.
2875 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2877 gBS
->CloseProtocol (
2879 &gEfiBlockIoProtocolGuid
,
2880 This
->DriverBindingHandle
,
2886 // Acquire Ascii printable name of child, if not found, then ignore device
2888 Result
= OpalDriverGetDriverDeviceName (Dev
);
2893 Status
= OpalDiskInitialize (Dev
);
2894 if (EFI_ERROR (Status
)) {
2898 AddDeviceToTail (Dev
);
2901 // Check if device is locked and prompt for password.
2903 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2906 // Process OPAL request from last boot.
2908 ProcessOpalRequest (Dev
);
2914 // free device, close protocols and exit
2916 gBS
->CloseProtocol (
2918 &gEfiStorageSecurityCommandProtocolGuid
,
2919 This
->DriverBindingHandle
,
2925 return EFI_DEVICE_ERROR
;
2929 Stop this driver on Controller.
2931 @param This Protocol instance pointer.
2932 @param Controller Handle of device to stop driver on
2933 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2934 children is zero stop the entire bus driver.
2935 @param ChildHandleBuffer List of Child Handles to Stop.
2937 @retval EFI_SUCCESS This driver is removed Controller.
2938 @retval other This driver could not be removed from this device.
2943 OpalEfiDriverBindingStop (
2944 EFI_DRIVER_BINDING_PROTOCOL
*This
,
2945 EFI_HANDLE Controller
,
2946 UINTN NumberOfChildren
,
2947 EFI_HANDLE
*ChildHandleBuffer
2950 OPAL_DRIVER_DEVICE
*Itr
;
2952 Itr
= mOpalDriver
.DeviceList
;
2955 // does Controller match any of the devices we are managing for Opal
2957 while (Itr
!= NULL
) {
2958 if (Itr
->Handle
== Controller
) {
2959 OpalDriverStopDevice (Itr
);
2966 return EFI_NOT_FOUND
;
2970 Unloads UEFI Driver. Very useful for debugging and testing.
2972 @param ImageHandle Image Handle this driver.
2974 @retval EFI_SUCCESS This function always complete successfully.
2975 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2979 OpalEfiDriverUnload (
2980 IN EFI_HANDLE ImageHandle
2984 OPAL_DRIVER_DEVICE
*Itr
;
2986 Status
= EFI_SUCCESS
;
2988 if (ImageHandle
!= gImageHandle
) {
2989 return (EFI_INVALID_PARAMETER
);
2993 // Uninstall any interface added to each device by us
2995 while (mOpalDriver
.DeviceList
) {
2996 Itr
= mOpalDriver
.DeviceList
;
2998 // Remove OPAL_DRIVER_DEVICE from the list
2999 // it updates the controllerList pointer
3001 OpalDriverStopDevice (Itr
);
3005 // Uninstall the HII capability
3007 Status
= HiiUninstall ();