2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
11 // HII GUI to manage Opal features if the device is Opal capable
12 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
13 // window during boot requesting a user password
15 #include "OpalDriver.h"
18 EFI_GUID mOpalDeviceLockBoxGuid
= OPAL_DEVICE_LOCKBOX_GUID
;
20 BOOLEAN mOpalEndOfDxe
= FALSE
;
21 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
22 UINTN mOpalRequestVariableSize
= 0;
23 CHAR16 mPopUpString
[100];
25 OPAL_DRIVER mOpalDriver
;
30 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
31 OpalEfiDriverBindingSupported
,
32 OpalEfiDriverBindingStart
,
33 OpalEfiDriverBindingStop
,
41 The function determines the available actions for the OPAL_DISK provided.
43 @param[in] SupportedAttributes The supported attributes for the device.
44 @param[in] LockingFeature The locking status for the device.
45 @param[in] OwnerShip The ownership for the device.
46 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
51 OpalSupportGetAvailableActions(
52 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
53 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
55 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
58 BOOLEAN ExistingPassword
;
60 NULL_CHECK(AvalDiskActions
);
62 AvalDiskActions
->AdminPass
= 1;
63 AvalDiskActions
->UserPass
= 0;
64 AvalDiskActions
->DisableUser
= 0;
65 AvalDiskActions
->Unlock
= 0;
68 // Revert is performed on locking sp, so only allow if locking sp is enabled
70 if (LockingFeature
->LockingEnabled
) {
71 AvalDiskActions
->Revert
= 1;
75 // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
77 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
80 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
81 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
82 // intact and accessible
84 AvalDiskActions
->PsidRevert
= 1;
85 AvalDiskActions
->RevertKeepDataForced
= 0;
88 // Secure erase is performed by generating a new encryption key
89 // this is only available if encryption is supported
91 AvalDiskActions
->SecureErase
= 1;
93 AvalDiskActions
->PsidRevert
= 0;
94 AvalDiskActions
->SecureErase
= 0;
97 // If no media encryption is supported, then a revert (using password) will not
98 // erase the Data (since you can't generate a new encryption key)
100 AvalDiskActions
->RevertKeepDataForced
= 1;
103 if (LockingFeature
->Locked
) {
104 AvalDiskActions
->Unlock
= 1;
106 AvalDiskActions
->Unlock
= 0;
110 // Only allow user to set password if an admin password exists
112 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
113 AvalDiskActions
->UserPass
= ExistingPassword
;
116 // This will still show up even if there isn't a user, which is fine
118 AvalDiskActions
->DisableUser
= ExistingPassword
;
120 return TcgResultSuccess
;
124 Enable Opal Feature for the input device.
126 @param[in] Session The opal session for the opal device.
128 @param[in] MsidLength Msid Length
129 @param[in] Password Admin password
130 @param[in] PassLength Length of password in bytes
135 OpalSupportEnableOpalFeature (
136 IN OPAL_SESSION
*Session
,
138 IN UINT32 MsidLength
,
147 NULL_CHECK(Password
);
149 Ret
= OpalUtilSetAdminPasswordAsSid(
156 if (Ret
== TcgResultSuccess
) {
158 // Enable global locking range
160 Ret
= OpalUtilSetOpalLockingRange(
164 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
178 Update password for the Opal disk.
180 @param[in, out] OpalDisk The disk to update password.
181 @param[in] Password The input password.
182 @param[in] PasswordLength The input password length.
186 OpalSupportUpdatePassword (
187 IN OUT OPAL_DISK
*OpalDisk
,
189 IN UINT32 PasswordLength
192 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
193 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
197 Extract device info from the device path.
199 @param[in] DevicePath Device path info for the device.
200 @param[out] DevInfoLength Device information length needed.
201 @param[out] DevInfo Device information extracted.
205 ExtractDeviceInfoFromDevicePath (
206 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
207 OUT UINT32
*DevInfoLength
,
208 OUT OPAL_DEVICE_LOCKBOX_DATA
*DevInfo OPTIONAL
211 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
212 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
213 PCI_DEVICE_PATH
*PciDevPath
;
216 OPAL_PCI_DEVICE
*PciDevice
;
218 ASSERT (DevicePath
!= NULL
);
219 ASSERT (DevInfoLength
!= NULL
);
221 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
224 TmpDevPath
= DevicePath
;
229 while (!IsDevicePathEnd (TmpDevPath
)) {
230 if ((TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
) &&
231 (TmpDevPath
->SubType
== MSG_SATA_DP
|| TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
232 if (DevInfo
!= NULL
) {
233 DevInfo
->DevicePathLength
= (UINT32
) GetDevicePathSize (DevicePath
);
234 CopyMem (DevInfo
->DevicePath
, DevicePath
, DevInfo
->DevicePathLength
);
237 DeviceType
= (TmpDevPath
->SubType
== MSG_SATA_DP
) ? OPAL_DEVICE_TYPE_ATA
: OPAL_DEVICE_TYPE_NVME
;
238 *DevInfoLength
= sizeof (OPAL_DEVICE_LOCKBOX_DATA
) + (UINT32
) GetDevicePathSize (DevicePath
);
241 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
248 TmpDevPath
= DevicePath
;
249 TmpDevPath2
= NextDevicePathNode (DevicePath
);
250 while (!IsDevicePathEnd (TmpDevPath2
)) {
251 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
252 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
253 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
) &&
254 (TmpDevPath2
->SubType
== MSG_SATA_DP
|| TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)) {
255 if (DevInfo
!= NULL
) {
256 PciDevice
= &DevInfo
->Device
;
257 PciDevice
->Segment
= 0;
258 PciDevice
->Bus
= BusNum
;
259 PciDevice
->Device
= PciDevPath
->Device
;
260 PciDevice
->Function
= PciDevPath
->Function
;
263 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
264 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
269 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
270 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
273 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
278 Build OPAL device info and save them to LockBox.
282 BuildOpalDeviceInfo (
287 OPAL_DEVICE_LOCKBOX_DATA
*DevInfo
;
288 OPAL_DEVICE_LOCKBOX_DATA
*TempDevInfo
;
289 UINTN TotalDevInfoLength
;
290 UINT32 DevInfoLength
;
291 OPAL_DRIVER_DEVICE
*TmpDev
;
293 BOOLEAN S3InitDevicesExist
;
294 UINTN S3InitDevicesLength
;
295 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevices
;
296 EFI_DEVICE_PATH_PROTOCOL
*S3InitDevicesBak
;
299 // Build OPAL device info and save them to LockBox.
301 TotalDevInfoLength
= 0;
302 TmpDev
= mOpalDriver
.DeviceList
;
303 while (TmpDev
!= NULL
) {
304 ExtractDeviceInfoFromDevicePath (
305 TmpDev
->OpalDisk
.OpalDevicePath
,
309 TotalDevInfoLength
+= DevInfoLength
;
310 TmpDev
= TmpDev
->Next
;
313 if (TotalDevInfoLength
== 0) {
317 S3InitDevicesLength
= sizeof (DummyData
);
318 Status
= RestoreLockBox (
319 &gS3StorageDeviceInitListGuid
,
323 ASSERT ((Status
== EFI_NOT_FOUND
) || (Status
== EFI_BUFFER_TOO_SMALL
));
324 if (Status
== EFI_NOT_FOUND
) {
325 S3InitDevices
= NULL
;
326 S3InitDevicesExist
= FALSE
;
327 } else if (Status
== EFI_BUFFER_TOO_SMALL
) {
328 S3InitDevices
= AllocatePool (S3InitDevicesLength
);
329 ASSERT (S3InitDevices
!= NULL
);
330 if (S3InitDevices
== NULL
) {
334 Status
= RestoreLockBox (
335 &gS3StorageDeviceInitListGuid
,
339 ASSERT_EFI_ERROR (Status
);
340 S3InitDevicesExist
= TRUE
;
345 DevInfo
= AllocateZeroPool (TotalDevInfoLength
);
346 ASSERT (DevInfo
!= NULL
);
347 if (DevInfo
== NULL
) {
351 TempDevInfo
= DevInfo
;
352 TmpDev
= mOpalDriver
.DeviceList
;
353 while (TmpDev
!= NULL
) {
354 ExtractDeviceInfoFromDevicePath (
355 TmpDev
->OpalDisk
.OpalDevicePath
,
359 TempDevInfo
->Length
= DevInfoLength
;
360 TempDevInfo
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
362 TempDevInfo
->Password
,
363 TmpDev
->OpalDisk
.Password
,
364 TmpDev
->OpalDisk
.PasswordLength
366 TempDevInfo
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
368 S3InitDevicesBak
= S3InitDevices
;
369 S3InitDevices
= AppendDevicePathInstance (
371 TmpDev
->OpalDisk
.OpalDevicePath
373 if (S3InitDevicesBak
!= NULL
) {
374 FreePool (S3InitDevicesBak
);
376 ASSERT (S3InitDevices
!= NULL
);
377 if (S3InitDevices
== NULL
) {
381 TempDevInfo
= (OPAL_DEVICE_LOCKBOX_DATA
*) ((UINTN
) TempDevInfo
+ DevInfoLength
);
382 TmpDev
= TmpDev
->Next
;
385 Status
= SaveLockBox (
386 &mOpalDeviceLockBoxGuid
,
390 ASSERT_EFI_ERROR (Status
);
392 Status
= SetLockBoxAttributes (
393 &mOpalDeviceLockBoxGuid
,
394 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
396 ASSERT_EFI_ERROR (Status
);
398 S3InitDevicesLength
= GetDevicePathSize (S3InitDevices
);
399 if (S3InitDevicesExist
) {
400 Status
= UpdateLockBox (
401 &gS3StorageDeviceInitListGuid
,
406 ASSERT_EFI_ERROR (Status
);
408 Status
= SaveLockBox (
409 &gS3StorageDeviceInitListGuid
,
413 ASSERT_EFI_ERROR (Status
);
415 Status
= SetLockBoxAttributes (
416 &gS3StorageDeviceInitListGuid
,
417 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
419 ASSERT_EFI_ERROR (Status
);
422 ZeroMem (DevInfo
, TotalDevInfoLength
);
424 FreePool (S3InitDevices
);
428 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
430 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
432 @param Event Event whose notification function is being invoked.
433 @param Context Pointer to the notification function's context.
438 OpalEndOfDxeEventNotify (
443 OPAL_DRIVER_DEVICE
*TmpDev
;
445 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
447 mOpalEndOfDxe
= TRUE
;
449 if (mOpalRequestVariable
!= NULL
) {
451 // Free the OPAL request variable buffer here
452 // as the OPAL requests should have been processed.
454 FreePool (mOpalRequestVariable
);
455 mOpalRequestVariable
= NULL
;
456 mOpalRequestVariableSize
= 0;
460 // If no any device, return directly.
462 if (mOpalDriver
.DeviceList
== NULL
) {
463 gBS
->CloseEvent (Event
);
467 BuildOpalDeviceInfo ();
472 TmpDev
= mOpalDriver
.DeviceList
;
473 while (TmpDev
!= NULL
) {
474 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
475 TmpDev
= TmpDev
->Next
;
478 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
480 gBS
->CloseEvent (Event
);
484 Get Psid input from the popup window.
486 @param[in] Dev The device which need Psid to process Psid Revert
488 @param[in] PopUpString Pop up string.
489 @param[in] PopUpString2 Pop up string in line 2.
490 @param[in] PopUpString3 Pop up string in line 3.
492 @param[out] PressEsc Whether user escape function through Press ESC.
494 @retval Psid string if success. NULL if failed.
498 OpalDriverPopUpPsidInput (
499 IN OPAL_DRIVER_DEVICE
*Dev
,
500 IN CHAR16
*PopUpString
,
501 IN CHAR16
*PopUpString2
,
502 IN CHAR16
*PopUpString3
,
503 OUT BOOLEAN
*PressEsc
506 EFI_INPUT_KEY InputKey
;
508 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
509 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
512 ZeroMem(Unicode
, sizeof(Unicode
));
513 ZeroMem(Mask
, sizeof(Mask
));
517 gST
->ConOut
->ClearScreen(gST
->ConOut
);
521 Mask
[InputLength
] = L
'_';
522 if (PopUpString2
== NULL
) {
524 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
527 L
"---------------------",
532 if (PopUpString3
== NULL
) {
534 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
538 L
"---------------------",
544 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
549 L
"---------------------",
559 if (InputKey
.ScanCode
== SCAN_NULL
) {
563 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
565 // Add the null terminator.
567 Unicode
[InputLength
] = 0;
568 Mask
[InputLength
] = 0;
570 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
571 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
572 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
577 // delete last key entered
579 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
580 if (InputLength
> 0) {
581 Unicode
[InputLength
] = 0;
582 Mask
[InputLength
] = 0;
587 // add Next key entry
589 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
590 Mask
[InputLength
] = InputKey
.UnicodeChar
;
592 if (InputLength
== PSID_CHARACTER_LENGTH
) {
594 // Add the null terminator.
596 Unicode
[InputLength
] = 0;
597 Mask
[InputLength
] = 0;
607 if (InputKey
.ScanCode
== SCAN_ESC
) {
613 gST
->ConOut
->ClearScreen(gST
->ConOut
);
615 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
616 ZeroMem (Unicode
, sizeof (Unicode
));
617 ZeroMem (Mask
, sizeof (Mask
));
621 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
623 ZeroMem (Unicode
, sizeof (Unicode
));
624 ZeroMem (Mask
, sizeof (Mask
));
628 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
629 ZeroMem (Unicode
, sizeof (Unicode
));
630 ZeroMem (Mask
, sizeof (Mask
));
637 Get password input from the popup window.
639 @param[in] Dev The device which need password to unlock or
640 process OPAL request.
641 @param[in] PopUpString1 Pop up string 1.
642 @param[in] PopUpString2 Pop up string 2.
643 @param[in] PopUpString3 Pop up string 3.
644 @param[out] PressEsc Whether user escape function through Press ESC.
646 @retval Password string if success. NULL if failed.
650 OpalDriverPopUpPasswordInput (
651 IN OPAL_DRIVER_DEVICE
*Dev
,
652 IN CHAR16
*PopUpString1
,
653 IN CHAR16
*PopUpString2
,
654 IN CHAR16
*PopUpString3
,
655 OUT BOOLEAN
*PressEsc
658 EFI_INPUT_KEY InputKey
;
660 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
661 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
664 ZeroMem(Unicode
, sizeof(Unicode
));
665 ZeroMem(Mask
, sizeof(Mask
));
669 gST
->ConOut
->ClearScreen(gST
->ConOut
);
673 Mask
[InputLength
] = L
'_';
674 if (PopUpString2
== NULL
) {
676 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
679 L
"---------------------",
684 if (PopUpString3
== NULL
) {
686 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
690 L
"---------------------",
696 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
701 L
"---------------------",
711 if (InputKey
.ScanCode
== SCAN_NULL
) {
715 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
717 // Add the null terminator.
719 Unicode
[InputLength
] = 0;
720 Mask
[InputLength
] = 0;
722 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
723 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
724 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
729 // delete last key entered
731 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
732 if (InputLength
> 0) {
733 Unicode
[InputLength
] = 0;
734 Mask
[InputLength
] = 0;
739 // add Next key entry
741 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
742 Mask
[InputLength
] = L
'*';
744 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
746 // Add the null terminator.
748 Unicode
[InputLength
] = 0;
749 Mask
[InputLength
] = 0;
759 if (InputKey
.ScanCode
== SCAN_ESC
) {
765 gST
->ConOut
->ClearScreen(gST
->ConOut
);
767 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
768 ZeroMem (Unicode
, sizeof (Unicode
));
772 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
774 ZeroMem (Unicode
, sizeof (Unicode
));
778 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
779 ZeroMem (Unicode
, sizeof (Unicode
));
787 @param[in] Dev The OPAL device.
788 @param[in] RequestString Request string.
790 @return Pop up string.
795 IN OPAL_DRIVER_DEVICE
*Dev
,
796 IN CHAR16
*RequestString
799 if (Dev
->Name16
== NULL
) {
800 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
802 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
809 Check if disk is locked, show popup window and ask for password if it is.
811 @param[in] Dev The device which need to be unlocked.
812 @param[in] RequestString Request string.
816 OpalDriverRequestPassword (
817 IN OPAL_DRIVER_DEVICE
*Dev
,
818 IN CHAR16
*RequestString
826 OPAL_SESSION Session
;
836 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
838 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
842 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
844 ZeroMem(&Session
, sizeof(Session
));
845 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
846 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
847 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
849 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
851 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
855 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
856 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
860 // Current device in the lock status and
861 // User not input password and press ESC,
862 // keep device in lock status and continue boot.
866 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
868 L
"Press ENTER to skip the request and continue boot,",
869 L
"Press ESC to input password again",
872 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
874 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
875 gST
->ConOut
->ClearScreen(gST
->ConOut
);
877 // Keep lock and continue boot.
882 // Let user input password again.
888 // Current device in the unlock status and
889 // User not input password and press ESC,
890 // Shutdown the device.
894 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
896 L
"Press ENTER to shutdown, Press ESC to input password again",
899 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
901 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
902 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
905 // Let user input password again.
912 if (Password
== NULL
) {
916 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
919 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
921 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
922 if (Ret
== TcgResultSuccess
) {
923 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
927 if (Ret
== TcgResultSuccess
) {
928 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
929 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
931 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
934 if (Password
!= NULL
) {
935 ZeroMem (Password
, PasswordLen
);
939 if (Ret
== TcgResultSuccess
) {
944 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
945 // before accept new password.
947 if (Ret
== TcgResultFailureInvalidType
) {
948 Count
= MAX_PASSWORD_TRY_COUNT
;
956 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
958 L
"Invalid password.",
959 L
"Press ENTER to retry",
962 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
965 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
968 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
970 L
"Opal password retry count exceeds the limit. Must shutdown!",
971 L
"Press ENTER to shutdown",
974 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
976 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
982 Process Enable Feature OPAL request.
984 @param[in] Dev The device which has Enable Feature OPAL request.
985 @param[in] RequestString Request string.
989 ProcessOpalRequestEnableFeature (
990 IN OPAL_DRIVER_DEVICE
*Dev
,
991 IN CHAR16
*RequestString
997 CHAR8
*PasswordConfirm
;
998 UINT32 PasswordLenConfirm
;
999 OPAL_SESSION Session
;
1003 CHAR16
*PopUpString
;
1009 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1011 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1015 ZeroMem(&Session
, sizeof(Session
));
1016 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1017 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1018 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1020 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1021 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1025 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1027 L
"Press ENTER to skip the request and continue boot,",
1028 L
"Press ESC to input password again",
1031 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1033 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1034 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1038 // Let user input password again.
1044 if (Password
== NULL
) {
1048 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1050 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1051 if (PasswordConfirm
== NULL
) {
1052 ZeroMem (Password
, PasswordLen
);
1053 FreePool (Password
);
1057 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1058 if ((PasswordLen
!= PasswordLenConfirm
) ||
1059 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1060 ZeroMem (Password
, PasswordLen
);
1061 FreePool (Password
);
1062 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1063 FreePool (PasswordConfirm
);
1066 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1068 L
"Passwords are not the same.",
1069 L
"Press ENTER to retry",
1072 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1077 if (PasswordConfirm
!= NULL
) {
1078 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1079 FreePool (PasswordConfirm
);
1082 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1083 if (Ret
== TcgResultSuccess
) {
1084 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1085 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1087 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1090 if (Password
!= NULL
) {
1091 ZeroMem (Password
, PasswordLen
);
1092 FreePool (Password
);
1095 if (Ret
== TcgResultSuccess
) {
1103 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1106 L
"Press ENTER to retry",
1109 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1112 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1115 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1117 L
"Opal password retry count exceeds the limit.",
1118 L
"Press ENTER to skip the request and continue boot",
1121 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1122 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1127 Process Disable User OPAL request.
1129 @param[in] Dev The device which has Disable User OPAL request.
1130 @param[in] RequestString Request string.
1134 ProcessOpalRequestDisableUser (
1135 IN OPAL_DRIVER_DEVICE
*Dev
,
1136 IN CHAR16
*RequestString
1142 OPAL_SESSION Session
;
1146 BOOLEAN PasswordFailed
;
1147 CHAR16
*PopUpString
;
1153 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1155 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1159 ZeroMem(&Session
, sizeof(Session
));
1160 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1161 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1162 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1164 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1165 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, NULL
, &PressEsc
);
1169 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1171 L
"Press ENTER to skip the request and continue boot,",
1172 L
"Press ESC to input password again",
1175 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1177 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1178 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1182 // Let user input password again.
1188 if (Password
== NULL
) {
1192 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1194 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1195 if (Ret
== TcgResultSuccess
) {
1196 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1197 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1199 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1202 if (Password
!= NULL
) {
1203 ZeroMem (Password
, PasswordLen
);
1204 FreePool (Password
);
1207 if (Ret
== TcgResultSuccess
) {
1215 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1217 L
"Invalid password, request failed.",
1218 L
"Press ENTER to retry",
1221 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1224 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1227 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1229 L
"Opal password retry count exceeds the limit.",
1230 L
"Press ENTER to skip the request and continue boot",
1233 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1234 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1239 Process Psid Revert OPAL request.
1241 @param[in] Dev The device which has Psid Revert OPAL request.
1242 @param[in] RequestString Request string.
1246 ProcessOpalRequestPsidRevert (
1247 IN OPAL_DRIVER_DEVICE
*Dev
,
1248 IN CHAR16
*RequestString
1254 OPAL_SESSION Session
;
1258 CHAR16
*PopUpString
;
1259 CHAR16
*PopUpString2
;
1260 CHAR16
*PopUpString3
;
1267 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1269 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1271 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1272 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1273 PopUpString2
= AllocateZeroPool (BufferSize
);
1274 ASSERT (PopUpString2
!= NULL
);
1278 L
"WARNING: Revert action will take about %d seconds",
1279 Dev
->OpalDisk
.EstimateTimeCost
1281 PopUpString3
= L
"DO NOT power off system during the revert action!";
1283 PopUpString2
= NULL
;
1284 PopUpString3
= NULL
;
1289 ZeroMem(&Session
, sizeof(Session
));
1290 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1291 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1292 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1294 while (Count
< MAX_PSID_TRY_COUNT
) {
1295 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1299 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1301 L
"Press ENTER to skip the request and continue boot,",
1302 L
"Press ESC to input Psid again",
1305 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1307 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1308 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1312 // Let user input Psid again.
1322 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1324 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1325 if (Ret
== TcgResultSuccess
) {
1326 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1328 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1332 ZeroMem (Psid
, PsidLen
);
1336 if (Ret
== TcgResultSuccess
) {
1344 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1346 L
"Invalid Psid, request failed.",
1347 L
"Press ENTER to retry",
1350 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1353 if (Count
>= MAX_PSID_TRY_COUNT
) {
1356 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1358 L
"Opal Psid retry count exceeds the limit.",
1359 L
"Press ENTER to skip the request and continue boot",
1362 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1363 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1367 if (PopUpString2
!= NULL
) {
1368 FreePool (PopUpString2
);
1373 Process Admin Revert OPAL request.
1375 @param[in] Dev The device which has Revert OPAL request.
1376 @param[in] KeepUserData Whether to keep user data or not.
1377 @param[in] RequestString Request string.
1381 ProcessOpalRequestRevert (
1382 IN OPAL_DRIVER_DEVICE
*Dev
,
1383 IN BOOLEAN KeepUserData
,
1384 IN CHAR16
*RequestString
1390 OPAL_SESSION Session
;
1394 BOOLEAN PasswordFailed
;
1395 CHAR16
*PopUpString
;
1396 CHAR16
*PopUpString2
;
1397 CHAR16
*PopUpString3
;
1404 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1406 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1408 if ((!KeepUserData
) &&
1409 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1410 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds");
1411 PopUpString2
= AllocateZeroPool (BufferSize
);
1412 ASSERT (PopUpString2
!= NULL
);
1416 L
"WARNING: Revert action will take about %d seconds",
1417 Dev
->OpalDisk
.EstimateTimeCost
1419 PopUpString3
= L
"DO NOT power off system during the revert action!";
1421 PopUpString2
= NULL
;
1422 PopUpString3
= NULL
;
1427 ZeroMem(&Session
, sizeof(Session
));
1428 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1429 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1430 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1432 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1433 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1437 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1439 L
"Press ENTER to skip the request and continue boot,",
1440 L
"Press ESC to input password again",
1443 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1445 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1446 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1450 // Let user input password again.
1456 if (Password
== NULL
) {
1460 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1462 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1463 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1465 // For pyrite type device which does not support media encryption,
1466 // it does not accept "Keep User Data" parameter.
1467 // So here hardcode a FALSE for this case.
1469 Ret
= OpalUtilRevert(
1476 Dev
->OpalDisk
.MsidLength
1479 Ret
= OpalUtilRevert(
1486 Dev
->OpalDisk
.MsidLength
1489 if (Ret
== TcgResultSuccess
) {
1490 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1491 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1493 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1496 if (Password
!= NULL
) {
1497 ZeroMem (Password
, PasswordLen
);
1498 FreePool (Password
);
1501 if (Ret
== TcgResultSuccess
) {
1509 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1511 L
"Invalid password, request failed.",
1512 L
"Press ENTER to retry",
1515 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1518 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1521 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1523 L
"Opal password retry count exceeds the limit.",
1524 L
"Press ENTER to skip the request and continue boot",
1527 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1528 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1532 if (PopUpString2
!= NULL
) {
1533 FreePool (PopUpString2
);
1538 Process Secure Erase OPAL request.
1540 @param[in] Dev The device which has Secure Erase OPAL request.
1541 @param[in] RequestString Request string.
1545 ProcessOpalRequestSecureErase (
1546 IN OPAL_DRIVER_DEVICE
*Dev
,
1547 IN CHAR16
*RequestString
1553 OPAL_SESSION Session
;
1557 BOOLEAN PasswordFailed
;
1558 CHAR16
*PopUpString
;
1559 CHAR16
*PopUpString2
;
1560 CHAR16
*PopUpString3
;
1567 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1569 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1571 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1572 BufferSize
= StrSize (L
"Warning: Secure erase action will take about ####### seconds");
1573 PopUpString2
= AllocateZeroPool (BufferSize
);
1574 ASSERT (PopUpString2
!= NULL
);
1578 L
"WARNING: Secure erase action will take about %d seconds",
1579 Dev
->OpalDisk
.EstimateTimeCost
1581 PopUpString3
= L
"DO NOT power off system during the action!";
1583 PopUpString2
= NULL
;
1584 PopUpString3
= NULL
;
1588 ZeroMem(&Session
, sizeof(Session
));
1589 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1590 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1591 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1593 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1594 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, PopUpString3
, &PressEsc
);
1598 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1600 L
"Press ENTER to skip the request and continue boot,",
1601 L
"Press ESC to input password again",
1604 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1606 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1607 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1611 // Let user input password again.
1617 if (Password
== NULL
) {
1621 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1623 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1624 if (Ret
== TcgResultSuccess
) {
1625 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1626 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1628 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1631 if (Password
!= NULL
) {
1632 ZeroMem (Password
, PasswordLen
);
1633 FreePool (Password
);
1636 if (Ret
== TcgResultSuccess
) {
1644 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1646 L
"Invalid password, request failed.",
1647 L
"Press ENTER to retry",
1650 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1653 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1656 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1658 L
"Opal password retry count exceeds the limit.",
1659 L
"Press ENTER to skip the request and continue boot",
1662 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1663 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1667 if (PopUpString2
!= NULL
) {
1668 FreePool (PopUpString2
);
1673 Process Set Admin Pwd OPAL request.
1675 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1676 @param[in] RequestString Request string.
1680 ProcessOpalRequestSetUserPwd (
1681 IN OPAL_DRIVER_DEVICE
*Dev
,
1682 IN CHAR16
*RequestString
1687 UINT32 OldPasswordLen
;
1690 CHAR8
*PasswordConfirm
;
1691 UINT32 PasswordLenConfirm
;
1692 OPAL_SESSION Session
;
1696 CHAR16
*PopUpString
;
1702 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1704 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1708 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1709 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1713 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1715 L
"Press ENTER to skip the request and continue boot,",
1716 L
"Press ESC to input password again",
1719 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1721 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1722 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1726 // Let user input password again.
1732 if (OldPassword
== NULL
) {
1736 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1738 ZeroMem(&Session
, sizeof(Session
));
1739 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1740 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1741 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1742 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1743 if (Ret
== TcgResultSuccess
) {
1744 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1746 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1747 if (Ret
== TcgResultSuccess
) {
1748 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1750 ZeroMem (OldPassword
, OldPasswordLen
);
1751 FreePool (OldPassword
);
1752 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1755 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1757 L
"Incorrect password.",
1758 L
"Press ENTER to retry",
1761 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1767 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1768 if (Password
== NULL
) {
1769 ZeroMem (OldPassword
, OldPasswordLen
);
1770 FreePool (OldPassword
);
1774 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1776 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1777 if (PasswordConfirm
== NULL
) {
1778 ZeroMem (OldPassword
, OldPasswordLen
);
1779 FreePool (OldPassword
);
1780 ZeroMem (Password
, PasswordLen
);
1781 FreePool (Password
);
1785 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1786 if ((PasswordLen
!= PasswordLenConfirm
) ||
1787 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1788 ZeroMem (OldPassword
, OldPasswordLen
);
1789 FreePool (OldPassword
);
1790 ZeroMem (Password
, PasswordLen
);
1791 FreePool (Password
);
1792 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1793 FreePool (PasswordConfirm
);
1796 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1798 L
"Passwords are not the same.",
1799 L
"Press ENTER to retry",
1802 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1807 if (PasswordConfirm
!= NULL
) {
1808 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1809 FreePool (PasswordConfirm
);
1812 ZeroMem(&Session
, sizeof(Session
));
1813 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1814 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1815 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1816 Ret
= OpalUtilSetUserPassword(
1823 if (Ret
== TcgResultSuccess
) {
1824 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1825 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1827 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1830 if (OldPassword
!= NULL
) {
1831 ZeroMem (OldPassword
, OldPasswordLen
);
1832 FreePool (OldPassword
);
1835 if (Password
!= NULL
) {
1836 ZeroMem (Password
, PasswordLen
);
1837 FreePool (Password
);
1840 if (Ret
== TcgResultSuccess
) {
1848 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1851 L
"Press ENTER to retry",
1854 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1857 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1860 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1862 L
"Opal password retry count exceeds the limit.",
1863 L
"Press ENTER to skip the request and continue boot",
1866 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1867 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1872 Process Set Admin Pwd OPAL request.
1874 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1875 @param[in] RequestString Request string.
1879 ProcessOpalRequestSetAdminPwd (
1880 IN OPAL_DRIVER_DEVICE
*Dev
,
1881 IN CHAR16
*RequestString
1886 UINT32 OldPasswordLen
;
1889 CHAR8
*PasswordConfirm
;
1890 UINT32 PasswordLenConfirm
;
1891 OPAL_SESSION Session
;
1895 CHAR16
*PopUpString
;
1901 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1903 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1907 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1908 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", NULL
, &PressEsc
);
1912 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1914 L
"Press ENTER to skip the request and continue boot,",
1915 L
"Press ESC to input password again",
1918 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1920 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1921 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1925 // Let user input password again.
1931 if (OldPassword
== NULL
) {
1935 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1937 ZeroMem(&Session
, sizeof(Session
));
1938 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1939 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1940 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1941 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1942 if (Ret
== TcgResultSuccess
) {
1943 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1945 ZeroMem (OldPassword
, OldPasswordLen
);
1946 FreePool (OldPassword
);
1947 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1950 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1952 L
"Incorrect password.",
1953 L
"Press ENTER to retry",
1956 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1961 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", NULL
, &PressEsc
);
1962 if (Password
== NULL
) {
1963 ZeroMem (OldPassword
, OldPasswordLen
);
1964 FreePool (OldPassword
);
1968 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1970 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", NULL
, &PressEsc
);
1971 if (PasswordConfirm
== NULL
) {
1972 ZeroMem (OldPassword
, OldPasswordLen
);
1973 FreePool (OldPassword
);
1974 ZeroMem (Password
, PasswordLen
);
1975 FreePool (Password
);
1979 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1980 if ((PasswordLen
!= PasswordLenConfirm
) ||
1981 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1982 ZeroMem (OldPassword
, OldPasswordLen
);
1983 FreePool (OldPassword
);
1984 ZeroMem (Password
, PasswordLen
);
1985 FreePool (Password
);
1986 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1987 FreePool (PasswordConfirm
);
1990 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1992 L
"Passwords are not the same.",
1993 L
"Press ENTER to retry",
1996 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2001 if (PasswordConfirm
!= NULL
) {
2002 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2003 FreePool (PasswordConfirm
);
2007 ZeroMem(&Session
, sizeof(Session
));
2008 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2009 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2010 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2011 Ret
= OpalUtilSetAdminPassword(
2018 if (Ret
== TcgResultSuccess
) {
2019 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2020 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2022 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2025 if (OldPassword
!= NULL
) {
2026 ZeroMem (OldPassword
, OldPasswordLen
);
2027 FreePool (OldPassword
);
2030 if (Password
!= NULL
) {
2031 ZeroMem (Password
, PasswordLen
);
2032 FreePool (Password
);
2035 if (Ret
== TcgResultSuccess
) {
2043 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2046 L
"Press ENTER to retry",
2049 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2052 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2055 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2057 L
"Opal password retry count exceeds the limit.",
2058 L
"Press ENTER to skip the request and continue boot",
2061 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2062 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2067 Process OPAL request.
2069 @param[in] Dev The device which has OPAL request.
2073 ProcessOpalRequest (
2074 IN OPAL_DRIVER_DEVICE
*Dev
2078 OPAL_REQUEST_VARIABLE
*TempVariable
;
2079 OPAL_REQUEST_VARIABLE
*Variable
;
2081 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2082 UINTN DevicePathSizeInVariable
;
2083 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2084 UINTN DevicePathSize
;
2085 BOOLEAN KeepUserData
;
2087 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2089 if (mOpalRequestVariable
== NULL
) {
2090 Status
= GetVariable2 (
2091 OPAL_REQUEST_VARIABLE_NAME
,
2092 &gHiiSetupVariableGuid
,
2093 (VOID
**) &Variable
,
2096 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2099 mOpalRequestVariable
= Variable
;
2100 mOpalRequestVariableSize
= VariableSize
;
2103 // Delete the OPAL request variable.
2105 Status
= gRT
->SetVariable (
2106 OPAL_REQUEST_VARIABLE_NAME
,
2107 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2112 ASSERT_EFI_ERROR (Status
);
2114 Variable
= mOpalRequestVariable
;
2115 VariableSize
= mOpalRequestVariableSize
;
2119 // Process the OPAL requests.
2121 TempVariable
= Variable
;
2122 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2123 (VariableSize
>= TempVariable
->Length
) &&
2124 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2125 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2126 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2127 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2128 DevicePathSize
= GetDevicePathSize (DevicePath
);
2129 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2130 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2132 // Found the node for the OPAL device.
2134 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2135 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2137 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2138 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2140 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2141 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2143 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2144 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2145 ProcessOpalRequestRevert (
2148 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2151 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2152 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2154 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2155 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2157 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2158 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2164 VariableSize
-= TempVariable
->Length
;
2165 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2168 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2172 Add new device to the global device list.
2174 @param Dev New create device.
2179 IN OPAL_DRIVER_DEVICE
*Dev
2182 OPAL_DRIVER_DEVICE
*TmpDev
;
2184 if (mOpalDriver
.DeviceList
== NULL
) {
2185 mOpalDriver
.DeviceList
= Dev
;
2187 TmpDev
= mOpalDriver
.DeviceList
;
2188 while (TmpDev
->Next
!= NULL
) {
2189 TmpDev
= TmpDev
->Next
;
2197 Remove one device in the global device list.
2199 @param Dev The device need to be removed.
2204 IN OPAL_DRIVER_DEVICE
*Dev
2207 OPAL_DRIVER_DEVICE
*TmpDev
;
2209 if (mOpalDriver
.DeviceList
== NULL
) {
2213 if (mOpalDriver
.DeviceList
== Dev
) {
2214 mOpalDriver
.DeviceList
= NULL
;
2218 TmpDev
= mOpalDriver
.DeviceList
;
2219 while (TmpDev
->Next
!= NULL
) {
2220 if (TmpDev
->Next
== Dev
) {
2221 TmpDev
->Next
= Dev
->Next
;
2228 Get current device count.
2230 @retval return the current created device count.
2239 OPAL_DRIVER_DEVICE
*TmpDev
;
2242 TmpDev
= mOpalDriver
.DeviceList
;
2244 while (TmpDev
!= NULL
) {
2246 TmpDev
= TmpDev
->Next
;
2253 Get devcie list info.
2255 @retval return the device list pointer.
2258 OpalDriverGetDeviceList(
2262 return mOpalDriver
.DeviceList
;
2266 ReadyToBoot callback to send BlockSid command.
2268 @param Event Pointer to this event
2269 @param Context Event handler private Data
2274 ReadyToBootCallback (
2279 OPAL_DRIVER_DEVICE
*Itr
;
2281 OPAL_SESSION Session
;
2282 UINT32 PpStorageFlag
;
2284 gBS
->CloseEvent (Event
);
2286 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2287 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2289 // Send BlockSID command to each Opal disk
2291 Itr
= mOpalDriver
.DeviceList
;
2292 while (Itr
!= NULL
) {
2293 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2294 ZeroMem(&Session
, sizeof(Session
));
2295 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2296 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2297 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2299 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2300 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2301 if (Result
!= TcgResultSuccess
) {
2302 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2313 Stop this Controller.
2315 @param Dev The device need to be stopped.
2319 OpalDriverStopDevice (
2320 OPAL_DRIVER_DEVICE
*Dev
2326 FreePool(Dev
->Name16
);
2329 // remove OPAL_DRIVER_DEVICE from the list
2330 // it updates the controllerList pointer
2335 // close protocols that were opened
2339 &gEfiStorageSecurityCommandProtocolGuid
,
2340 gOpalDriverBinding
.DriverBindingHandle
,
2346 &gEfiBlockIoProtocolGuid
,
2347 gOpalDriverBinding
.DriverBindingHandle
,
2355 Get devcie name through the component name protocol.
2357 @param[in] AllHandlesBuffer The handle buffer for current system.
2358 @param[in] NumAllHandles The number of handles for the handle buffer.
2359 @param[in] Dev The device which need to get name.
2360 @param[in] UseComp1 Whether use component name or name2 protocol.
2362 @retval TRUE Find the name for this device.
2363 @retval FALSE Not found the name for this device.
2366 OpalDriverGetDeviceNameByProtocol(
2367 EFI_HANDLE
*AllHandlesBuffer
,
2368 UINTN NumAllHandles
,
2369 OPAL_DRIVER_DEVICE
*Dev
,
2373 EFI_HANDLE
* ProtocolHandlesBuffer
;
2374 UINTN NumProtocolHandles
;
2376 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2379 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2382 EFI_HANDLE TmpHandle
;
2385 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2389 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2392 // Find all EFI_HANDLES with protocol
2394 Status
= gBS
->LocateHandleBuffer(
2398 &NumProtocolHandles
,
2399 &ProtocolHandlesBuffer
2401 if (EFI_ERROR(Status
)) {
2407 // Exit early if no supported devices
2409 if (NumProtocolHandles
== 0) {
2414 // Get printable name by iterating through all protocols
2415 // using the handle as the child, and iterate through all handles for the controller
2416 // exit loop early once found, if not found, then delete device
2417 // storage security protocol instances already exist, add them to internal list
2419 Status
= EFI_DEVICE_ERROR
;
2420 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2423 if (Dev
->Name16
!= NULL
) {
2427 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2429 Status
= gBS
->OpenProtocol(
2435 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2437 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2442 // Use all handles array as controller handle
2444 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2445 Status
= Cnp1_2
->GetControllerName(
2447 AllHandlesBuffer
[Index2
],
2449 LANGUAGE_ISO_639_2_ENGLISH
,
2452 if (EFI_ERROR(Status
)) {
2453 Status
= Cnp1_2
->GetControllerName(
2455 AllHandlesBuffer
[Index2
],
2457 LANGUAGE_RFC_3066_ENGLISH
,
2461 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2462 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2463 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2464 ASSERT (Dev
->Name16
!= NULL
);
2465 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2466 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2467 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2470 // Retrieve bridge BDF info and port number or namespace depending on type
2473 Status
= gBS
->OpenProtocol(
2475 &gEfiDevicePathProtocolGuid
,
2476 (VOID
**)&TmpDevPath
,
2479 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2481 if (!EFI_ERROR(Status
)) {
2482 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2486 if (Dev
->Name16
!= NULL
) {
2487 FreePool(Dev
->Name16
);
2490 if (Dev
->NameZ
!= NULL
) {
2491 FreePool(Dev
->NameZ
);
2502 Get devcie name through the component name protocol.
2504 @param[in] Dev The device which need to get name.
2506 @retval TRUE Find the name for this device.
2507 @retval FALSE Not found the name for this device.
2510 OpalDriverGetDriverDeviceName(
2511 OPAL_DRIVER_DEVICE
*Dev
2514 EFI_HANDLE
* AllHandlesBuffer
;
2515 UINTN NumAllHandles
;
2519 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2524 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2526 if (Dev
->Name16
== NULL
) {
2527 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2529 // Find all EFI_HANDLES
2531 Status
= gBS
->LocateHandleBuffer(
2538 if (EFI_ERROR(Status
)) {
2539 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2544 // Try component Name2
2546 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2547 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2548 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2549 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2559 Main entry for this driver.
2561 @param ImageHandle Image Handle this driver.
2562 @param SystemTable Pointer to SystemTable.
2564 @retval EFI_SUCESS This function always complete successfully.
2568 EfiDriverEntryPoint(
2569 IN EFI_HANDLE ImageHandle
,
2570 IN EFI_SYSTEM_TABLE
* SystemTable
2574 EFI_EVENT ReadyToBootEvent
;
2575 EFI_EVENT EndOfDxeEvent
;
2577 Status
= EfiLibInstallDriverBindingComponentName2 (
2580 &gOpalDriverBinding
,
2582 &gOpalComponentName
,
2583 &gOpalComponentName2
2586 if (EFI_ERROR(Status
)) {
2587 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2592 // Initialize Driver object
2594 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2595 mOpalDriver
.Handle
= ImageHandle
;
2597 Status
= gBS
->CreateEventEx (
2600 OpalEndOfDxeEventNotify
,
2602 &gEfiEndOfDxeEventGroupGuid
,
2605 ASSERT_EFI_ERROR (Status
);
2608 // register a ReadyToBoot event callback for sending BlockSid command
2610 Status
= EfiCreateEventReadyToBootEx (
2612 ReadyToBootCallback
,
2613 (VOID
*) &ImageHandle
,
2618 // Install Hii packages.
2626 Tests to see if this driver supports a given controller.
2628 This function checks to see if the controller contains an instance of the
2629 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2630 and returns EFI_SUCCESS if it does.
2632 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2633 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2634 must support a protocol interface that supplies
2635 an I/O abstraction to the driver.
2636 @param[in] RemainingDevicePath This parameter is ignored.
2638 @retval EFI_SUCCESS The device contains required protocols
2639 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2640 RemainingDevicePath is already being managed by the driver
2642 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2643 RemainingDevicePath is already being managed by a different
2644 driver or an application that requires exclusive access.
2645 Currently not implemented.
2646 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2651 OpalEfiDriverBindingSupported(
2652 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2653 IN EFI_HANDLE Controller
,
2654 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2658 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2659 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2661 if (mOpalEndOfDxe
) {
2662 return EFI_UNSUPPORTED
;
2666 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2668 Status
= gBS
->OpenProtocol(
2670 &gEfiStorageSecurityCommandProtocolGuid
,
2671 ( VOID
** )&SecurityCommand
,
2672 This
->DriverBindingHandle
,
2674 EFI_OPEN_PROTOCOL_BY_DRIVER
2677 if (Status
== EFI_ALREADY_STARTED
) {
2681 if (EFI_ERROR(Status
)) {
2686 // Close protocol and reopen in Start call
2690 &gEfiStorageSecurityCommandProtocolGuid
,
2691 This
->DriverBindingHandle
,
2696 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2699 Status
= gBS
->OpenProtocol(
2701 &gEfiBlockIoProtocolGuid
,
2703 This
->DriverBindingHandle
,
2705 EFI_OPEN_PROTOCOL_BY_DRIVER
2708 if (EFI_ERROR(Status
)) {
2709 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2714 // Close protocol and reopen in Start call
2718 &gEfiBlockIoProtocolGuid
,
2719 This
->DriverBindingHandle
,
2727 Enables Opal Management on a supported device if available.
2729 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2730 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2731 This function will complete the other necessary checks, such as verifying the device supports
2732 the correct version of Opal. Upon verification, it will add the device to the
2733 Opal HII list in order to expose Opal managmeent options.
2735 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2736 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2737 must support a protocol interface that supplies
2738 an I/O abstraction to the driver.
2739 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2740 parameter is ignored by device drivers, and is optional for bus
2741 drivers. For a bus driver, if this parameter is NULL, then handles
2742 for all the children of Controller are created by this driver.
2743 If this parameter is not NULL and the first Device Path Node is
2744 not the End of Device Path Node, then only the Handle for the
2745 child device specified by the first Device Path Node of
2746 RemainingDevicePath is created by this driver.
2747 If the first Device Path Node of RemainingDevicePath is
2748 the End of Device Path Node, no child Handle is created by this
2751 @retval EFI_SUCCESS Opal management was enabled.
2752 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2753 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2754 @retval Others The driver failed to start the device.
2759 OpalEfiDriverBindingStart(
2760 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2761 IN EFI_HANDLE Controller
,
2762 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2766 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2767 OPAL_DRIVER_DEVICE
*Dev
;
2768 OPAL_DRIVER_DEVICE
*Itr
;
2771 Itr
= mOpalDriver
.DeviceList
;
2772 while (Itr
!= NULL
) {
2773 if (Controller
== Itr
->Handle
) {
2780 // Create internal device for tracking. This allows all disks to be tracked
2783 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2785 return EFI_OUT_OF_RESOURCES
;
2787 Dev
->Handle
= Controller
;
2790 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2792 Status
= gBS
->OpenProtocol(
2794 &gEfiStorageSecurityCommandProtocolGuid
,
2795 (VOID
**)&Dev
->Sscp
,
2796 This
->DriverBindingHandle
,
2798 EFI_OPEN_PROTOCOL_BY_DRIVER
2800 if (EFI_ERROR(Status
)) {
2806 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2809 Status
= gBS
->OpenProtocol(
2811 &gEfiBlockIoProtocolGuid
,
2813 This
->DriverBindingHandle
,
2815 EFI_OPEN_PROTOCOL_BY_DRIVER
2817 if (EFI_ERROR(Status
)) {
2819 // Close storage security that was opened
2823 &gEfiStorageSecurityCommandProtocolGuid
,
2824 This
->DriverBindingHandle
,
2835 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2839 &gEfiBlockIoProtocolGuid
,
2840 This
->DriverBindingHandle
,
2845 // Acquire Ascii printable name of child, if not found, then ignore device
2847 Result
= OpalDriverGetDriverDeviceName (Dev
);
2852 Status
= OpalDiskInitialize (Dev
);
2853 if (EFI_ERROR (Status
)) {
2857 AddDeviceToTail(Dev
);
2860 // Check if device is locked and prompt for password.
2862 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2865 // Process OPAL request from last boot.
2867 ProcessOpalRequest (Dev
);
2873 // free device, close protocols and exit
2877 &gEfiStorageSecurityCommandProtocolGuid
,
2878 This
->DriverBindingHandle
,
2884 return EFI_DEVICE_ERROR
;
2888 Stop this driver on Controller.
2890 @param This Protocol instance pointer.
2891 @param Controller Handle of device to stop driver on
2892 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2893 children is zero stop the entire bus driver.
2894 @param ChildHandleBuffer List of Child Handles to Stop.
2896 @retval EFI_SUCCESS This driver is removed Controller.
2897 @retval other This driver could not be removed from this device.
2902 OpalEfiDriverBindingStop(
2903 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2904 EFI_HANDLE Controller
,
2905 UINTN NumberOfChildren
,
2906 EFI_HANDLE
* ChildHandleBuffer
2909 OPAL_DRIVER_DEVICE
* Itr
;
2911 Itr
= mOpalDriver
.DeviceList
;
2914 // does Controller match any of the devices we are managing for Opal
2916 while (Itr
!= NULL
) {
2917 if (Itr
->Handle
== Controller
) {
2918 OpalDriverStopDevice (Itr
);
2925 return EFI_NOT_FOUND
;
2930 Unloads UEFI Driver. Very useful for debugging and testing.
2932 @param ImageHandle Image Handle this driver.
2934 @retval EFI_SUCCESS This function always complete successfully.
2935 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2939 OpalEfiDriverUnload (
2940 IN EFI_HANDLE ImageHandle
2944 OPAL_DRIVER_DEVICE
*Itr
;
2946 Status
= EFI_SUCCESS
;
2948 if (ImageHandle
!= gImageHandle
) {
2949 return (EFI_INVALID_PARAMETER
);
2953 // Uninstall any interface added to each device by us
2955 while (mOpalDriver
.DeviceList
) {
2956 Itr
= mOpalDriver
.DeviceList
;
2958 // Remove OPAL_DRIVER_DEVICE from the list
2959 // it updates the controllerList pointer
2961 OpalDriverStopDevice(Itr
);
2965 // Uninstall the HII capability
2967 Status
= HiiUninstall();