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"));
469 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
471 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
473 @param Event Event whose notification function is being invoked.
474 @param Context Pointer to the notification function's context.
479 OpalEndOfDxeEventNotify (
484 OPAL_DRIVER_DEVICE
*TmpDev
;
486 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
488 mOpalEndOfDxe
= TRUE
;
490 if (mOpalRequestVariable
!= NULL
) {
492 // Free the OPAL request variable buffer here
493 // as the OPAL requests should have been processed.
495 FreePool (mOpalRequestVariable
);
496 mOpalRequestVariable
= NULL
;
497 mOpalRequestVariableSize
= 0;
501 // If no any device, return directly.
503 if (mOpalDriver
.DeviceList
== NULL
) {
504 gBS
->CloseEvent (Event
);
508 BuildOpalDeviceInfo ();
513 TmpDev
= mOpalDriver
.DeviceList
;
514 while (TmpDev
!= NULL
) {
515 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
516 TmpDev
= TmpDev
->Next
;
520 // Send BlockSid command if needed.
522 SendBlockSidCommand ();
524 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
526 gBS
->CloseEvent (Event
);
530 Get Psid input from the popup window.
532 @param[in] Dev The device which need Psid to process Psid Revert
534 @param[in] PopUpString Pop up string.
535 @param[in] PopUpString2 Pop up string in line 2.
536 @param[in] PopUpString3 Pop up string in line 3.
538 @param[out] PressEsc Whether user escape function through Press ESC.
540 @retval Psid string if success. NULL if failed.
544 OpalDriverPopUpPsidInput (
545 IN OPAL_DRIVER_DEVICE
*Dev
,
546 IN CHAR16
*PopUpString
,
547 IN CHAR16
*PopUpString2
,
548 IN CHAR16
*PopUpString3
,
549 OUT BOOLEAN
*PressEsc
552 EFI_INPUT_KEY InputKey
;
554 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
555 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
558 ZeroMem(Unicode
, sizeof(Unicode
));
559 ZeroMem(Mask
, sizeof(Mask
));
563 gST
->ConOut
->ClearScreen(gST
->ConOut
);
567 Mask
[InputLength
] = L
'_';
568 if (PopUpString2
== NULL
) {
570 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
573 L
"---------------------",
578 if (PopUpString3
== NULL
) {
580 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
584 L
"---------------------",
590 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
595 L
"---------------------",
605 if (InputKey
.ScanCode
== SCAN_NULL
) {
609 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
611 // Add the null terminator.
613 Unicode
[InputLength
] = 0;
614 Mask
[InputLength
] = 0;
616 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
617 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
618 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
623 // delete last key entered
625 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
626 if (InputLength
> 0) {
627 Unicode
[InputLength
] = 0;
628 Mask
[InputLength
] = 0;
633 // add Next key entry
635 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
636 Mask
[InputLength
] = InputKey
.UnicodeChar
;
638 if (InputLength
== PSID_CHARACTER_LENGTH
) {
640 // Add the null terminator.
642 Unicode
[InputLength
] = 0;
643 Mask
[InputLength
] = 0;
653 if (InputKey
.ScanCode
== SCAN_ESC
) {
659 gST
->ConOut
->ClearScreen(gST
->ConOut
);
661 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
662 ZeroMem (Unicode
, sizeof (Unicode
));
663 ZeroMem (Mask
, sizeof (Mask
));
667 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
669 ZeroMem (Unicode
, sizeof (Unicode
));
670 ZeroMem (Mask
, sizeof (Mask
));
674 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
675 ZeroMem (Unicode
, sizeof (Unicode
));
676 ZeroMem (Mask
, sizeof (Mask
));
683 Get password input from the popup window.
685 @param[in] Dev The device which need password to unlock or
686 process OPAL request.
687 @param[in] PopUpString1 Pop up string 1.
688 @param[in] PopUpString2 Pop up string 2.
689 @param[in] PopUpString3 Pop up string 3.
690 @param[out] PressEsc Whether user escape function through Press ESC.
692 @retval Password string if success. NULL if failed.
696 OpalDriverPopUpPasswordInput (
697 IN OPAL_DRIVER_DEVICE
*Dev
,
698 IN CHAR16
*PopUpString1
,
699 IN CHAR16
*PopUpString2
,
700 IN CHAR16
*PopUpString3
,
701 OUT BOOLEAN
*PressEsc
704 EFI_INPUT_KEY InputKey
;
706 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
707 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
710 ZeroMem(Unicode
, sizeof(Unicode
));
711 ZeroMem(Mask
, sizeof(Mask
));
715 gST
->ConOut
->ClearScreen(gST
->ConOut
);
719 Mask
[InputLength
] = L
'_';
720 if (PopUpString2
== NULL
) {
722 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
725 L
"---------------------",
730 if (PopUpString3
== NULL
) {
732 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
736 L
"---------------------",
742 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
747 L
"---------------------",
757 if (InputKey
.ScanCode
== SCAN_NULL
) {
761 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
763 // Add the null terminator.
765 Unicode
[InputLength
] = 0;
766 Mask
[InputLength
] = 0;
768 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
769 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
770 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
775 // delete last key entered
777 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
778 if (InputLength
> 0) {
779 Unicode
[InputLength
] = 0;
780 Mask
[InputLength
] = 0;
785 // add Next key entry
787 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
788 Mask
[InputLength
] = L
'*';
790 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
792 // Add the null terminator.
794 Unicode
[InputLength
] = 0;
795 Mask
[InputLength
] = 0;
805 if (InputKey
.ScanCode
== SCAN_ESC
) {
811 gST
->ConOut
->ClearScreen(gST
->ConOut
);
813 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
814 ZeroMem (Unicode
, sizeof (Unicode
));
818 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
820 ZeroMem (Unicode
, sizeof (Unicode
));
824 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
825 ZeroMem (Unicode
, sizeof (Unicode
));
833 @param[in] Dev The OPAL device.
834 @param[in] RequestString Request string.
836 @return Pop up string.
841 IN OPAL_DRIVER_DEVICE
*Dev
,
842 IN CHAR16
*RequestString
845 if (Dev
->Name16
== NULL
) {
846 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
848 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
855 Check if disk is locked, show popup window and ask for password if it is.
857 @param[in] Dev The device which need to be unlocked.
858 @param[in] RequestString Request string.
862 OpalDriverRequestPassword (
863 IN OPAL_DRIVER_DEVICE
*Dev
,
864 IN CHAR16
*RequestString
872 OPAL_SESSION Session
;
882 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
884 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
888 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
890 ZeroMem(&Session
, sizeof(Session
));
891 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
892 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
893 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
895 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
897 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
901 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
902 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
906 // Current device in the lock status and
907 // User not input password and press ESC,
908 // keep device in lock status and continue boot.
912 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
914 L
"Press ENTER to skip the request and continue boot,",
915 L
"Press ESC to input password again",
918 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
920 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
921 gST
->ConOut
->ClearScreen(gST
->ConOut
);
923 // Keep lock and continue boot.
928 // Let user input password again.
934 // Current device in the unlock status and
935 // User not input password and press ESC,
936 // Shutdown the device.
940 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
942 L
"Press ENTER to shutdown, Press ESC to input password again",
945 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
947 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
948 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
951 // Let user input password again.
958 if (Password
== NULL
) {
962 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
965 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
967 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
968 if (Ret
== TcgResultSuccess
) {
969 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
973 if (Ret
== TcgResultSuccess
) {
974 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
975 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
977 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
980 if (Password
!= NULL
) {
981 ZeroMem (Password
, PasswordLen
);
985 if (Ret
== TcgResultSuccess
) {
990 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
991 // before accept new password.
993 if (Ret
== TcgResultFailureInvalidType
) {
994 Count
= MAX_PASSWORD_TRY_COUNT
;
1002 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1004 L
"Invalid password.",
1005 L
"Press ENTER to retry",
1008 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1011 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1014 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1016 L
"Opal password retry count exceeds the limit. Must shutdown!",
1017 L
"Press ENTER to shutdown",
1020 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1022 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1028 Process Enable Feature OPAL request.
1030 @param[in] Dev The device which has Enable Feature OPAL request.
1031 @param[in] RequestString Request string.
1035 ProcessOpalRequestEnableFeature (
1036 IN OPAL_DRIVER_DEVICE
*Dev
,
1037 IN CHAR16
*RequestString
1043 CHAR8
*PasswordConfirm
;
1044 UINT32 PasswordLenConfirm
;
1045 OPAL_SESSION Session
;
1049 CHAR16
*PopUpString
;
1055 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1057 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1061 ZeroMem(&Session
, sizeof(Session
));
1062 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1063 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1064 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1066 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1067 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1071 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1073 L
"Press ENTER to skip the request and continue boot,",
1074 L
"Press ESC to input password again",
1077 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1079 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1080 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1084 // Let user input password again.
1090 if (Password
== NULL
) {
1094 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1096 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1097 if (PasswordConfirm
== NULL
) {
1098 ZeroMem (Password
, PasswordLen
);
1099 FreePool (Password
);
1103 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1104 if ((PasswordLen
!= PasswordLenConfirm
) ||
1105 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1106 ZeroMem (Password
, PasswordLen
);
1107 FreePool (Password
);
1108 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1109 FreePool (PasswordConfirm
);
1112 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1114 L
"Passwords are not the same.",
1115 L
"Press ENTER to retry",
1118 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1123 if (PasswordConfirm
!= NULL
) {
1124 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1125 FreePool (PasswordConfirm
);
1128 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1129 if (Ret
== TcgResultSuccess
) {
1130 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1131 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1133 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1136 if (Password
!= NULL
) {
1137 ZeroMem (Password
, PasswordLen
);
1138 FreePool (Password
);
1141 if (Ret
== TcgResultSuccess
) {
1149 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1152 L
"Press ENTER to retry",
1155 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1158 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1161 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1163 L
"Opal password retry count exceeds the limit.",
1164 L
"Press ENTER to skip the request and continue boot",
1167 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1168 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1173 Process Disable User OPAL request.
1175 @param[in] Dev The device which has Disable User OPAL request.
1176 @param[in] RequestString Request string.
1180 ProcessOpalRequestDisableUser (
1181 IN OPAL_DRIVER_DEVICE
*Dev
,
1182 IN CHAR16
*RequestString
1188 OPAL_SESSION Session
;
1192 BOOLEAN PasswordFailed
;
1193 CHAR16
*PopUpString
;
1199 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1201 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1205 ZeroMem(&Session
, sizeof(Session
));
1206 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1207 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1208 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1210 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1211 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
1215 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1217 L
"Press ENTER to skip the request and continue boot,",
1218 L
"Press ESC to input password again",
1221 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1223 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1224 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1228 // Let user input password again.
1234 if (Password
== NULL
) {
1238 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1240 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1241 if (Ret
== TcgResultSuccess
) {
1242 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1243 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1245 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1248 if (Password
!= NULL
) {
1249 ZeroMem (Password
, PasswordLen
);
1250 FreePool (Password
);
1253 if (Ret
== TcgResultSuccess
) {
1261 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1263 L
"Invalid password, request failed.",
1264 L
"Press ENTER to retry",
1267 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1270 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1273 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1275 L
"Opal password retry count exceeds the limit.",
1276 L
"Press ENTER to skip the request and continue boot",
1279 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1280 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1285 Process Psid Revert OPAL request.
1287 @param[in] Dev The device which has Psid Revert OPAL request.
1288 @param[in] RequestString Request string.
1292 ProcessOpalRequestPsidRevert (
1293 IN OPAL_DRIVER_DEVICE
*Dev
,
1294 IN CHAR16
*RequestString
1300 OPAL_SESSION Session
;
1304 CHAR16
*PopUpString
;
1305 CHAR16
*PopUpString2
;
1306 CHAR16
*PopUpString3
;
1313 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1315 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1317 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1318 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1319 PopUpString2
= AllocateZeroPool (BufferSize
);
1320 ASSERT (PopUpString2
!= NULL
);
1324 L
"WARNING: Revert action will take about %d seconds",
1325 Dev
->OpalDisk
.EstimateTimeCost
1327 PopUpString3
= L
"DO NOT power off system during the revert action!";
1329 PopUpString2
= NULL
;
1330 PopUpString3
= NULL
;
1335 ZeroMem(&Session
, sizeof(Session
));
1336 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1337 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1338 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1340 while (Count
< MAX_PSID_TRY_COUNT
) {
1341 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1345 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1347 L
"Press ENTER to skip the request and continue boot,",
1348 L
"Press ESC to input Psid again",
1351 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1353 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1354 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1358 // Let user input Psid again.
1368 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1370 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1371 if (Ret
== TcgResultSuccess
) {
1372 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1374 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1378 ZeroMem (Psid
, PsidLen
);
1382 if (Ret
== TcgResultSuccess
) {
1390 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1392 L
"Invalid Psid, request failed.",
1393 L
"Press ENTER to retry",
1396 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1399 if (Count
>= MAX_PSID_TRY_COUNT
) {
1402 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1404 L
"Opal Psid retry count exceeds the limit.",
1405 L
"Press ENTER to skip the request and continue boot",
1408 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1409 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1413 if (PopUpString2
!= NULL
) {
1414 FreePool (PopUpString2
);
1419 Process Admin Revert OPAL request.
1421 @param[in] Dev The device which has Revert OPAL request.
1422 @param[in] KeepUserData Whether to keep user data or not.
1423 @param[in] RequestString Request string.
1427 ProcessOpalRequestRevert (
1428 IN OPAL_DRIVER_DEVICE
*Dev
,
1429 IN BOOLEAN KeepUserData
,
1430 IN CHAR16
*RequestString
1436 OPAL_SESSION Session
;
1440 BOOLEAN PasswordFailed
;
1441 CHAR16
*PopUpString
;
1442 CHAR16
*PopUpString2
;
1443 CHAR16
*PopUpString3
;
1450 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1452 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1454 if ((!KeepUserData
) &&
1455 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1456 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1457 PopUpString2
= AllocateZeroPool (BufferSize
);
1458 ASSERT (PopUpString2
!= NULL
);
1462 L
"WARNING: Revert action will take about %d seconds",
1463 Dev
->OpalDisk
.EstimateTimeCost
1465 PopUpString3
= L
"DO NOT power off system during the revert action!";
1467 PopUpString2
= NULL
;
1468 PopUpString3
= NULL
;
1473 ZeroMem(&Session
, sizeof(Session
));
1474 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1475 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1476 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1478 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1479 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1483 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1485 L
"Press ENTER to skip the request and continue boot,",
1486 L
"Press ESC to input password again",
1489 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1491 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1492 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1496 // Let user input password again.
1502 if (Password
== NULL
) {
1506 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1508 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1509 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1511 // For pyrite type device which does not support media encryption,
1512 // it does not accept "Keep User Data" parameter.
1513 // So here hardcode a FALSE for this case.
1515 Ret
= OpalUtilRevert(
1522 Dev
->OpalDisk
.MsidLength
1525 Ret
= OpalUtilRevert(
1532 Dev
->OpalDisk
.MsidLength
1535 if (Ret
== TcgResultSuccess
) {
1536 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1537 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1539 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1542 if (Password
!= NULL
) {
1543 ZeroMem (Password
, PasswordLen
);
1544 FreePool (Password
);
1547 if (Ret
== TcgResultSuccess
) {
1555 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1557 L
"Invalid password, request failed.",
1558 L
"Press ENTER to retry",
1561 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1564 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1567 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1569 L
"Opal password retry count exceeds the limit.",
1570 L
"Press ENTER to skip the request and continue boot",
1573 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1574 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1578 if (PopUpString2
!= NULL
) {
1579 FreePool (PopUpString2
);
1584 Process Secure Erase OPAL request.
1586 @param[in] Dev The device which has Secure Erase OPAL request.
1587 @param[in] RequestString Request string.
1591 ProcessOpalRequestSecureErase (
1592 IN OPAL_DRIVER_DEVICE
*Dev
,
1593 IN CHAR16
*RequestString
1599 OPAL_SESSION Session
;
1603 BOOLEAN PasswordFailed
;
1604 CHAR16
*PopUpString
;
1605 CHAR16
*PopUpString2
;
1606 CHAR16
*PopUpString3
;
1613 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1615 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1617 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1618 BufferSize
= StrSize (L
"Warning: Secure erase action will take about ####### seconds");
1619 PopUpString2
= AllocateZeroPool (BufferSize
);
1620 ASSERT (PopUpString2
!= NULL
);
1624 L
"WARNING: Secure erase action will take about %d seconds",
1625 Dev
->OpalDisk
.EstimateTimeCost
1627 PopUpString3
= L
"DO NOT power off system during the action!";
1629 PopUpString2
= NULL
;
1630 PopUpString3
= NULL
;
1634 ZeroMem(&Session
, sizeof(Session
));
1635 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1636 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1637 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1639 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1640 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1644 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1646 L
"Press ENTER to skip the request and continue boot,",
1647 L
"Press ESC to input password again",
1650 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1652 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1653 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1657 // Let user input password again.
1663 if (Password
== NULL
) {
1667 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1669 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1670 if (Ret
== TcgResultSuccess
) {
1671 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1672 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1674 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1677 if (Password
!= NULL
) {
1678 ZeroMem (Password
, PasswordLen
);
1679 FreePool (Password
);
1682 if (Ret
== TcgResultSuccess
) {
1690 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1692 L
"Invalid password, request failed.",
1693 L
"Press ENTER to retry",
1696 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1699 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1702 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1704 L
"Opal password retry count exceeds the limit.",
1705 L
"Press ENTER to skip the request and continue boot",
1708 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1709 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1713 if (PopUpString2
!= NULL
) {
1714 FreePool (PopUpString2
);
1719 Process Set Admin Pwd OPAL request.
1721 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1722 @param[in] RequestString Request string.
1726 ProcessOpalRequestSetUserPwd (
1727 IN OPAL_DRIVER_DEVICE
*Dev
,
1728 IN CHAR16
*RequestString
1733 UINT32 OldPasswordLen
;
1736 CHAR8
*PasswordConfirm
;
1737 UINT32 PasswordLenConfirm
;
1738 OPAL_SESSION Session
;
1742 CHAR16
*PopUpString
;
1748 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1750 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1754 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1755 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1759 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1761 L
"Press ENTER to skip the request and continue boot,",
1762 L
"Press ESC to input password again",
1765 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1767 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1768 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1772 // Let user input password again.
1778 if (OldPassword
== NULL
) {
1782 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1784 ZeroMem(&Session
, sizeof(Session
));
1785 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1786 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1787 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1788 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1789 if (Ret
== TcgResultSuccess
) {
1790 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1792 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1793 if (Ret
== TcgResultSuccess
) {
1794 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1796 ZeroMem (OldPassword
, OldPasswordLen
);
1797 FreePool (OldPassword
);
1798 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1801 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1803 L
"Incorrect password.",
1804 L
"Press ENTER to retry",
1807 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1813 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1814 if (Password
== NULL
) {
1815 ZeroMem (OldPassword
, OldPasswordLen
);
1816 FreePool (OldPassword
);
1820 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1822 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1823 if (PasswordConfirm
== NULL
) {
1824 ZeroMem (OldPassword
, OldPasswordLen
);
1825 FreePool (OldPassword
);
1826 ZeroMem (Password
, PasswordLen
);
1827 FreePool (Password
);
1831 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1832 if ((PasswordLen
!= PasswordLenConfirm
) ||
1833 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1834 ZeroMem (OldPassword
, OldPasswordLen
);
1835 FreePool (OldPassword
);
1836 ZeroMem (Password
, PasswordLen
);
1837 FreePool (Password
);
1838 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1839 FreePool (PasswordConfirm
);
1842 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1844 L
"Passwords are not the same.",
1845 L
"Press ENTER to retry",
1848 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1853 if (PasswordConfirm
!= NULL
) {
1854 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1855 FreePool (PasswordConfirm
);
1858 ZeroMem(&Session
, sizeof(Session
));
1859 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1860 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1861 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1862 Ret
= OpalUtilSetUserPassword(
1869 if (Ret
== TcgResultSuccess
) {
1870 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1871 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1873 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1876 if (OldPassword
!= NULL
) {
1877 ZeroMem (OldPassword
, OldPasswordLen
);
1878 FreePool (OldPassword
);
1881 if (Password
!= NULL
) {
1882 ZeroMem (Password
, PasswordLen
);
1883 FreePool (Password
);
1886 if (Ret
== TcgResultSuccess
) {
1894 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1897 L
"Press ENTER to retry",
1900 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1903 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1906 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1908 L
"Opal password retry count exceeds the limit.",
1909 L
"Press ENTER to skip the request and continue boot",
1912 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1913 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1918 Process Set Admin Pwd OPAL request.
1920 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1921 @param[in] RequestString Request string.
1925 ProcessOpalRequestSetAdminPwd (
1926 IN OPAL_DRIVER_DEVICE
*Dev
,
1927 IN CHAR16
*RequestString
1932 UINT32 OldPasswordLen
;
1935 CHAR8
*PasswordConfirm
;
1936 UINT32 PasswordLenConfirm
;
1937 OPAL_SESSION Session
;
1941 CHAR16
*PopUpString
;
1947 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1949 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1953 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1954 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1958 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1960 L
"Press ENTER to skip the request and continue boot,",
1961 L
"Press ESC to input password again",
1964 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1966 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1967 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1971 // Let user input password again.
1977 if (OldPassword
== NULL
) {
1981 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1983 ZeroMem(&Session
, sizeof(Session
));
1984 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1985 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1986 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1987 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1988 if (Ret
== TcgResultSuccess
) {
1989 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1991 ZeroMem (OldPassword
, OldPasswordLen
);
1992 FreePool (OldPassword
);
1993 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1996 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1998 L
"Incorrect password.",
1999 L
"Press ENTER to retry",
2002 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2007 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
2008 if (Password
== NULL
) {
2009 ZeroMem (OldPassword
, OldPasswordLen
);
2010 FreePool (OldPassword
);
2014 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2016 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
2017 if (PasswordConfirm
== NULL
) {
2018 ZeroMem (OldPassword
, OldPasswordLen
);
2019 FreePool (OldPassword
);
2020 ZeroMem (Password
, PasswordLen
);
2021 FreePool (Password
);
2025 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2026 if ((PasswordLen
!= PasswordLenConfirm
) ||
2027 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2028 ZeroMem (OldPassword
, OldPasswordLen
);
2029 FreePool (OldPassword
);
2030 ZeroMem (Password
, PasswordLen
);
2031 FreePool (Password
);
2032 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2033 FreePool (PasswordConfirm
);
2036 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2038 L
"Passwords are not the same.",
2039 L
"Press ENTER to retry",
2042 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2047 if (PasswordConfirm
!= NULL
) {
2048 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2049 FreePool (PasswordConfirm
);
2053 ZeroMem(&Session
, sizeof(Session
));
2054 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2055 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2056 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2057 Ret
= OpalUtilSetAdminPassword(
2064 if (Ret
== TcgResultSuccess
) {
2065 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2066 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2068 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2071 if (OldPassword
!= NULL
) {
2072 ZeroMem (OldPassword
, OldPasswordLen
);
2073 FreePool (OldPassword
);
2076 if (Password
!= NULL
) {
2077 ZeroMem (Password
, PasswordLen
);
2078 FreePool (Password
);
2081 if (Ret
== TcgResultSuccess
) {
2089 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2092 L
"Press ENTER to retry",
2095 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2098 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2101 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2103 L
"Opal password retry count exceeds the limit.",
2104 L
"Press ENTER to skip the request and continue boot",
2107 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2108 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2113 Process OPAL request.
2115 @param[in] Dev The device which has OPAL request.
2119 ProcessOpalRequest (
2120 IN OPAL_DRIVER_DEVICE
*Dev
2124 OPAL_REQUEST_VARIABLE
*TempVariable
;
2125 OPAL_REQUEST_VARIABLE
*Variable
;
2127 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2128 UINTN DevicePathSizeInVariable
;
2129 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2130 UINTN DevicePathSize
;
2131 BOOLEAN KeepUserData
;
2133 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2135 if (mOpalRequestVariable
== NULL
) {
2136 Status
= GetVariable2 (
2137 OPAL_REQUEST_VARIABLE_NAME
,
2138 &gHiiSetupVariableGuid
,
2139 (VOID
**) &Variable
,
2142 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2145 mOpalRequestVariable
= Variable
;
2146 mOpalRequestVariableSize
= VariableSize
;
2149 // Delete the OPAL request variable.
2151 Status
= gRT
->SetVariable (
2152 OPAL_REQUEST_VARIABLE_NAME
,
2153 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2158 ASSERT_EFI_ERROR (Status
);
2160 Variable
= mOpalRequestVariable
;
2161 VariableSize
= mOpalRequestVariableSize
;
2165 // Process the OPAL requests.
2167 TempVariable
= Variable
;
2168 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2169 (VariableSize
>= TempVariable
->Length
) &&
2170 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2171 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2172 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2173 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2174 DevicePathSize
= GetDevicePathSize (DevicePath
);
2175 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2176 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2178 // Found the node for the OPAL device.
2180 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2181 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2183 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2184 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2186 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2187 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2189 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2190 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2191 ProcessOpalRequestRevert (
2194 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2197 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2198 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2200 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2201 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2203 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2204 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2210 VariableSize
-= TempVariable
->Length
;
2211 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2214 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2218 Add new device to the global device list.
2220 @param Dev New create device.
2225 IN OPAL_DRIVER_DEVICE
*Dev
2228 OPAL_DRIVER_DEVICE
*TmpDev
;
2230 if (mOpalDriver
.DeviceList
== NULL
) {
2231 mOpalDriver
.DeviceList
= Dev
;
2233 TmpDev
= mOpalDriver
.DeviceList
;
2234 while (TmpDev
->Next
!= NULL
) {
2235 TmpDev
= TmpDev
->Next
;
2243 Remove one device in the global device list.
2245 @param Dev The device need to be removed.
2250 IN OPAL_DRIVER_DEVICE
*Dev
2253 OPAL_DRIVER_DEVICE
*TmpDev
;
2255 if (mOpalDriver
.DeviceList
== NULL
) {
2259 if (mOpalDriver
.DeviceList
== Dev
) {
2260 mOpalDriver
.DeviceList
= NULL
;
2264 TmpDev
= mOpalDriver
.DeviceList
;
2265 while (TmpDev
->Next
!= NULL
) {
2266 if (TmpDev
->Next
== Dev
) {
2267 TmpDev
->Next
= Dev
->Next
;
2274 Get current device count.
2276 @retval return the current created device count.
2285 OPAL_DRIVER_DEVICE
*TmpDev
;
2288 TmpDev
= mOpalDriver
.DeviceList
;
2290 while (TmpDev
!= NULL
) {
2292 TmpDev
= TmpDev
->Next
;
2299 Get devcie list info.
2301 @retval return the device list pointer.
2304 OpalDriverGetDeviceList(
2308 return mOpalDriver
.DeviceList
;
2312 Stop this Controller.
2314 @param Dev The device need to be stopped.
2318 OpalDriverStopDevice (
2319 OPAL_DRIVER_DEVICE
*Dev
2325 FreePool(Dev
->Name16
);
2328 // remove OPAL_DRIVER_DEVICE from the list
2329 // it updates the controllerList pointer
2334 // close protocols that were opened
2338 &gEfiStorageSecurityCommandProtocolGuid
,
2339 gOpalDriverBinding
.DriverBindingHandle
,
2345 &gEfiBlockIoProtocolGuid
,
2346 gOpalDriverBinding
.DriverBindingHandle
,
2354 Get devcie name through the component name protocol.
2356 @param[in] AllHandlesBuffer The handle buffer for current system.
2357 @param[in] NumAllHandles The number of handles for the handle buffer.
2358 @param[in] Dev The device which need to get name.
2359 @param[in] UseComp1 Whether use component name or name2 protocol.
2361 @retval TRUE Find the name for this device.
2362 @retval FALSE Not found the name for this device.
2365 OpalDriverGetDeviceNameByProtocol(
2366 EFI_HANDLE
*AllHandlesBuffer
,
2367 UINTN NumAllHandles
,
2368 OPAL_DRIVER_DEVICE
*Dev
,
2372 EFI_HANDLE
* ProtocolHandlesBuffer
;
2373 UINTN NumProtocolHandles
;
2375 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2378 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2381 EFI_HANDLE TmpHandle
;
2384 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2388 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2391 // Find all EFI_HANDLES with protocol
2393 Status
= gBS
->LocateHandleBuffer(
2397 &NumProtocolHandles
,
2398 &ProtocolHandlesBuffer
2400 if (EFI_ERROR(Status
)) {
2406 // Exit early if no supported devices
2408 if (NumProtocolHandles
== 0) {
2413 // Get printable name by iterating through all protocols
2414 // using the handle as the child, and iterate through all handles for the controller
2415 // exit loop early once found, if not found, then delete device
2416 // storage security protocol instances already exist, add them to internal list
2418 Status
= EFI_DEVICE_ERROR
;
2419 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2422 if (Dev
->Name16
!= NULL
) {
2426 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2428 Status
= gBS
->OpenProtocol(
2434 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2436 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2441 // Use all handles array as controller handle
2443 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2444 Status
= Cnp1_2
->GetControllerName(
2446 AllHandlesBuffer
[Index2
],
2448 LANGUAGE_ISO_639_2_ENGLISH
,
2451 if (EFI_ERROR(Status
)) {
2452 Status
= Cnp1_2
->GetControllerName(
2454 AllHandlesBuffer
[Index2
],
2456 LANGUAGE_RFC_3066_ENGLISH
,
2460 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2461 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2462 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2463 ASSERT (Dev
->Name16
!= NULL
);
2464 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2465 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2466 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2469 // Retrieve bridge BDF info and port number or namespace depending on type
2472 Status
= gBS
->OpenProtocol(
2474 &gEfiDevicePathProtocolGuid
,
2475 (VOID
**)&TmpDevPath
,
2478 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2480 if (!EFI_ERROR(Status
)) {
2481 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2485 if (Dev
->Name16
!= NULL
) {
2486 FreePool(Dev
->Name16
);
2489 if (Dev
->NameZ
!= NULL
) {
2490 FreePool(Dev
->NameZ
);
2501 Get devcie name through the component name protocol.
2503 @param[in] Dev The device which need to get name.
2505 @retval TRUE Find the name for this device.
2506 @retval FALSE Not found the name for this device.
2509 OpalDriverGetDriverDeviceName(
2510 OPAL_DRIVER_DEVICE
*Dev
2513 EFI_HANDLE
* AllHandlesBuffer
;
2514 UINTN NumAllHandles
;
2518 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2523 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2525 if (Dev
->Name16
== NULL
) {
2526 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2528 // Find all EFI_HANDLES
2530 Status
= gBS
->LocateHandleBuffer(
2537 if (EFI_ERROR(Status
)) {
2538 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2543 // Try component Name2
2545 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2546 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2547 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2548 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2558 Main entry for this driver.
2560 @param ImageHandle Image Handle this driver.
2561 @param SystemTable Pointer to SystemTable.
2563 @retval EFI_SUCESS This function always complete successfully.
2567 EfiDriverEntryPoint(
2568 IN EFI_HANDLE ImageHandle
,
2569 IN EFI_SYSTEM_TABLE
* SystemTable
2573 EFI_EVENT EndOfDxeEvent
;
2575 Status
= EfiLibInstallDriverBindingComponentName2 (
2578 &gOpalDriverBinding
,
2580 &gOpalComponentName
,
2581 &gOpalComponentName2
2584 if (EFI_ERROR(Status
)) {
2585 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2590 // Initialize Driver object
2592 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2593 mOpalDriver
.Handle
= ImageHandle
;
2595 Status
= gBS
->CreateEventEx (
2598 OpalEndOfDxeEventNotify
,
2600 &gEfiEndOfDxeEventGroupGuid
,
2603 ASSERT_EFI_ERROR (Status
);
2606 // Install Hii packages.
2614 Tests to see if this driver supports a given controller.
2616 This function checks to see if the controller contains an instance of the
2617 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2618 and returns EFI_SUCCESS if it does.
2620 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2621 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2622 must support a protocol interface that supplies
2623 an I/O abstraction to the driver.
2624 @param[in] RemainingDevicePath This parameter is ignored.
2626 @retval EFI_SUCCESS The device contains required protocols
2627 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2628 RemainingDevicePath is already being managed by the driver
2630 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2631 RemainingDevicePath is already being managed by a different
2632 driver or an application that requires exclusive access.
2633 Currently not implemented.
2634 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2639 OpalEfiDriverBindingSupported(
2640 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2641 IN EFI_HANDLE Controller
,
2642 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2646 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2647 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2649 if (mOpalEndOfDxe
) {
2650 return EFI_UNSUPPORTED
;
2654 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2656 Status
= gBS
->OpenProtocol(
2658 &gEfiStorageSecurityCommandProtocolGuid
,
2659 ( VOID
** )&SecurityCommand
,
2660 This
->DriverBindingHandle
,
2662 EFI_OPEN_PROTOCOL_BY_DRIVER
2665 if (Status
== EFI_ALREADY_STARTED
) {
2669 if (EFI_ERROR(Status
)) {
2674 // Close protocol and reopen in Start call
2678 &gEfiStorageSecurityCommandProtocolGuid
,
2679 This
->DriverBindingHandle
,
2684 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2687 Status
= gBS
->OpenProtocol(
2689 &gEfiBlockIoProtocolGuid
,
2691 This
->DriverBindingHandle
,
2693 EFI_OPEN_PROTOCOL_BY_DRIVER
2696 if (EFI_ERROR(Status
)) {
2697 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2702 // Close protocol and reopen in Start call
2706 &gEfiBlockIoProtocolGuid
,
2707 This
->DriverBindingHandle
,
2715 Enables Opal Management on a supported device if available.
2717 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2718 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2719 This function will complete the other necessary checks, such as verifying the device supports
2720 the correct version of Opal. Upon verification, it will add the device to the
2721 Opal HII list in order to expose Opal managmeent options.
2723 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2724 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2725 must support a protocol interface that supplies
2726 an I/O abstraction to the driver.
2727 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2728 parameter is ignored by device drivers, and is optional for bus
2729 drivers. For a bus driver, if this parameter is NULL, then handles
2730 for all the children of Controller are created by this driver.
2731 If this parameter is not NULL and the first Device Path Node is
2732 not the End of Device Path Node, then only the Handle for the
2733 child device specified by the first Device Path Node of
2734 RemainingDevicePath is created by this driver.
2735 If the first Device Path Node of RemainingDevicePath is
2736 the End of Device Path Node, no child Handle is created by this
2739 @retval EFI_SUCCESS Opal management was enabled.
2740 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2741 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2742 @retval Others The driver failed to start the device.
2747 OpalEfiDriverBindingStart(
2748 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2749 IN EFI_HANDLE Controller
,
2750 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2754 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2755 OPAL_DRIVER_DEVICE
*Dev
;
2756 OPAL_DRIVER_DEVICE
*Itr
;
2759 Itr
= mOpalDriver
.DeviceList
;
2760 while (Itr
!= NULL
) {
2761 if (Controller
== Itr
->Handle
) {
2768 // Create internal device for tracking. This allows all disks to be tracked
2771 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2773 return EFI_OUT_OF_RESOURCES
;
2775 Dev
->Handle
= Controller
;
2778 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2780 Status
= gBS
->OpenProtocol(
2782 &gEfiStorageSecurityCommandProtocolGuid
,
2783 (VOID
**)&Dev
->Sscp
,
2784 This
->DriverBindingHandle
,
2786 EFI_OPEN_PROTOCOL_BY_DRIVER
2788 if (EFI_ERROR(Status
)) {
2794 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2797 Status
= gBS
->OpenProtocol(
2799 &gEfiBlockIoProtocolGuid
,
2801 This
->DriverBindingHandle
,
2803 EFI_OPEN_PROTOCOL_BY_DRIVER
2805 if (EFI_ERROR(Status
)) {
2807 // Close storage security that was opened
2811 &gEfiStorageSecurityCommandProtocolGuid
,
2812 This
->DriverBindingHandle
,
2823 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2827 &gEfiBlockIoProtocolGuid
,
2828 This
->DriverBindingHandle
,
2833 // Acquire Ascii printable name of child, if not found, then ignore device
2835 Result
= OpalDriverGetDriverDeviceName (Dev
);
2840 Status
= OpalDiskInitialize (Dev
);
2841 if (EFI_ERROR (Status
)) {
2845 AddDeviceToTail(Dev
);
2848 // Check if device is locked and prompt for password.
2850 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2853 // Process OPAL request from last boot.
2855 ProcessOpalRequest (Dev
);
2861 // free device, close protocols and exit
2865 &gEfiStorageSecurityCommandProtocolGuid
,
2866 This
->DriverBindingHandle
,
2872 return EFI_DEVICE_ERROR
;
2876 Stop this driver on Controller.
2878 @param This Protocol instance pointer.
2879 @param Controller Handle of device to stop driver on
2880 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2881 children is zero stop the entire bus driver.
2882 @param ChildHandleBuffer List of Child Handles to Stop.
2884 @retval EFI_SUCCESS This driver is removed Controller.
2885 @retval other This driver could not be removed from this device.
2890 OpalEfiDriverBindingStop(
2891 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2892 EFI_HANDLE Controller
,
2893 UINTN NumberOfChildren
,
2894 EFI_HANDLE
* ChildHandleBuffer
2897 OPAL_DRIVER_DEVICE
* Itr
;
2899 Itr
= mOpalDriver
.DeviceList
;
2902 // does Controller match any of the devices we are managing for Opal
2904 while (Itr
!= NULL
) {
2905 if (Itr
->Handle
== Controller
) {
2906 OpalDriverStopDevice (Itr
);
2913 return EFI_NOT_FOUND
;
2918 Unloads UEFI Driver. Very useful for debugging and testing.
2920 @param ImageHandle Image Handle this driver.
2922 @retval EFI_SUCCESS This function always complete successfully.
2923 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2927 OpalEfiDriverUnload (
2928 IN EFI_HANDLE ImageHandle
2932 OPAL_DRIVER_DEVICE
*Itr
;
2934 Status
= EFI_SUCCESS
;
2936 if (ImageHandle
!= gImageHandle
) {
2937 return (EFI_INVALID_PARAMETER
);
2941 // Uninstall any interface added to each device by us
2943 while (mOpalDriver
.DeviceList
) {
2944 Itr
= mOpalDriver
.DeviceList
;
2946 // Remove OPAL_DRIVER_DEVICE from the list
2947 // it updates the controllerList pointer
2949 OpalDriverStopDevice(Itr
);
2953 // Uninstall the HII capability
2955 Status
= HiiUninstall();