2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 // This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
17 // HII GUI to manage Opal features if the device is Opal capable
18 // If the Opal device is being managed by the UEFI Driver, it shall provide a popup
19 // window during boot requesting a user password
21 #include "OpalDriver.h"
24 EFI_GUID mOpalDeviceAtaGuid
= OPAL_DEVICE_ATA_GUID
;
25 EFI_GUID mOpalDeviceNvmeGuid
= OPAL_DEVICE_NVME_GUID
;
27 BOOLEAN mOpalEndOfDxe
= FALSE
;
28 OPAL_REQUEST_VARIABLE
*mOpalRequestVariable
= NULL
;
29 UINTN mOpalRequestVariableSize
= 0;
30 CHAR16 mPopUpString
[256];
34 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
35 } OPAL_HC_PCI_REGISTER_SAVE
;
38 // To unlock the Intel SATA controller at S3 Resume, restored the following registers.
40 const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate
[] = {
41 {0x9, S3BootScriptWidthUint8
},
42 {0x10, S3BootScriptWidthUint32
},
43 {0x14, S3BootScriptWidthUint32
},
44 {0x18, S3BootScriptWidthUint32
},
45 {0x1C, S3BootScriptWidthUint32
},
46 {0x20, S3BootScriptWidthUint32
},
47 {0x24, S3BootScriptWidthUint32
},
48 {0x3c, S3BootScriptWidthUint8
},
49 {0x3d, S3BootScriptWidthUint8
},
50 {0x40, S3BootScriptWidthUint16
},
51 {0x42, S3BootScriptWidthUint16
},
52 {0x92, S3BootScriptWidthUint16
},
53 {0x94, S3BootScriptWidthUint32
},
54 {0x9C, S3BootScriptWidthUint32
},
55 {0x4, S3BootScriptWidthUint16
},
58 OPAL_DRIVER mOpalDriver
;
63 EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding
= {
64 OpalEfiDriverBindingSupported
,
65 OpalEfiDriverBindingStart
,
66 OpalEfiDriverBindingStop
,
74 The function determines the available actions for the OPAL_DISK provided.
76 @param[in] SupportedAttributes The supported attributes for the device.
77 @param[in] LockingFeature The locking status for the device.
78 @param[in] OwnerShip The ownership for the device.
79 @param[out] AvalDiskActions Pointer to fill-out with appropriate disk actions.
84 OpalSupportGetAvailableActions(
85 IN OPAL_DISK_SUPPORT_ATTRIBUTE
*SupportedAttributes
,
86 IN TCG_LOCKING_FEATURE_DESCRIPTOR
*LockingFeature
,
88 OUT OPAL_DISK_ACTIONS
*AvalDiskActions
91 BOOLEAN ExistingPassword
;
93 NULL_CHECK(AvalDiskActions
);
95 AvalDiskActions
->AdminPass
= 1;
96 AvalDiskActions
->UserPass
= 0;
97 AvalDiskActions
->DisableUser
= 0;
98 AvalDiskActions
->Unlock
= 0;
101 // Revert is performed on locking sp, so only allow if locking sp is enabled
103 if (LockingFeature
->LockingEnabled
) {
104 AvalDiskActions
->Revert
= 1;
108 // Psid revert is available for any device with media encryption support
109 // Revert is allowed for any device with media encryption support, however it requires
111 if (SupportedAttributes
->MediaEncryption
) {
114 // Only allow psid revert if media encryption is enabled.
115 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
116 // intact and accessible
118 AvalDiskActions
->PsidRevert
= 1;
119 AvalDiskActions
->RevertKeepDataForced
= 0;
122 // Secure erase is performed by generating a new encryption key
123 // this is only available if encryption is supported
125 AvalDiskActions
->SecureErase
= 1;
127 AvalDiskActions
->PsidRevert
= 0;
128 AvalDiskActions
->SecureErase
= 0;
131 // If no media encryption is supported, then a revert (using password) will not
132 // erase the Data (since you can't generate a new encryption key)
134 AvalDiskActions
->RevertKeepDataForced
= 1;
137 if (LockingFeature
->Locked
) {
138 AvalDiskActions
->Unlock
= 1;
140 AvalDiskActions
->Unlock
= 0;
144 // Only allow user to set password if an admin password exists
146 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
147 AvalDiskActions
->UserPass
= ExistingPassword
;
150 // This will still show up even if there isn't a user, which is fine
152 AvalDiskActions
->DisableUser
= ExistingPassword
;
154 return TcgResultSuccess
;
158 Enable Opal Feature for the input device.
160 @param[in] Session The opal session for the opal device.
162 @param[in] MsidLength Msid Length
163 @param[in] Password Admin password
164 @param[in] PassLength Length of password in bytes
169 OpalSupportEnableOpalFeature (
170 IN OPAL_SESSION
*Session
,
172 IN UINT32 MsidLength
,
181 NULL_CHECK(Password
);
183 Ret
= OpalUtilSetAdminPasswordAsSid(
190 if (Ret
== TcgResultSuccess
) {
192 // Enable global locking range
194 Ret
= OpalUtilSetOpalLockingRange(
198 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
212 Update password for the Opal disk.
214 @param[in, out] OpalDisk The disk to update password.
215 @param[in] Password The input password.
216 @param[in] PasswordLength The input password length.
220 OpalSupportUpdatePassword (
221 IN OUT OPAL_DISK
*OpalDisk
,
223 IN UINT32 PasswordLength
226 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
227 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
231 Extract device info from the device path.
233 @param[in] DevicePath Device path info for the device.
234 @param[out] DevInfoLength Device information length needed.
235 @param[out] DevInfo Device information extracted.
241 ExtractDeviceInfoFromDevicePath (
242 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
243 OUT UINT16
*DevInfoLength
,
244 OUT OPAL_DEVICE_COMMON
*DevInfo OPTIONAL
247 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
248 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
249 PCI_DEVICE_PATH
*PciDevPath
;
252 OPAL_PCI_DEVICE
*PciDevice
;
253 OPAL_DEVICE_ATA
*DevInfoAta
;
254 OPAL_DEVICE_NVME
*DevInfoNvme
;
255 SATA_DEVICE_PATH
*SataDevPath
;
256 NVME_NAMESPACE_DEVICE_PATH
*NvmeDevPath
;
258 ASSERT (DevicePath
!= NULL
);
259 ASSERT (DevInfoLength
!= NULL
);
261 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
264 TmpDevPath
= DevicePath
;
269 while (!IsDevicePathEnd (TmpDevPath
)) {
270 if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_SATA_DP
) {
274 if (DevInfo
!= NULL
) {
275 SataDevPath
= (SATA_DEVICE_PATH
*) TmpDevPath
;
276 DevInfoAta
= (OPAL_DEVICE_ATA
*) DevInfo
;
277 DevInfoAta
->Port
= SataDevPath
->HBAPortNumber
;
278 DevInfoAta
->PortMultiplierPort
= SataDevPath
->PortMultiplierPortNumber
;
280 DeviceType
= OPAL_DEVICE_TYPE_ATA
;
281 *DevInfoLength
= sizeof (OPAL_DEVICE_ATA
);
283 } else if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
) {
287 if (DevInfo
!= NULL
) {
288 NvmeDevPath
= (NVME_NAMESPACE_DEVICE_PATH
*) TmpDevPath
;
289 DevInfoNvme
= (OPAL_DEVICE_NVME
*) DevInfo
;
290 DevInfoNvme
->NvmeNamespaceId
= NvmeDevPath
->NamespaceId
;
292 DeviceType
= OPAL_DEVICE_TYPE_NVME
;
293 *DevInfoLength
= sizeof (OPAL_DEVICE_NVME
);
296 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
303 TmpDevPath
= DevicePath
;
304 TmpDevPath2
= NextDevicePathNode (DevicePath
);
305 while (!IsDevicePathEnd (TmpDevPath2
)) {
306 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
307 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
308 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)||
309 (TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_SATA_DP
)) {
310 if (DevInfo
!= NULL
) {
311 PciDevice
= &DevInfo
->Device
;
312 PciDevice
->Segment
= 0;
313 PciDevice
->Bus
= BusNum
;
314 PciDevice
->Device
= PciDevPath
->Device
;
315 PciDevice
->Function
= PciDevPath
->Function
;
318 if (DevInfo
!= NULL
) {
319 PciDevice
= (OPAL_PCI_DEVICE
*) ((UINTN
) DevInfo
+ *DevInfoLength
);
320 PciDevice
->Segment
= 0;
321 PciDevice
->Bus
= BusNum
;
322 PciDevice
->Device
= PciDevPath
->Device
;
323 PciDevice
->Function
= PciDevPath
->Function
;
325 *DevInfoLength
+= sizeof (OPAL_PCI_DEVICE
);
326 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
327 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
332 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
333 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
336 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
341 Save boot script for ATA OPAL device.
343 @param[in] DevInfo Pointer to ATA Opal device information.
347 OpalDeviceAtaSaveBootScript (
348 IN OPAL_DEVICE_ATA
*DevInfo
358 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
360 OPAL_HC_PCI_REGISTER_SAVE
*HcRegisterSaveListPtr
;
365 Bus
= DevInfo
->Device
.Bus
;
366 Device
= DevInfo
->Device
.Device
;
367 Function
= DevInfo
->Device
.Function
;
369 HcRegisterSaveListPtr
= (OPAL_HC_PCI_REGISTER_SAVE
*) mSataHcRegisterSaveTemplate
;
370 Count
= sizeof (mSataHcRegisterSaveTemplate
) / sizeof (OPAL_HC_PCI_REGISTER_SAVE
);
372 for (Index
= 0; Index
< Count
; Index
++) {
373 Offset
= HcRegisterSaveListPtr
[Index
].Address
;
374 Width
= HcRegisterSaveListPtr
[Index
].Width
;
377 case S3BootScriptWidthUint8
:
378 Data
= (UINT32
)PciRead8 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
380 case S3BootScriptWidthUint16
:
381 Data
= (UINT32
)PciRead16 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
383 case S3BootScriptWidthUint32
:
384 Data
= PciRead32 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
391 Address
= S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus
, Device
, Function
, Offset
);
392 Status
= S3BootScriptSavePciCfgWrite (Width
, Address
, 1, &Data
);
393 ASSERT_EFI_ERROR (Status
);
398 Build ATA OPAL device info and save them to LockBox.
400 @param[in] BarAddr Bar address allocated.
404 BuildOpalDeviceInfoAta (
410 OPAL_DEVICE_ATA
*DevInfoAta
;
411 OPAL_DEVICE_ATA
*TempDevInfoAta
;
412 UINTN DevInfoLengthAta
;
413 UINT16 DevInfoLength
;
414 OPAL_DRIVER_DEVICE
*TmpDev
;
417 // Build ATA OPAL device info and save them to LockBox.
419 DevInfoLengthAta
= 0;
420 TmpDev
= mOpalDriver
.DeviceList
;
421 while (TmpDev
!= NULL
) {
422 DeviceType
= ExtractDeviceInfoFromDevicePath (
423 TmpDev
->OpalDisk
.OpalDevicePath
,
427 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
428 DevInfoLengthAta
+= DevInfoLength
;
431 TmpDev
= TmpDev
->Next
;
434 if (DevInfoLengthAta
== 0) {
438 DevInfoAta
= AllocateZeroPool (DevInfoLengthAta
);
439 ASSERT (DevInfoAta
!= NULL
);
441 TempDevInfoAta
= DevInfoAta
;
442 TmpDev
= mOpalDriver
.DeviceList
;
443 while (TmpDev
!= NULL
) {
444 DeviceType
= ExtractDeviceInfoFromDevicePath (
445 TmpDev
->OpalDisk
.OpalDevicePath
,
449 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
450 ExtractDeviceInfoFromDevicePath (
451 TmpDev
->OpalDisk
.OpalDevicePath
,
453 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
455 TempDevInfoAta
->Length
= DevInfoLength
;
456 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
457 TempDevInfoAta
->BarAddr
= BarAddr
;
459 TempDevInfoAta
->Password
,
460 TmpDev
->OpalDisk
.Password
,
461 TmpDev
->OpalDisk
.PasswordLength
463 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
464 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
465 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
468 TmpDev
= TmpDev
->Next
;
471 Status
= SaveLockBox (
476 ASSERT_EFI_ERROR (Status
);
478 Status
= SetLockBoxAttributes (
480 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
482 ASSERT_EFI_ERROR (Status
);
484 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
485 FreePool (DevInfoAta
);
489 Build NVMe OPAL device info and save them to LockBox.
491 @param[in] BarAddr Bar address allocated.
495 BuildOpalDeviceInfoNvme (
501 OPAL_DEVICE_NVME
*DevInfoNvme
;
502 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
503 UINTN DevInfoLengthNvme
;
504 UINT16 DevInfoLength
;
505 OPAL_DRIVER_DEVICE
*TmpDev
;
508 // Build NVMe OPAL device info and save them to LockBox.
510 DevInfoLengthNvme
= 0;
511 TmpDev
= mOpalDriver
.DeviceList
;
512 while (TmpDev
!= NULL
) {
513 DeviceType
= ExtractDeviceInfoFromDevicePath (
514 TmpDev
->OpalDisk
.OpalDevicePath
,
518 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
519 DevInfoLengthNvme
+= DevInfoLength
;
522 TmpDev
= TmpDev
->Next
;
525 if (DevInfoLengthNvme
== 0) {
529 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
530 ASSERT (DevInfoNvme
!= NULL
);
532 TempDevInfoNvme
= DevInfoNvme
;
533 TmpDev
= mOpalDriver
.DeviceList
;
534 while (TmpDev
!= NULL
) {
535 DeviceType
= ExtractDeviceInfoFromDevicePath (
536 TmpDev
->OpalDisk
.OpalDevicePath
,
540 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
541 ExtractDeviceInfoFromDevicePath (
542 TmpDev
->OpalDisk
.OpalDevicePath
,
544 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
546 TempDevInfoNvme
->Length
= DevInfoLength
;
547 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
548 TempDevInfoNvme
->BarAddr
= BarAddr
;
550 TempDevInfoNvme
->Password
,
551 TmpDev
->OpalDisk
.Password
,
552 TmpDev
->OpalDisk
.PasswordLength
554 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
555 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
558 TmpDev
= TmpDev
->Next
;
561 Status
= SaveLockBox (
562 &mOpalDeviceNvmeGuid
,
566 ASSERT_EFI_ERROR (Status
);
568 Status
= SetLockBoxAttributes (
569 &mOpalDeviceNvmeGuid
,
570 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
572 ASSERT_EFI_ERROR (Status
);
574 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
575 FreePool (DevInfoNvme
);
579 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
581 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
583 @param Event Event whose notification function is being invoked.
584 @param Context Pointer to the notification function's context.
589 OpalEndOfDxeEventNotify (
595 EFI_PHYSICAL_ADDRESS Address
;
597 OPAL_DRIVER_DEVICE
*TmpDev
;
599 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
601 mOpalEndOfDxe
= TRUE
;
603 if (mOpalRequestVariable
!= NULL
) {
605 // Free the OPAL request variable buffer here
606 // as the OPAL requests should have been processed.
608 FreePool (mOpalRequestVariable
);
609 mOpalRequestVariable
= NULL
;
610 mOpalRequestVariableSize
= 0;
614 // Assume 64K size and alignment are enough.
617 Address
= 0xFFFFFFFF;
618 Status
= gDS
->AllocateMemorySpace (
619 EfiGcdAllocateMaxAddressSearchBottomUp
,
620 EfiGcdMemoryTypeMemoryMappedIo
,
621 16, // 2^16: 64K Alignment
627 ASSERT_EFI_ERROR (Status
);
629 BuildOpalDeviceInfoAta ((UINT32
) Address
);
630 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
635 TmpDev
= mOpalDriver
.DeviceList
;
636 while (TmpDev
!= NULL
) {
637 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
638 TmpDev
= TmpDev
->Next
;
641 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
643 gBS
->CloseEvent (Event
);
647 Get Psid input from the popup window.
649 @param[in] Dev The device which need Psid to process Psid Revert
651 @param[in] PopUpString Pop up string.
652 @param[out] PressEsc Whether user escape function through Press ESC.
654 @retval Password string if success. NULL if failed.
658 OpalDriverPopUpPsidInput (
659 IN OPAL_DRIVER_DEVICE
*Dev
,
660 IN CHAR16
*PopUpString
,
661 OUT BOOLEAN
*PressEsc
664 EFI_INPUT_KEY InputKey
;
666 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
667 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
670 ZeroMem(Unicode
, sizeof(Unicode
));
671 ZeroMem(Mask
, sizeof(Mask
));
675 gST
->ConOut
->ClearScreen(gST
->ConOut
);
679 Mask
[InputLength
] = L
'_';
681 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
684 L
"---------------------",
692 if (InputKey
.ScanCode
== SCAN_NULL
) {
696 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
698 // Add the null terminator.
700 Unicode
[InputLength
] = 0;
701 Mask
[InputLength
] = 0;
703 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
704 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
705 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
710 // delete last key entered
712 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
713 if (InputLength
> 0) {
714 Unicode
[InputLength
] = 0;
715 Mask
[InputLength
] = 0;
720 // add Next key entry
722 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
723 Mask
[InputLength
] = InputKey
.UnicodeChar
;
725 if (InputLength
== PSID_CHARACTER_LENGTH
) {
727 // Add the null terminator.
729 Unicode
[InputLength
] = 0;
730 Mask
[InputLength
] = 0;
740 if (InputKey
.ScanCode
== SCAN_ESC
) {
746 gST
->ConOut
->ClearScreen(gST
->ConOut
);
748 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
749 ZeroMem (Unicode
, sizeof (Unicode
));
750 ZeroMem (Mask
, sizeof (Mask
));
754 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
756 ZeroMem (Unicode
, sizeof (Unicode
));
757 ZeroMem (Mask
, sizeof (Mask
));
761 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
762 ZeroMem (Unicode
, sizeof (Unicode
));
763 ZeroMem (Mask
, sizeof (Mask
));
770 Get password input from the popup window.
772 @param[in] Dev The device which need password to unlock or
773 process OPAL request.
774 @param[in] PopUpString1 Pop up string 1.
775 @param[in] PopUpString2 Pop up string 2.
776 @param[out] PressEsc Whether user escape function through Press ESC.
778 @retval Password string if success. NULL if failed.
782 OpalDriverPopUpPasswordInput (
783 IN OPAL_DRIVER_DEVICE
*Dev
,
784 IN CHAR16
*PopUpString1
,
785 IN CHAR16
*PopUpString2
,
786 OUT BOOLEAN
*PressEsc
789 EFI_INPUT_KEY InputKey
;
791 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
792 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
795 ZeroMem(Unicode
, sizeof(Unicode
));
796 ZeroMem(Mask
, sizeof(Mask
));
800 gST
->ConOut
->ClearScreen(gST
->ConOut
);
804 Mask
[InputLength
] = L
'_';
805 if (PopUpString2
== NULL
) {
807 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
810 L
"---------------------",
816 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
820 L
"---------------------",
829 if (InputKey
.ScanCode
== SCAN_NULL
) {
833 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
835 // Add the null terminator.
837 Unicode
[InputLength
] = 0;
838 Mask
[InputLength
] = 0;
840 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
841 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
842 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
847 // delete last key entered
849 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
850 if (InputLength
> 0) {
851 Unicode
[InputLength
] = 0;
852 Mask
[InputLength
] = 0;
857 // add Next key entry
859 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
860 Mask
[InputLength
] = L
'*';
862 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
864 // Add the null terminator.
866 Unicode
[InputLength
] = 0;
867 Mask
[InputLength
] = 0;
877 if (InputKey
.ScanCode
== SCAN_ESC
) {
883 gST
->ConOut
->ClearScreen(gST
->ConOut
);
885 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
886 ZeroMem (Unicode
, sizeof (Unicode
));
890 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
892 ZeroMem (Unicode
, sizeof (Unicode
));
896 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
897 ZeroMem (Unicode
, sizeof (Unicode
));
903 Check if disk is locked, show popup window and ask for password if it is.
905 @param[in] Dev The device which need to be unlocked.
906 @param[in] RequestString Request string.
911 IN OPAL_DRIVER_DEVICE
*Dev
,
912 IN CHAR16
*RequestString
917 StrLength
= StrLen (RequestString
) + 1 + MAX (StrLen (Dev
->Name16
), StrLen (L
"Disk"));
918 ASSERT (StrLength
< sizeof (mPopUpString
) / sizeof (CHAR16
));
920 if (Dev
->Name16
== NULL
) {
921 UnicodeSPrint (mPopUpString
, StrLength
+ 1, L
"%s Disk", RequestString
);
923 UnicodeSPrint (mPopUpString
, StrLength
+ 1, L
"%s %s", RequestString
, Dev
->Name16
);
930 Check if disk is locked, show popup window and ask for password if it is.
932 @param[in] Dev The device which need to be unlocked.
933 @param[in] RequestString Request string.
937 OpalDriverRequestPassword (
938 IN OPAL_DRIVER_DEVICE
*Dev
,
939 IN CHAR16
*RequestString
947 OPAL_SESSION Session
;
957 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
959 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
963 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
965 ZeroMem(&Session
, sizeof(Session
));
966 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
967 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
968 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
970 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
972 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
973 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
977 // Current device in the lock status and
978 // User not input password and press ESC,
979 // keep device in lock status and continue boot.
983 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
985 L
"Press ENTER to skip the request and continue boot,",
986 L
"Press ESC to input password again",
989 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
991 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
992 gST
->ConOut
->ClearScreen(gST
->ConOut
);
994 // Keep lock and continue boot.
999 // Let user input password again.
1005 // Current device in the unlock status and
1006 // User not input password and press ESC,
1007 // Shutdown the device.
1011 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1013 L
"Press ENTER to shutdown, Press ESC to input password again",
1016 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1018 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1019 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1022 // Let user input password again.
1029 if (Password
== NULL
) {
1033 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1036 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1038 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1039 if (Ret
== TcgResultSuccess
) {
1040 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1044 if (Ret
== TcgResultSuccess
) {
1045 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1046 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1048 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1051 if (Password
!= NULL
) {
1052 ZeroMem (Password
, PasswordLen
);
1053 FreePool (Password
);
1056 if (Ret
== TcgResultSuccess
) {
1064 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1066 L
"Invalid password.",
1067 L
"Press ENTER to retry",
1070 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1073 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1076 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1078 L
"Opal password retry count exceeds the limit. Must shutdown!",
1079 L
"Press ENTER to shutdown",
1082 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1084 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1090 Process Enable Feature OPAL request.
1092 @param[in] Dev The device which has Enable Feature OPAL request.
1093 @param[in] RequestString Request string.
1097 ProcessOpalRequestEnableFeature (
1098 IN OPAL_DRIVER_DEVICE
*Dev
,
1099 IN CHAR16
*RequestString
1105 CHAR8
*PasswordConfirm
;
1106 UINT32 PasswordLenConfirm
;
1107 OPAL_SESSION Session
;
1111 CHAR16
*PopUpString
;
1117 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1119 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1123 ZeroMem(&Session
, sizeof(Session
));
1124 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1125 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1126 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1128 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1129 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1133 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1135 L
"Press ENTER to skip the request and continue boot,",
1136 L
"Press ESC to input password again",
1139 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1141 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1142 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1146 // Let user input password again.
1152 if (Password
== NULL
) {
1156 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1158 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1159 if (PasswordConfirm
== NULL
) {
1160 ZeroMem (Password
, PasswordLen
);
1161 FreePool (Password
);
1165 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1166 if ((PasswordLen
!= PasswordLenConfirm
) ||
1167 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1168 ZeroMem (Password
, PasswordLen
);
1169 FreePool (Password
);
1170 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1171 FreePool (PasswordConfirm
);
1174 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1176 L
"Passwords are not the same.",
1177 L
"Press ENTER to retry",
1180 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1185 if (PasswordConfirm
!= NULL
) {
1186 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1187 FreePool (PasswordConfirm
);
1190 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1191 if (Ret
== TcgResultSuccess
) {
1192 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1193 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1195 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1198 if (Password
!= NULL
) {
1199 ZeroMem (Password
, PasswordLen
);
1200 FreePool (Password
);
1203 if (Ret
== TcgResultSuccess
) {
1211 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1214 L
"Press ENTER to retry",
1217 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1220 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1223 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1225 L
"Opal password retry count exceeds the limit.",
1226 L
"Press ENTER to skip the request and continue boot",
1229 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1230 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1235 Process Disable User OPAL request.
1237 @param[in] Dev The device which has Disable User OPAL request.
1238 @param[in] RequestString Request string.
1242 ProcessOpalRequestDisableUser (
1243 IN OPAL_DRIVER_DEVICE
*Dev
,
1244 IN CHAR16
*RequestString
1250 OPAL_SESSION Session
;
1254 BOOLEAN PasswordFailed
;
1255 CHAR16
*PopUpString
;
1261 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1263 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1267 ZeroMem(&Session
, sizeof(Session
));
1268 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1269 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1270 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1272 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1273 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1277 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1279 L
"Press ENTER to skip the request and continue boot,",
1280 L
"Press ESC to input password again",
1283 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1285 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1286 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1290 // Let user input password again.
1296 if (Password
== NULL
) {
1300 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1302 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1303 if (Ret
== TcgResultSuccess
) {
1304 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1305 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1307 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1310 if (Password
!= NULL
) {
1311 ZeroMem (Password
, PasswordLen
);
1312 FreePool (Password
);
1315 if (Ret
== TcgResultSuccess
) {
1323 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1325 L
"Invalid password, request failed.",
1326 L
"Press ENTER to retry",
1329 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1332 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1335 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1337 L
"Opal password retry count exceeds the limit.",
1338 L
"Press ENTER to skip the request and continue boot",
1341 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1342 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1347 Process Psid Revert OPAL request.
1349 @param[in] Dev The device which has Psid Revert OPAL request.
1350 @param[in] RequestString Request string.
1354 ProcessOpalRequestPsidRevert (
1355 IN OPAL_DRIVER_DEVICE
*Dev
,
1356 IN CHAR16
*RequestString
1362 OPAL_SESSION Session
;
1366 CHAR16
*PopUpString
;
1372 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1374 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1378 ZeroMem(&Session
, sizeof(Session
));
1379 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1380 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1381 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1383 while (Count
< MAX_PSID_TRY_COUNT
) {
1384 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, &PressEsc
);
1388 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1390 L
"Press ENTER to skip the request and continue boot,",
1391 L
"Press ESC to input Psid again",
1394 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1396 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1397 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1401 // Let user input Psid again.
1411 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1413 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1414 if (Ret
== TcgResultSuccess
) {
1415 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1417 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1421 ZeroMem (Psid
, PsidLen
);
1425 if (Ret
== TcgResultSuccess
) {
1433 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1435 L
"Invalid Psid, request failed.",
1436 L
"Press ENTER to retry",
1439 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1442 if (Count
>= MAX_PSID_TRY_COUNT
) {
1445 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1447 L
"Opal Psid retry count exceeds the limit.",
1448 L
"Press ENTER to skip the request and continue boot",
1451 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1452 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1457 Process Admin Revert OPAL request.
1459 @param[in] Dev The device which has Revert OPAL request.
1460 @param[in] KeepUserData Whether to keep user data or not.
1461 @param[in] RequestString Request string.
1465 ProcessOpalRequestRevert (
1466 IN OPAL_DRIVER_DEVICE
*Dev
,
1467 IN BOOLEAN KeepUserData
,
1468 IN CHAR16
*RequestString
1474 OPAL_SESSION Session
;
1478 BOOLEAN PasswordFailed
;
1479 CHAR16
*PopUpString
;
1485 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1487 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1491 ZeroMem(&Session
, sizeof(Session
));
1492 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1493 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1494 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1496 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1497 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1501 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1503 L
"Press ENTER to skip the request and continue boot,",
1504 L
"Press ESC to input password again",
1507 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1509 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1510 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1514 // Let user input password again.
1520 if (Password
== NULL
) {
1524 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1526 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1527 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1529 // For pyrite type device which does not support media encryption,
1530 // it does not accept "Keep User Data" parameter.
1531 // So here hardcode a FALSE for this case.
1533 Ret
= OpalUtilRevert(
1540 Dev
->OpalDisk
.MsidLength
1543 Ret
= OpalUtilRevert(
1550 Dev
->OpalDisk
.MsidLength
1553 if (Ret
== TcgResultSuccess
) {
1554 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1555 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1557 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1560 if (Password
!= NULL
) {
1561 ZeroMem (Password
, PasswordLen
);
1562 FreePool (Password
);
1565 if (Ret
== TcgResultSuccess
) {
1573 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1575 L
"Invalid password, request failed.",
1576 L
"Press ENTER to retry",
1579 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1582 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1585 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1587 L
"Opal password retry count exceeds the limit.",
1588 L
"Press ENTER to skip the request and continue boot",
1591 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1592 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1597 Process Secure Erase OPAL request.
1599 @param[in] Dev The device which has Secure Erase OPAL request.
1600 @param[in] RequestString Request string.
1604 ProcessOpalRequestSecureErase (
1605 IN OPAL_DRIVER_DEVICE
*Dev
,
1606 IN CHAR16
*RequestString
1612 OPAL_SESSION Session
;
1616 BOOLEAN PasswordFailed
;
1617 CHAR16
*PopUpString
;
1623 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1625 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1629 ZeroMem(&Session
, sizeof(Session
));
1630 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1631 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1632 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1634 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1635 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1639 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1641 L
"Press ENTER to skip the request and continue boot,",
1642 L
"Press ESC to input password again",
1645 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1647 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1648 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1652 // Let user input password again.
1658 if (Password
== NULL
) {
1662 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1664 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1665 if (Ret
== TcgResultSuccess
) {
1666 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1667 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1669 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1672 if (Password
!= NULL
) {
1673 ZeroMem (Password
, PasswordLen
);
1674 FreePool (Password
);
1677 if (Ret
== TcgResultSuccess
) {
1685 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1687 L
"Invalid password, request failed.",
1688 L
"Press ENTER to retry",
1691 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1694 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1697 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1699 L
"Opal password retry count exceeds the limit.",
1700 L
"Press ENTER to skip the request and continue boot",
1703 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1704 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1709 Process Set Admin Pwd OPAL request.
1711 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1712 @param[in] RequestString Request string.
1716 ProcessOpalRequestSetUserPwd (
1717 IN OPAL_DRIVER_DEVICE
*Dev
,
1718 IN CHAR16
*RequestString
1723 UINT32 OldPasswordLen
;
1726 CHAR8
*PasswordConfirm
;
1727 UINT32 PasswordLenConfirm
;
1728 OPAL_SESSION Session
;
1732 CHAR16
*PopUpString
;
1738 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1740 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1744 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1745 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1749 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1751 L
"Press ENTER to skip the request and continue boot,",
1752 L
"Press ESC to input password again",
1755 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1757 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1758 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1762 // Let user input password again.
1768 if (OldPassword
== NULL
) {
1772 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1774 ZeroMem(&Session
, sizeof(Session
));
1775 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1776 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1777 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1778 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1779 if (Ret
== TcgResultSuccess
) {
1780 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1782 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1783 if (Ret
== TcgResultSuccess
) {
1784 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1786 ZeroMem (OldPassword
, OldPasswordLen
);
1787 FreePool (OldPassword
);
1788 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1791 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1793 L
"Incorrect password.",
1794 L
"Press ENTER to retry",
1797 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1803 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1804 if (Password
== NULL
) {
1805 ZeroMem (OldPassword
, OldPasswordLen
);
1806 FreePool (OldPassword
);
1810 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1812 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1813 if (PasswordConfirm
== NULL
) {
1814 ZeroMem (OldPassword
, OldPasswordLen
);
1815 FreePool (OldPassword
);
1816 ZeroMem (Password
, PasswordLen
);
1817 FreePool (Password
);
1821 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1822 if ((PasswordLen
!= PasswordLenConfirm
) ||
1823 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1824 ZeroMem (OldPassword
, OldPasswordLen
);
1825 FreePool (OldPassword
);
1826 ZeroMem (Password
, PasswordLen
);
1827 FreePool (Password
);
1828 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1829 FreePool (PasswordConfirm
);
1832 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1834 L
"Passwords are not the same.",
1835 L
"Press ENTER to retry",
1838 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1843 if (PasswordConfirm
!= NULL
) {
1844 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1845 FreePool (PasswordConfirm
);
1848 ZeroMem(&Session
, sizeof(Session
));
1849 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1850 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1851 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1852 Ret
= OpalUtilSetUserPassword(
1859 if (Ret
== TcgResultSuccess
) {
1860 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1861 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1863 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1866 if (OldPassword
!= NULL
) {
1867 ZeroMem (OldPassword
, OldPasswordLen
);
1868 FreePool (OldPassword
);
1871 if (Password
!= NULL
) {
1872 ZeroMem (Password
, PasswordLen
);
1873 FreePool (Password
);
1876 if (Ret
== TcgResultSuccess
) {
1884 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1887 L
"Press ENTER to retry",
1890 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1893 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1896 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1898 L
"Opal password retry count exceeds the limit.",
1899 L
"Press ENTER to skip the request and continue boot",
1902 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1903 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1908 Process Set Admin Pwd OPAL request.
1910 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1911 @param[in] RequestString Request string.
1915 ProcessOpalRequestSetAdminPwd (
1916 IN OPAL_DRIVER_DEVICE
*Dev
,
1917 IN CHAR16
*RequestString
1922 UINT32 OldPasswordLen
;
1925 CHAR8
*PasswordConfirm
;
1926 UINT32 PasswordLenConfirm
;
1927 OPAL_SESSION Session
;
1931 CHAR16
*PopUpString
;
1937 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1939 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1943 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1944 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1948 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1950 L
"Press ENTER to skip the request and continue boot,",
1951 L
"Press ESC to input password again",
1954 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1956 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1957 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1961 // Let user input password again.
1967 if (OldPassword
== NULL
) {
1971 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1973 ZeroMem(&Session
, sizeof(Session
));
1974 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1975 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1976 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1977 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1978 if (Ret
== TcgResultSuccess
) {
1979 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
1981 ZeroMem (OldPassword
, OldPasswordLen
);
1982 FreePool (OldPassword
);
1983 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1986 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1988 L
"Incorrect password.",
1989 L
"Press ENTER to retry",
1992 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1997 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1998 if (Password
== NULL
) {
1999 ZeroMem (OldPassword
, OldPasswordLen
);
2000 FreePool (OldPassword
);
2004 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2006 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2007 if (PasswordConfirm
== NULL
) {
2008 ZeroMem (OldPassword
, OldPasswordLen
);
2009 FreePool (OldPassword
);
2010 ZeroMem (Password
, PasswordLen
);
2011 FreePool (Password
);
2015 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2016 if ((PasswordLen
!= PasswordLenConfirm
) ||
2017 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2018 ZeroMem (OldPassword
, OldPasswordLen
);
2019 FreePool (OldPassword
);
2020 ZeroMem (Password
, PasswordLen
);
2021 FreePool (Password
);
2022 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2023 FreePool (PasswordConfirm
);
2026 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2028 L
"Passwords are not the same.",
2029 L
"Press ENTER to retry",
2032 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2037 if (PasswordConfirm
!= NULL
) {
2038 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2039 FreePool (PasswordConfirm
);
2043 ZeroMem(&Session
, sizeof(Session
));
2044 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2045 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2046 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2047 Ret
= OpalUtilSetAdminPassword(
2054 if (Ret
== TcgResultSuccess
) {
2055 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2056 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2058 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2061 if (OldPassword
!= NULL
) {
2062 ZeroMem (OldPassword
, OldPasswordLen
);
2063 FreePool (OldPassword
);
2066 if (Password
!= NULL
) {
2067 ZeroMem (Password
, PasswordLen
);
2068 FreePool (Password
);
2071 if (Ret
== TcgResultSuccess
) {
2079 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2082 L
"Press ENTER to retry",
2085 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2088 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2091 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2093 L
"Opal password retry count exceeds the limit.",
2094 L
"Press ENTER to skip the request and continue boot",
2097 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2098 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2103 Process OPAL request.
2105 @param[in] Dev The device which has OPAL request.
2109 ProcessOpalRequest (
2110 IN OPAL_DRIVER_DEVICE
*Dev
2114 OPAL_REQUEST_VARIABLE
*TempVariable
;
2115 OPAL_REQUEST_VARIABLE
*Variable
;
2117 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2118 UINTN DevicePathSizeInVariable
;
2119 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2120 UINTN DevicePathSize
;
2121 BOOLEAN KeepUserData
;
2123 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2125 if (mOpalRequestVariable
== NULL
) {
2126 Status
= GetVariable2 (
2127 OPAL_REQUEST_VARIABLE_NAME
,
2128 &gHiiSetupVariableGuid
,
2129 (VOID
**) &Variable
,
2132 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2135 mOpalRequestVariable
= Variable
;
2136 mOpalRequestVariableSize
= VariableSize
;
2139 // Delete the OPAL request variable.
2141 Status
= gRT
->SetVariable (
2142 OPAL_REQUEST_VARIABLE_NAME
,
2143 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2148 ASSERT_EFI_ERROR (Status
);
2150 Variable
= mOpalRequestVariable
;
2151 VariableSize
= mOpalRequestVariableSize
;
2155 // Process the OPAL requests.
2157 TempVariable
= Variable
;
2158 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2159 (VariableSize
>= TempVariable
->Length
) &&
2160 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2161 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2162 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2163 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2164 DevicePathSize
= GetDevicePathSize (DevicePath
);
2165 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2166 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2168 // Found the node for the OPAL device.
2170 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2171 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2173 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2174 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2176 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2177 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2179 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2180 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2181 ProcessOpalRequestRevert (
2184 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2187 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2188 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2190 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2191 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2193 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2194 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2200 VariableSize
-= TempVariable
->Length
;
2201 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2204 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2208 Add new device to the global device list.
2210 @param Dev New create device.
2215 IN OPAL_DRIVER_DEVICE
*Dev
2218 OPAL_DRIVER_DEVICE
*TmpDev
;
2220 if (mOpalDriver
.DeviceList
== NULL
) {
2221 mOpalDriver
.DeviceList
= Dev
;
2223 TmpDev
= mOpalDriver
.DeviceList
;
2224 while (TmpDev
->Next
!= NULL
) {
2225 TmpDev
= TmpDev
->Next
;
2233 Remove one device in the global device list.
2235 @param Dev The device need to be removed.
2240 IN OPAL_DRIVER_DEVICE
*Dev
2243 OPAL_DRIVER_DEVICE
*TmpDev
;
2245 if (mOpalDriver
.DeviceList
== NULL
) {
2249 if (mOpalDriver
.DeviceList
== Dev
) {
2250 mOpalDriver
.DeviceList
= NULL
;
2254 TmpDev
= mOpalDriver
.DeviceList
;
2255 while (TmpDev
->Next
!= NULL
) {
2256 if (TmpDev
->Next
== Dev
) {
2257 TmpDev
->Next
= Dev
->Next
;
2264 Get current device count.
2266 @retval return the current created device count.
2275 OPAL_DRIVER_DEVICE
*TmpDev
;
2278 TmpDev
= mOpalDriver
.DeviceList
;
2280 while (TmpDev
!= NULL
) {
2282 TmpDev
= TmpDev
->Next
;
2289 Get devcie list info.
2291 @retval return the device list pointer.
2294 OpalDriverGetDeviceList(
2298 return mOpalDriver
.DeviceList
;
2302 ReadyToBoot callback to send BlockSid command.
2304 @param Event Pointer to this event
2305 @param Context Event handler private Data
2310 ReadyToBootCallback (
2315 OPAL_DRIVER_DEVICE
*Itr
;
2317 OPAL_SESSION Session
;
2318 UINT32 PpStorageFlag
;
2320 gBS
->CloseEvent (Event
);
2322 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2323 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2325 // Send BlockSID command to each Opal disk
2327 Itr
= mOpalDriver
.DeviceList
;
2328 while (Itr
!= NULL
) {
2329 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2330 ZeroMem(&Session
, sizeof(Session
));
2331 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2332 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2333 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2335 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2336 if (Result
!= TcgResultSuccess
) {
2337 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2348 Stop this Controller.
2350 @param Dev The device need to be stopped.
2354 OpalDriverStopDevice (
2355 OPAL_DRIVER_DEVICE
*Dev
2361 FreePool(Dev
->Name16
);
2364 // remove OPAL_DRIVER_DEVICE from the list
2365 // it updates the controllerList pointer
2370 // close protocols that were opened
2374 &gEfiStorageSecurityCommandProtocolGuid
,
2375 gOpalDriverBinding
.DriverBindingHandle
,
2381 &gEfiBlockIoProtocolGuid
,
2382 gOpalDriverBinding
.DriverBindingHandle
,
2390 Get devcie name through the component name protocol.
2392 @param[in] AllHandlesBuffer The handle buffer for current system.
2393 @param[in] NumAllHandles The number of handles for the handle buffer.
2394 @param[in] Dev The device which need to get name.
2395 @param[in] UseComp1 Whether use component name or name2 protocol.
2397 @retval TRUE Find the name for this device.
2398 @retval FALSE Not found the name for this device.
2401 OpalDriverGetDeviceNameByProtocol(
2402 EFI_HANDLE
*AllHandlesBuffer
,
2403 UINTN NumAllHandles
,
2404 OPAL_DRIVER_DEVICE
*Dev
,
2408 EFI_HANDLE
* ProtocolHandlesBuffer
;
2409 UINTN NumProtocolHandles
;
2411 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2414 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2417 EFI_HANDLE TmpHandle
;
2420 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2424 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2427 // Find all EFI_HANDLES with protocol
2429 Status
= gBS
->LocateHandleBuffer(
2433 &NumProtocolHandles
,
2434 &ProtocolHandlesBuffer
2436 if (EFI_ERROR(Status
)) {
2442 // Exit early if no supported devices
2444 if (NumProtocolHandles
== 0) {
2449 // Get printable name by iterating through all protocols
2450 // using the handle as the child, and iterate through all handles for the controller
2451 // exit loop early once found, if not found, then delete device
2452 // storage security protocol instances already exist, add them to internal list
2454 Status
= EFI_DEVICE_ERROR
;
2455 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2458 if (Dev
->Name16
!= NULL
) {
2462 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2464 Status
= gBS
->OpenProtocol(
2470 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2472 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2477 // Use all handles array as controller handle
2479 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2480 Status
= Cnp1_2
->GetControllerName(
2482 AllHandlesBuffer
[Index2
],
2484 LANGUAGE_ISO_639_2_ENGLISH
,
2487 if (EFI_ERROR(Status
)) {
2488 Status
= Cnp1_2
->GetControllerName(
2490 AllHandlesBuffer
[Index2
],
2492 LANGUAGE_RFC_3066_ENGLISH
,
2496 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2497 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2498 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2499 ASSERT (Dev
->Name16
!= NULL
);
2500 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2501 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2502 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2505 // Retrieve bridge BDF info and port number or namespace depending on type
2508 Status
= gBS
->OpenProtocol(
2510 &gEfiDevicePathProtocolGuid
,
2511 (VOID
**)&TmpDevPath
,
2514 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2516 if (!EFI_ERROR(Status
)) {
2517 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2521 if (Dev
->Name16
!= NULL
) {
2522 FreePool(Dev
->Name16
);
2525 if (Dev
->NameZ
!= NULL
) {
2526 FreePool(Dev
->NameZ
);
2537 Get devcie name through the component name protocol.
2539 @param[in] Dev The device which need to get name.
2541 @retval TRUE Find the name for this device.
2542 @retval FALSE Not found the name for this device.
2545 OpalDriverGetDriverDeviceName(
2546 OPAL_DRIVER_DEVICE
*Dev
2549 EFI_HANDLE
* AllHandlesBuffer
;
2550 UINTN NumAllHandles
;
2554 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2559 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2561 if (Dev
->Name16
== NULL
) {
2562 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2564 // Find all EFI_HANDLES
2566 Status
= gBS
->LocateHandleBuffer(
2573 if (EFI_ERROR(Status
)) {
2574 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2579 // Try component Name2
2581 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2582 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2583 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2584 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2594 Main entry for this driver.
2596 @param ImageHandle Image Handle this driver.
2597 @param SystemTable Pointer to SystemTable.
2599 @retval EFI_SUCESS This function always complete successfully.
2603 EfiDriverEntryPoint(
2604 IN EFI_HANDLE ImageHandle
,
2605 IN EFI_SYSTEM_TABLE
* SystemTable
2609 EFI_EVENT ReadyToBootEvent
;
2610 EFI_EVENT EndOfDxeEvent
;
2612 Status
= EfiLibInstallDriverBindingComponentName2 (
2615 &gOpalDriverBinding
,
2617 &gOpalComponentName
,
2618 &gOpalComponentName2
2621 if (EFI_ERROR(Status
)) {
2622 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2627 // Initialize Driver object
2629 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2630 mOpalDriver
.Handle
= ImageHandle
;
2632 Status
= gBS
->CreateEventEx (
2635 OpalEndOfDxeEventNotify
,
2637 &gEfiEndOfDxeEventGroupGuid
,
2640 ASSERT_EFI_ERROR (Status
);
2643 // register a ReadyToBoot event callback for sending BlockSid command
2645 Status
= EfiCreateEventReadyToBootEx (
2647 ReadyToBootCallback
,
2648 (VOID
*) &ImageHandle
,
2653 // Install Hii packages.
2661 Tests to see if this driver supports a given controller.
2663 This function checks to see if the controller contains an instance of the
2664 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2665 and returns EFI_SUCCESS if it does.
2667 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2668 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2669 must support a protocol interface that supplies
2670 an I/O abstraction to the driver.
2671 @param[in] RemainingDevicePath This parameter is ignored.
2673 @retval EFI_SUCCESS The device contains required protocols
2674 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2675 RemainingDevicePath is already being managed by the driver
2677 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2678 RemainingDevicePath is already being managed by a different
2679 driver or an application that requires exclusive access.
2680 Currently not implemented.
2681 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2686 OpalEfiDriverBindingSupported(
2687 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2688 IN EFI_HANDLE Controller
,
2689 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2693 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2694 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2696 if (mOpalEndOfDxe
) {
2697 return EFI_UNSUPPORTED
;
2701 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2703 Status
= gBS
->OpenProtocol(
2705 &gEfiStorageSecurityCommandProtocolGuid
,
2706 ( VOID
** )&SecurityCommand
,
2707 This
->DriverBindingHandle
,
2709 EFI_OPEN_PROTOCOL_BY_DRIVER
2712 if (Status
== EFI_ALREADY_STARTED
) {
2716 if (EFI_ERROR(Status
)) {
2721 // Close protocol and reopen in Start call
2725 &gEfiStorageSecurityCommandProtocolGuid
,
2726 This
->DriverBindingHandle
,
2731 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2734 Status
= gBS
->OpenProtocol(
2736 &gEfiBlockIoProtocolGuid
,
2738 This
->DriverBindingHandle
,
2740 EFI_OPEN_PROTOCOL_BY_DRIVER
2743 if (EFI_ERROR(Status
)) {
2744 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2749 // Close protocol and reopen in Start call
2753 &gEfiBlockIoProtocolGuid
,
2754 This
->DriverBindingHandle
,
2762 Enables Opal Management on a supported device if available.
2764 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2765 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2766 This function will complete the other necessary checks, such as verifying the device supports
2767 the correct version of Opal. Upon verification, it will add the device to the
2768 Opal HII list in order to expose Opal managmeent options.
2770 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2771 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2772 must support a protocol interface that supplies
2773 an I/O abstraction to the driver.
2774 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2775 parameter is ignored by device drivers, and is optional for bus
2776 drivers. For a bus driver, if this parameter is NULL, then handles
2777 for all the children of Controller are created by this driver.
2778 If this parameter is not NULL and the first Device Path Node is
2779 not the End of Device Path Node, then only the Handle for the
2780 child device specified by the first Device Path Node of
2781 RemainingDevicePath is created by this driver.
2782 If the first Device Path Node of RemainingDevicePath is
2783 the End of Device Path Node, no child Handle is created by this
2786 @retval EFI_SUCCESS Opal management was enabled.
2787 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2788 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2789 @retval Others The driver failed to start the device.
2794 OpalEfiDriverBindingStart(
2795 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2796 IN EFI_HANDLE Controller
,
2797 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2801 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2802 OPAL_DRIVER_DEVICE
*Dev
;
2803 OPAL_DRIVER_DEVICE
*Itr
;
2806 Itr
= mOpalDriver
.DeviceList
;
2807 while (Itr
!= NULL
) {
2808 if (Controller
== Itr
->Handle
) {
2815 // Create internal device for tracking. This allows all disks to be tracked
2818 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2820 return EFI_OUT_OF_RESOURCES
;
2822 Dev
->Handle
= Controller
;
2825 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2827 Status
= gBS
->OpenProtocol(
2829 &gEfiStorageSecurityCommandProtocolGuid
,
2830 (VOID
**)&Dev
->Sscp
,
2831 This
->DriverBindingHandle
,
2833 EFI_OPEN_PROTOCOL_BY_DRIVER
2835 if (EFI_ERROR(Status
)) {
2841 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2844 Status
= gBS
->OpenProtocol(
2846 &gEfiBlockIoProtocolGuid
,
2848 This
->DriverBindingHandle
,
2850 EFI_OPEN_PROTOCOL_BY_DRIVER
2852 if (EFI_ERROR(Status
)) {
2854 // Close storage security that was opened
2858 &gEfiStorageSecurityCommandProtocolGuid
,
2859 This
->DriverBindingHandle
,
2870 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2874 &gEfiBlockIoProtocolGuid
,
2875 This
->DriverBindingHandle
,
2880 // Acquire Ascii printable name of child, if not found, then ignore device
2882 Result
= OpalDriverGetDriverDeviceName (Dev
);
2887 Status
= OpalDiskInitialize (Dev
);
2888 if (EFI_ERROR (Status
)) {
2892 AddDeviceToTail(Dev
);
2895 // Check if device is locked and prompt for password.
2897 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2900 // Process OPAL request from last boot.
2902 ProcessOpalRequest (Dev
);
2908 // free device, close protocols and exit
2912 &gEfiStorageSecurityCommandProtocolGuid
,
2913 This
->DriverBindingHandle
,
2919 return EFI_DEVICE_ERROR
;
2923 Stop this driver on Controller.
2925 @param This Protocol instance pointer.
2926 @param Controller Handle of device to stop driver on
2927 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
2928 children is zero stop the entire bus driver.
2929 @param ChildHandleBuffer List of Child Handles to Stop.
2931 @retval EFI_SUCCESS This driver is removed Controller.
2932 @retval other This driver could not be removed from this device.
2937 OpalEfiDriverBindingStop(
2938 EFI_DRIVER_BINDING_PROTOCOL
* This
,
2939 EFI_HANDLE Controller
,
2940 UINTN NumberOfChildren
,
2941 EFI_HANDLE
* ChildHandleBuffer
2944 OPAL_DRIVER_DEVICE
* Itr
;
2946 Itr
= mOpalDriver
.DeviceList
;
2949 // does Controller match any of the devices we are managing for Opal
2951 while (Itr
!= NULL
) {
2952 if (Itr
->Handle
== Controller
) {
2953 OpalDriverStopDevice (Itr
);
2960 return EFI_NOT_FOUND
;
2965 Unloads UEFI Driver. Very useful for debugging and testing.
2967 @param ImageHandle Image Handle this driver.
2969 @retval EFI_SUCCESS This function always complete successfully.
2970 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
2974 OpalEfiDriverUnload (
2975 IN EFI_HANDLE ImageHandle
2979 OPAL_DRIVER_DEVICE
*Itr
;
2981 Status
= EFI_SUCCESS
;
2983 if (ImageHandle
!= gImageHandle
) {
2984 return (EFI_INVALID_PARAMETER
);
2988 // Uninstall any interface added to each device by us
2990 while (mOpalDriver
.DeviceList
) {
2991 Itr
= mOpalDriver
.DeviceList
;
2993 // Remove OPAL_DRIVER_DEVICE from the list
2994 // it updates the controllerList pointer
2996 OpalDriverStopDevice(Itr
);
3000 // Uninstall the HII capability
3002 Status
= HiiUninstall();