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
);
903 // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.
904 // Due to board design, device may not power off during system warm boot, which result in
905 // security status remain unlocked status, hence we add device security status check here.
907 // If device is in the locked status, device keeps locked and system continues booting.
908 // If device is in the unlocked status, system is forced shutdown to support security requirement.
910 if (PcdGetBool (PcdSkipOpalPasswordPrompt
)) {
914 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
918 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
919 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
923 // Current device in the lock status and
924 // User not input password and press ESC,
925 // keep device in lock status and continue boot.
929 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
931 L
"Press ENTER to skip the request and continue boot,",
932 L
"Press ESC to input password again",
935 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
937 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
938 gST
->ConOut
->ClearScreen(gST
->ConOut
);
940 // Keep lock and continue boot.
945 // Let user input password again.
951 // Current device in the unlock status and
952 // User not input password and press ESC,
953 // Shutdown the device.
957 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
959 L
"Press ENTER to shutdown, Press ESC to input password again",
962 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
964 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
965 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
968 // Let user input password again.
975 if (Password
== NULL
) {
979 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
982 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
984 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
985 if (Ret
== TcgResultSuccess
) {
986 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
990 if (Ret
== TcgResultSuccess
) {
991 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
992 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
994 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
997 if (Password
!= NULL
) {
998 ZeroMem (Password
, PasswordLen
);
1002 if (Ret
== TcgResultSuccess
) {
1007 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
1008 // before accept new password.
1010 if (Ret
== TcgResultFailureInvalidType
) {
1011 Count
= MAX_PASSWORD_TRY_COUNT
;
1019 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1021 L
"Invalid password.",
1022 L
"Press ENTER to retry",
1025 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1028 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1031 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1033 L
"Opal password retry count exceeds the limit. Must shutdown!",
1034 L
"Press ENTER to shutdown",
1037 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1039 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1045 Process Enable Feature OPAL request.
1047 @param[in] Dev The device which has Enable Feature OPAL request.
1048 @param[in] RequestString Request string.
1052 ProcessOpalRequestEnableFeature (
1053 IN OPAL_DRIVER_DEVICE
*Dev
,
1054 IN CHAR16
*RequestString
1060 CHAR8
*PasswordConfirm
;
1061 UINT32 PasswordLenConfirm
;
1062 OPAL_SESSION Session
;
1066 CHAR16
*PopUpString
;
1072 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1074 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1078 ZeroMem(&Session
, sizeof(Session
));
1079 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1080 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1081 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1083 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1084 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1088 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1090 L
"Press ENTER to skip the request and continue boot,",
1091 L
"Press ESC to input password again",
1094 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1096 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1097 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1101 // Let user input password again.
1107 if (Password
== NULL
) {
1111 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1113 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1114 if (PasswordConfirm
== NULL
) {
1115 ZeroMem (Password
, PasswordLen
);
1116 FreePool (Password
);
1120 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1121 if ((PasswordLen
!= PasswordLenConfirm
) ||
1122 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1123 ZeroMem (Password
, PasswordLen
);
1124 FreePool (Password
);
1125 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1126 FreePool (PasswordConfirm
);
1129 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1131 L
"Passwords are not the same.",
1132 L
"Press ENTER to retry",
1135 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1140 if (PasswordConfirm
!= NULL
) {
1141 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1142 FreePool (PasswordConfirm
);
1145 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1146 if (Ret
== TcgResultSuccess
) {
1147 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1148 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1150 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1153 if (Password
!= NULL
) {
1154 ZeroMem (Password
, PasswordLen
);
1155 FreePool (Password
);
1158 if (Ret
== TcgResultSuccess
) {
1166 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1169 L
"Press ENTER to retry",
1172 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1175 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1178 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1180 L
"Opal password retry count exceeds the limit.",
1181 L
"Press ENTER to skip the request and continue boot",
1184 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1185 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1190 Process Disable User OPAL request.
1192 @param[in] Dev The device which has Disable User OPAL request.
1193 @param[in] RequestString Request string.
1197 ProcessOpalRequestDisableUser (
1198 IN OPAL_DRIVER_DEVICE
*Dev
,
1199 IN CHAR16
*RequestString
1205 OPAL_SESSION Session
;
1209 BOOLEAN PasswordFailed
;
1210 CHAR16
*PopUpString
;
1216 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1218 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1222 ZeroMem(&Session
, sizeof(Session
));
1223 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1224 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1225 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1227 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1228 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
1232 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1234 L
"Press ENTER to skip the request and continue boot,",
1235 L
"Press ESC to input password again",
1238 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1240 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1241 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1245 // Let user input password again.
1251 if (Password
== NULL
) {
1255 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1257 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1258 if (Ret
== TcgResultSuccess
) {
1259 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1260 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1262 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1265 if (Password
!= NULL
) {
1266 ZeroMem (Password
, PasswordLen
);
1267 FreePool (Password
);
1270 if (Ret
== TcgResultSuccess
) {
1278 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1280 L
"Invalid password, request failed.",
1281 L
"Press ENTER to retry",
1284 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1287 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1290 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1292 L
"Opal password retry count exceeds the limit.",
1293 L
"Press ENTER to skip the request and continue boot",
1296 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1297 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1302 Process Psid Revert OPAL request.
1304 @param[in] Dev The device which has Psid Revert OPAL request.
1305 @param[in] RequestString Request string.
1309 ProcessOpalRequestPsidRevert (
1310 IN OPAL_DRIVER_DEVICE
*Dev
,
1311 IN CHAR16
*RequestString
1317 OPAL_SESSION Session
;
1321 CHAR16
*PopUpString
;
1322 CHAR16
*PopUpString2
;
1323 CHAR16
*PopUpString3
;
1330 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1332 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1334 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1335 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1336 PopUpString2
= AllocateZeroPool (BufferSize
);
1337 ASSERT (PopUpString2
!= NULL
);
1341 L
"WARNING: Revert action will take about %d seconds",
1342 Dev
->OpalDisk
.EstimateTimeCost
1344 PopUpString3
= L
"DO NOT power off system during the revert action!";
1346 PopUpString2
= NULL
;
1347 PopUpString3
= NULL
;
1352 ZeroMem(&Session
, sizeof(Session
));
1353 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1354 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1355 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1357 while (Count
< MAX_PSID_TRY_COUNT
) {
1358 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1362 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1364 L
"Press ENTER to skip the request and continue boot,",
1365 L
"Press ESC to input Psid again",
1368 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1370 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1371 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1375 // Let user input Psid again.
1385 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1387 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1388 if (Ret
== TcgResultSuccess
) {
1389 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1391 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1395 ZeroMem (Psid
, PsidLen
);
1399 if (Ret
== TcgResultSuccess
) {
1407 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1409 L
"Invalid Psid, request failed.",
1410 L
"Press ENTER to retry",
1413 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1416 if (Count
>= MAX_PSID_TRY_COUNT
) {
1419 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1421 L
"Opal Psid retry count exceeds the limit.",
1422 L
"Press ENTER to skip the request and continue boot",
1425 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1426 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1430 if (PopUpString2
!= NULL
) {
1431 FreePool (PopUpString2
);
1436 Process Admin Revert OPAL request.
1438 @param[in] Dev The device which has Revert OPAL request.
1439 @param[in] KeepUserData Whether to keep user data or not.
1440 @param[in] RequestString Request string.
1444 ProcessOpalRequestRevert (
1445 IN OPAL_DRIVER_DEVICE
*Dev
,
1446 IN BOOLEAN KeepUserData
,
1447 IN CHAR16
*RequestString
1453 OPAL_SESSION Session
;
1457 BOOLEAN PasswordFailed
;
1458 CHAR16
*PopUpString
;
1459 CHAR16
*PopUpString2
;
1460 CHAR16
*PopUpString3
;
1467 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1469 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1471 if ((!KeepUserData
) &&
1472 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1473 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1474 PopUpString2
= AllocateZeroPool (BufferSize
);
1475 ASSERT (PopUpString2
!= NULL
);
1479 L
"WARNING: Revert action will take about %d seconds",
1480 Dev
->OpalDisk
.EstimateTimeCost
1482 PopUpString3
= L
"DO NOT power off system during the revert action!";
1484 PopUpString2
= NULL
;
1485 PopUpString3
= NULL
;
1490 ZeroMem(&Session
, sizeof(Session
));
1491 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1492 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1493 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1495 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1496 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1500 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1502 L
"Press ENTER to skip the request and continue boot,",
1503 L
"Press ESC to input password again",
1506 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1508 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1509 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1513 // Let user input password again.
1519 if (Password
== NULL
) {
1523 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1525 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1526 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1528 // For pyrite type device which does not support media encryption,
1529 // it does not accept "Keep User Data" parameter.
1530 // So here hardcode a FALSE for this case.
1532 Ret
= OpalUtilRevert(
1539 Dev
->OpalDisk
.MsidLength
1542 Ret
= OpalUtilRevert(
1549 Dev
->OpalDisk
.MsidLength
1552 if (Ret
== TcgResultSuccess
) {
1553 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1554 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1556 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1559 if (Password
!= NULL
) {
1560 ZeroMem (Password
, PasswordLen
);
1561 FreePool (Password
);
1564 if (Ret
== TcgResultSuccess
) {
1572 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1574 L
"Invalid password, request failed.",
1575 L
"Press ENTER to retry",
1578 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1581 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1584 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1586 L
"Opal password retry count exceeds the limit.",
1587 L
"Press ENTER to skip the request and continue boot",
1590 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1591 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1595 if (PopUpString2
!= NULL
) {
1596 FreePool (PopUpString2
);
1601 Process Secure Erase OPAL request.
1603 @param[in] Dev The device which has Secure Erase OPAL request.
1604 @param[in] RequestString Request string.
1608 ProcessOpalRequestSecureErase (
1609 IN OPAL_DRIVER_DEVICE
*Dev
,
1610 IN CHAR16
*RequestString
1616 OPAL_SESSION Session
;
1620 BOOLEAN PasswordFailed
;
1621 CHAR16
*PopUpString
;
1622 CHAR16
*PopUpString2
;
1623 CHAR16
*PopUpString3
;
1630 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1632 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1634 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1635 BufferSize
= StrSize (L
"Warning: Secure erase action will take about ####### seconds");
1636 PopUpString2
= AllocateZeroPool (BufferSize
);
1637 ASSERT (PopUpString2
!= NULL
);
1641 L
"WARNING: Secure erase action will take about %d seconds",
1642 Dev
->OpalDisk
.EstimateTimeCost
1644 PopUpString3
= L
"DO NOT power off system during the action!";
1646 PopUpString2
= NULL
;
1647 PopUpString3
= NULL
;
1651 ZeroMem(&Session
, sizeof(Session
));
1652 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1653 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1654 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1656 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1657 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1661 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1663 L
"Press ENTER to skip the request and continue boot,",
1664 L
"Press ESC to input password again",
1667 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1669 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1670 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1674 // Let user input password again.
1680 if (Password
== NULL
) {
1684 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1686 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1687 if (Ret
== TcgResultSuccess
) {
1688 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1689 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1691 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1694 if (Password
!= NULL
) {
1695 ZeroMem (Password
, PasswordLen
);
1696 FreePool (Password
);
1699 if (Ret
== TcgResultSuccess
) {
1707 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1709 L
"Invalid password, request failed.",
1710 L
"Press ENTER to retry",
1713 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1716 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1719 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1721 L
"Opal password retry count exceeds the limit.",
1722 L
"Press ENTER to skip the request and continue boot",
1725 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1726 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1730 if (PopUpString2
!= NULL
) {
1731 FreePool (PopUpString2
);
1736 Process Set Admin Pwd OPAL request.
1738 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1739 @param[in] RequestString Request string.
1743 ProcessOpalRequestSetUserPwd (
1744 IN OPAL_DRIVER_DEVICE
*Dev
,
1745 IN CHAR16
*RequestString
1750 UINT32 OldPasswordLen
;
1753 CHAR8
*PasswordConfirm
;
1754 UINT32 PasswordLenConfirm
;
1755 OPAL_SESSION Session
;
1759 CHAR16
*PopUpString
;
1765 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1767 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1771 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1772 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1776 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1778 L
"Press ENTER to skip the request and continue boot,",
1779 L
"Press ESC to input password again",
1782 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1784 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1785 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1789 // Let user input password again.
1795 if (OldPassword
== NULL
) {
1799 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1801 ZeroMem(&Session
, sizeof(Session
));
1802 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1803 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1804 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1805 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1806 if (Ret
== TcgResultSuccess
) {
1807 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1809 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1810 if (Ret
== TcgResultSuccess
) {
1811 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1813 ZeroMem (OldPassword
, OldPasswordLen
);
1814 FreePool (OldPassword
);
1815 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1818 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1820 L
"Incorrect password.",
1821 L
"Press ENTER to retry",
1824 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1830 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1831 if (Password
== NULL
) {
1832 ZeroMem (OldPassword
, OldPasswordLen
);
1833 FreePool (OldPassword
);
1837 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1839 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1840 if (PasswordConfirm
== NULL
) {
1841 ZeroMem (OldPassword
, OldPasswordLen
);
1842 FreePool (OldPassword
);
1843 ZeroMem (Password
, PasswordLen
);
1844 FreePool (Password
);
1848 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1849 if ((PasswordLen
!= PasswordLenConfirm
) ||
1850 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1851 ZeroMem (OldPassword
, OldPasswordLen
);
1852 FreePool (OldPassword
);
1853 ZeroMem (Password
, PasswordLen
);
1854 FreePool (Password
);
1855 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1856 FreePool (PasswordConfirm
);
1859 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1861 L
"Passwords are not the same.",
1862 L
"Press ENTER to retry",
1865 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1870 if (PasswordConfirm
!= NULL
) {
1871 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1872 FreePool (PasswordConfirm
);
1875 ZeroMem(&Session
, sizeof(Session
));
1876 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1877 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1878 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1879 Ret
= OpalUtilSetUserPassword(
1886 if (Ret
== TcgResultSuccess
) {
1887 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1888 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1890 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1893 if (OldPassword
!= NULL
) {
1894 ZeroMem (OldPassword
, OldPasswordLen
);
1895 FreePool (OldPassword
);
1898 if (Password
!= NULL
) {
1899 ZeroMem (Password
, PasswordLen
);
1900 FreePool (Password
);
1903 if (Ret
== TcgResultSuccess
) {
1911 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1914 L
"Press ENTER to retry",
1917 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1920 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1923 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1925 L
"Opal password retry count exceeds the limit.",
1926 L
"Press ENTER to skip the request and continue boot",
1929 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1930 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1935 Process Set Admin Pwd OPAL request.
1937 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1938 @param[in] RequestString Request string.
1942 ProcessOpalRequestSetAdminPwd (
1943 IN OPAL_DRIVER_DEVICE
*Dev
,
1944 IN CHAR16
*RequestString
1949 UINT32 OldPasswordLen
;
1952 CHAR8
*PasswordConfirm
;
1953 UINT32 PasswordLenConfirm
;
1954 OPAL_SESSION Session
;
1958 CHAR16
*PopUpString
;
1964 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1966 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1970 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1971 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1975 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1977 L
"Press ENTER to skip the request and continue boot,",
1978 L
"Press ESC to input password again",
1981 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1983 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1984 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1988 // Let user input password again.
1994 if (OldPassword
== NULL
) {
1998 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
2000 ZeroMem(&Session
, sizeof(Session
));
2001 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2002 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2003 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2004 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2005 if (Ret
== TcgResultSuccess
) {
2006 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2008 ZeroMem (OldPassword
, OldPasswordLen
);
2009 FreePool (OldPassword
);
2010 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2013 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2015 L
"Incorrect password.",
2016 L
"Press ENTER to retry",
2019 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2024 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
2025 if (Password
== NULL
) {
2026 ZeroMem (OldPassword
, OldPasswordLen
);
2027 FreePool (OldPassword
);
2031 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2033 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
2034 if (PasswordConfirm
== NULL
) {
2035 ZeroMem (OldPassword
, OldPasswordLen
);
2036 FreePool (OldPassword
);
2037 ZeroMem (Password
, PasswordLen
);
2038 FreePool (Password
);
2042 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2043 if ((PasswordLen
!= PasswordLenConfirm
) ||
2044 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2045 ZeroMem (OldPassword
, OldPasswordLen
);
2046 FreePool (OldPassword
);
2047 ZeroMem (Password
, PasswordLen
);
2048 FreePool (Password
);
2049 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2050 FreePool (PasswordConfirm
);
2053 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2055 L
"Passwords are not the same.",
2056 L
"Press ENTER to retry",
2059 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2064 if (PasswordConfirm
!= NULL
) {
2065 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2066 FreePool (PasswordConfirm
);
2070 ZeroMem(&Session
, sizeof(Session
));
2071 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2072 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2073 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2074 Ret
= OpalUtilSetAdminPassword(
2081 if (Ret
== TcgResultSuccess
) {
2082 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2083 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2085 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2088 if (OldPassword
!= NULL
) {
2089 ZeroMem (OldPassword
, OldPasswordLen
);
2090 FreePool (OldPassword
);
2093 if (Password
!= NULL
) {
2094 ZeroMem (Password
, PasswordLen
);
2095 FreePool (Password
);
2098 if (Ret
== TcgResultSuccess
) {
2106 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2109 L
"Press ENTER to retry",
2112 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2115 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2118 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2120 L
"Opal password retry count exceeds the limit.",
2121 L
"Press ENTER to skip the request and continue boot",
2124 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2125 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2130 Process OPAL request.
2132 @param[in] Dev The device which has OPAL request.
2136 ProcessOpalRequest (
2137 IN OPAL_DRIVER_DEVICE
*Dev
2141 OPAL_REQUEST_VARIABLE
*TempVariable
;
2142 OPAL_REQUEST_VARIABLE
*Variable
;
2144 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2145 UINTN DevicePathSizeInVariable
;
2146 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2147 UINTN DevicePathSize
;
2148 BOOLEAN KeepUserData
;
2150 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2152 if (mOpalRequestVariable
== NULL
) {
2153 Status
= GetVariable2 (
2154 OPAL_REQUEST_VARIABLE_NAME
,
2155 &gHiiSetupVariableGuid
,
2156 (VOID
**) &Variable
,
2159 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2162 mOpalRequestVariable
= Variable
;
2163 mOpalRequestVariableSize
= VariableSize
;
2166 // Delete the OPAL request variable.
2168 Status
= gRT
->SetVariable (
2169 OPAL_REQUEST_VARIABLE_NAME
,
2170 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2175 ASSERT_EFI_ERROR (Status
);
2177 Variable
= mOpalRequestVariable
;
2178 VariableSize
= mOpalRequestVariableSize
;
2182 // Process the OPAL requests.
2184 TempVariable
= Variable
;
2185 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2186 (VariableSize
>= TempVariable
->Length
) &&
2187 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2188 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2189 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2190 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2191 DevicePathSize
= GetDevicePathSize (DevicePath
);
2192 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2193 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2195 // Found the node for the OPAL device.
2197 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2198 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2200 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2201 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2203 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2204 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2206 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2207 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2208 ProcessOpalRequestRevert (
2211 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2214 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2215 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2217 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2218 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2220 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2221 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2225 // Update Device ownership.
2226 // Later BlockSID command may block the update.
2228 OpalDiskUpdateOwnerShip (&Dev
->OpalDisk
);
2233 VariableSize
-= TempVariable
->Length
;
2234 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2237 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2241 Add new device to the global device list.
2243 @param Dev New create device.
2248 IN OPAL_DRIVER_DEVICE
*Dev
2251 OPAL_DRIVER_DEVICE
*TmpDev
;
2253 if (mOpalDriver
.DeviceList
== NULL
) {
2254 mOpalDriver
.DeviceList
= Dev
;
2256 TmpDev
= mOpalDriver
.DeviceList
;
2257 while (TmpDev
->Next
!= NULL
) {
2258 TmpDev
= TmpDev
->Next
;
2266 Remove one device in the global device list.
2268 @param Dev The device need to be removed.
2273 IN OPAL_DRIVER_DEVICE
*Dev
2276 OPAL_DRIVER_DEVICE
*TmpDev
;
2278 if (mOpalDriver
.DeviceList
== NULL
) {
2282 if (mOpalDriver
.DeviceList
== Dev
) {
2283 mOpalDriver
.DeviceList
= NULL
;
2287 TmpDev
= mOpalDriver
.DeviceList
;
2288 while (TmpDev
->Next
!= NULL
) {
2289 if (TmpDev
->Next
== Dev
) {
2290 TmpDev
->Next
= Dev
->Next
;
2297 Get current device count.
2299 @retval return the current created device count.
2308 OPAL_DRIVER_DEVICE
*TmpDev
;
2311 TmpDev
= mOpalDriver
.DeviceList
;
2313 while (TmpDev
!= NULL
) {
2315 TmpDev
= TmpDev
->Next
;
2322 Get devcie list info.
2324 @retval return the device list pointer.
2327 OpalDriverGetDeviceList(
2331 return mOpalDriver
.DeviceList
;
2335 Stop this Controller.
2337 @param Dev The device need to be stopped.
2341 OpalDriverStopDevice (
2342 OPAL_DRIVER_DEVICE
*Dev
2348 FreePool(Dev
->Name16
);
2351 // remove OPAL_DRIVER_DEVICE from the list
2352 // it updates the controllerList pointer
2357 // close protocols that were opened
2361 &gEfiStorageSecurityCommandProtocolGuid
,
2362 gOpalDriverBinding
.DriverBindingHandle
,
2368 &gEfiBlockIoProtocolGuid
,
2369 gOpalDriverBinding
.DriverBindingHandle
,
2377 Get devcie name through the component name protocol.
2379 @param[in] AllHandlesBuffer The handle buffer for current system.
2380 @param[in] NumAllHandles The number of handles for the handle buffer.
2381 @param[in] Dev The device which need to get name.
2382 @param[in] UseComp1 Whether use component name or name2 protocol.
2384 @retval TRUE Find the name for this device.
2385 @retval FALSE Not found the name for this device.
2388 OpalDriverGetDeviceNameByProtocol(
2389 EFI_HANDLE
*AllHandlesBuffer
,
2390 UINTN NumAllHandles
,
2391 OPAL_DRIVER_DEVICE
*Dev
,
2395 EFI_HANDLE
* ProtocolHandlesBuffer
;
2396 UINTN NumProtocolHandles
;
2398 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2401 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2404 EFI_HANDLE TmpHandle
;
2407 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2411 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2414 // Find all EFI_HANDLES with protocol
2416 Status
= gBS
->LocateHandleBuffer(
2420 &NumProtocolHandles
,
2421 &ProtocolHandlesBuffer
2423 if (EFI_ERROR(Status
)) {
2429 // Exit early if no supported devices
2431 if (NumProtocolHandles
== 0) {
2436 // Get printable name by iterating through all protocols
2437 // using the handle as the child, and iterate through all handles for the controller
2438 // exit loop early once found, if not found, then delete device
2439 // storage security protocol instances already exist, add them to internal list
2441 Status
= EFI_DEVICE_ERROR
;
2442 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2445 if (Dev
->Name16
!= NULL
) {
2449 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2451 Status
= gBS
->OpenProtocol(
2457 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2459 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2464 // Use all handles array as controller handle
2466 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2467 Status
= Cnp1_2
->GetControllerName(
2469 AllHandlesBuffer
[Index2
],
2471 LANGUAGE_ISO_639_2_ENGLISH
,
2474 if (EFI_ERROR(Status
)) {
2475 Status
= Cnp1_2
->GetControllerName(
2477 AllHandlesBuffer
[Index2
],
2479 LANGUAGE_RFC_3066_ENGLISH
,
2483 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2484 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2485 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2486 ASSERT (Dev
->Name16
!= NULL
);
2487 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2488 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2489 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2492 // Retrieve bridge BDF info and port number or namespace depending on type
2495 Status
= gBS
->OpenProtocol(
2497 &gEfiDevicePathProtocolGuid
,
2498 (VOID
**)&TmpDevPath
,
2501 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2503 if (!EFI_ERROR(Status
)) {
2504 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2508 if (Dev
->Name16
!= NULL
) {
2509 FreePool(Dev
->Name16
);
2512 if (Dev
->NameZ
!= NULL
) {
2513 FreePool(Dev
->NameZ
);
2524 Get devcie name through the component name protocol.
2526 @param[in] Dev The device which need to get name.
2528 @retval TRUE Find the name for this device.
2529 @retval FALSE Not found the name for this device.
2532 OpalDriverGetDriverDeviceName(
2533 OPAL_DRIVER_DEVICE
*Dev
2536 EFI_HANDLE
* AllHandlesBuffer
;
2537 UINTN NumAllHandles
;
2541 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2546 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2548 if (Dev
->Name16
== NULL
) {
2549 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2551 // Find all EFI_HANDLES
2553 Status
= gBS
->LocateHandleBuffer(
2560 if (EFI_ERROR(Status
)) {
2561 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2566 // Try component Name2
2568 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2569 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2570 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2571 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2581 Main entry for this driver.
2583 @param ImageHandle Image Handle this driver.
2584 @param SystemTable Pointer to SystemTable.
2586 @retval EFI_SUCCESS This function always complete successfully.
2590 EfiDriverEntryPoint(
2591 IN EFI_HANDLE ImageHandle
,
2592 IN EFI_SYSTEM_TABLE
* SystemTable
2596 EFI_EVENT EndOfDxeEvent
;
2598 Status
= EfiLibInstallDriverBindingComponentName2 (
2601 &gOpalDriverBinding
,
2603 &gOpalComponentName
,
2604 &gOpalComponentName2
2607 if (EFI_ERROR(Status
)) {
2608 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2613 // Initialize Driver object
2615 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2616 mOpalDriver
.Handle
= ImageHandle
;
2618 Status
= gBS
->CreateEventEx (
2621 OpalEndOfDxeEventNotify
,
2623 &gEfiEndOfDxeEventGroupGuid
,
2626 ASSERT_EFI_ERROR (Status
);
2629 // Install Hii packages.
2637 Tests to see if this driver supports a given controller.
2639 This function checks to see if the controller contains an instance of the
2640 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCOL
2641 and returns EFI_SUCCESS if it does.
2643 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2644 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2645 must support a protocol interface that supplies
2646 an I/O abstraction to the driver.
2647 @param[in] RemainingDevicePath This parameter is ignored.
2649 @retval EFI_SUCCESS The device contains required protocols
2650 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2651 RemainingDevicePath is already being managed by the driver
2653 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2654 RemainingDevicePath is already being managed by a different
2655 driver or an application that requires exclusive access.
2656 Currently not implemented.
2657 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2662 OpalEfiDriverBindingSupported(
2663 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2664 IN EFI_HANDLE Controller
,
2665 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2669 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2670 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2672 if (mOpalEndOfDxe
) {
2673 return EFI_UNSUPPORTED
;
2677 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2679 Status
= gBS
->OpenProtocol(
2681 &gEfiStorageSecurityCommandProtocolGuid
,
2682 ( VOID
** )&SecurityCommand
,
2683 This
->DriverBindingHandle
,
2685 EFI_OPEN_PROTOCOL_BY_DRIVER
2688 if (Status
== EFI_ALREADY_STARTED
) {
2692 if (EFI_ERROR(Status
)) {
2697 // Close protocol and reopen in Start call
2701 &gEfiStorageSecurityCommandProtocolGuid
,
2702 This
->DriverBindingHandle
,
2707 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2710 Status
= gBS
->OpenProtocol(
2712 &gEfiBlockIoProtocolGuid
,
2714 This
->DriverBindingHandle
,
2716 EFI_OPEN_PROTOCOL_BY_DRIVER
2719 if (EFI_ERROR(Status
)) {
2720 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2725 // Close protocol and reopen in Start call
2729 &gEfiBlockIoProtocolGuid
,
2730 This
->DriverBindingHandle
,
2738 Enables Opal Management on a supported device if available.
2740 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2741 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2742 This function will complete the other necessary checks, such as verifying the device supports
2743 the correct version of Opal. Upon verification, it will add the device to the
2744 Opal HII list in order to expose Opal management options.
2746 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2747 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2748 must support a protocol interface that supplies
2749 an I/O abstraction to the driver.
2750 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2751 parameter is ignored by device drivers, and is optional for bus
2752 drivers. For a bus driver, if this parameter is NULL, then handles
2753 for all the children of Controller are created by this driver.
2754 If this parameter is not NULL and the first Device Path Node is
2755 not the End of Device Path Node, then only the Handle for the
2756 child device specified by the first Device Path Node of
2757 RemainingDevicePath is created by this driver.
2758 If the first Device Path Node of RemainingDevicePath is
2759 the End of Device Path Node, no child Handle is created by this
2762 @retval EFI_SUCCESS Opal management was enabled.
2763 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2764 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2765 @retval Others The driver failed to start the device.
2770 OpalEfiDriverBindingStart(
2771 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2772 IN EFI_HANDLE Controller
,
2773 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2777 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2778 OPAL_DRIVER_DEVICE
*Dev
;
2779 OPAL_DRIVER_DEVICE
*Itr
;
2782 Itr
= mOpalDriver
.DeviceList
;
2783 while (Itr
!= NULL
) {
2784 if (Controller
== Itr
->Handle
) {
2791 // Create internal device for tracking. This allows all disks to be tracked
2794 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2796 return EFI_OUT_OF_RESOURCES
;
2798 Dev
->Handle
= Controller
;
2801 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2803 Status
= gBS
->OpenProtocol(
2805 &gEfiStorageSecurityCommandProtocolGuid
,
2806 (VOID
**)&Dev
->Sscp
,
2807 This
->DriverBindingHandle
,
2809 EFI_OPEN_PROTOCOL_BY_DRIVER
2811 if (EFI_ERROR(Status
)) {
2817 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2820 Status
= gBS
->OpenProtocol(
2822 &gEfiBlockIoProtocolGuid
,
2824 This
->DriverBindingHandle
,
2826 EFI_OPEN_PROTOCOL_BY_DRIVER
2828 if (EFI_ERROR(Status
)) {
2830 // Close storage security that was opened
2834 &gEfiStorageSecurityCommandProtocolGuid
,
2835 This
->DriverBindingHandle
,
2846 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2850 &gEfiBlockIoProtocolGuid
,
2851 This
->DriverBindingHandle
,
2856 // Acquire Ascii printable name of child, if not found, then ignore device
2858 Result
= OpalDriverGetDriverDeviceName (Dev
);
2863 Status
= OpalDiskInitialize (Dev
);
2864 if (EFI_ERROR (Status
)) {
2868 AddDeviceToTail(Dev
);
2871 // Check if device is locked and prompt for password.
2873 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2876 // Process OPAL request from last boot.
2878 ProcessOpalRequest (Dev
);
2884 // free device, close protocols and exit
2888 &gEfiStorageSecurityCommandProtocolGuid
,
2889 This
->DriverBindingHandle
,
2895 return EFI_DEVICE_ERROR
;
2899 Stop this driver on Controller.
2901 @param This Protocol instance pointer.
2902 @param Controller Handle of device to stop driver on
2903 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2904 children is zero stop the entire bus driver.
2905 @param ChildHandleBuffer List of Child Handles to Stop.
2907 @retval EFI_SUCCESS This driver is removed Controller.
2908 @retval other This driver could not be removed from this device.
2913 OpalEfiDriverBindingStop(
2914 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2915 EFI_HANDLE Controller
,
2916 UINTN NumberOfChildren
,
2917 EFI_HANDLE
* ChildHandleBuffer
2920 OPAL_DRIVER_DEVICE
* Itr
;
2922 Itr
= mOpalDriver
.DeviceList
;
2925 // does Controller match any of the devices we are managing for Opal
2927 while (Itr
!= NULL
) {
2928 if (Itr
->Handle
== Controller
) {
2929 OpalDriverStopDevice (Itr
);
2936 return EFI_NOT_FOUND
;
2941 Unloads UEFI Driver. Very useful for debugging and testing.
2943 @param ImageHandle Image Handle this driver.
2945 @retval EFI_SUCCESS This function always complete successfully.
2946 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2950 OpalEfiDriverUnload (
2951 IN EFI_HANDLE ImageHandle
2955 OPAL_DRIVER_DEVICE
*Itr
;
2957 Status
= EFI_SUCCESS
;
2959 if (ImageHandle
!= gImageHandle
) {
2960 return (EFI_INVALID_PARAMETER
);
2964 // Uninstall any interface added to each device by us
2966 while (mOpalDriver
.DeviceList
) {
2967 Itr
= mOpalDriver
.DeviceList
;
2969 // Remove OPAL_DRIVER_DEVICE from the list
2970 // it updates the controllerList pointer
2972 OpalDriverStopDevice(Itr
);
2976 // Uninstall the HII capability
2978 Status
= HiiUninstall();