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
[100];
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 or pyrite 2.0 type support.
110 if (SupportedAttributes
->PyriteSscV2
|| SupportedAttributes
->MediaEncryption
) {
113 // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
114 // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
115 // intact and accessible
117 AvalDiskActions
->PsidRevert
= 1;
118 AvalDiskActions
->RevertKeepDataForced
= 0;
121 // Secure erase is performed by generating a new encryption key
122 // this is only available if encryption is supported
124 AvalDiskActions
->SecureErase
= 1;
126 AvalDiskActions
->PsidRevert
= 0;
127 AvalDiskActions
->SecureErase
= 0;
130 // If no media encryption is supported, then a revert (using password) will not
131 // erase the Data (since you can't generate a new encryption key)
133 AvalDiskActions
->RevertKeepDataForced
= 1;
136 if (LockingFeature
->Locked
) {
137 AvalDiskActions
->Unlock
= 1;
139 AvalDiskActions
->Unlock
= 0;
143 // Only allow user to set password if an admin password exists
145 ExistingPassword
= OpalUtilAdminPasswordExists(OwnerShip
, LockingFeature
);
146 AvalDiskActions
->UserPass
= ExistingPassword
;
149 // This will still show up even if there isn't a user, which is fine
151 AvalDiskActions
->DisableUser
= ExistingPassword
;
153 return TcgResultSuccess
;
157 Enable Opal Feature for the input device.
159 @param[in] Session The opal session for the opal device.
161 @param[in] MsidLength Msid Length
162 @param[in] Password Admin password
163 @param[in] PassLength Length of password in bytes
168 OpalSupportEnableOpalFeature (
169 IN OPAL_SESSION
*Session
,
171 IN UINT32 MsidLength
,
180 NULL_CHECK(Password
);
182 Ret
= OpalUtilSetAdminPasswordAsSid(
189 if (Ret
== TcgResultSuccess
) {
191 // Enable global locking range
193 Ret
= OpalUtilSetOpalLockingRange(
197 OPAL_LOCKING_SP_LOCKING_GLOBALRANGE
,
211 Update password for the Opal disk.
213 @param[in, out] OpalDisk The disk to update password.
214 @param[in] Password The input password.
215 @param[in] PasswordLength The input password length.
219 OpalSupportUpdatePassword (
220 IN OUT OPAL_DISK
*OpalDisk
,
222 IN UINT32 PasswordLength
225 CopyMem (OpalDisk
->Password
, Password
, PasswordLength
);
226 OpalDisk
->PasswordLength
= (UINT8
) PasswordLength
;
230 Extract device info from the device path.
232 @param[in] DevicePath Device path info for the device.
233 @param[out] DevInfoLength Device information length needed.
234 @param[out] DevInfo Device information extracted.
240 ExtractDeviceInfoFromDevicePath (
241 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
242 OUT UINT16
*DevInfoLength
,
243 OUT OPAL_DEVICE_COMMON
*DevInfo OPTIONAL
246 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath
;
247 EFI_DEVICE_PATH_PROTOCOL
*TmpDevPath2
;
248 PCI_DEVICE_PATH
*PciDevPath
;
251 OPAL_PCI_DEVICE
*PciDevice
;
252 OPAL_DEVICE_ATA
*DevInfoAta
;
253 OPAL_DEVICE_NVME
*DevInfoNvme
;
254 SATA_DEVICE_PATH
*SataDevPath
;
255 NVME_NAMESPACE_DEVICE_PATH
*NvmeDevPath
;
257 ASSERT (DevicePath
!= NULL
);
258 ASSERT (DevInfoLength
!= NULL
);
260 DeviceType
= OPAL_DEVICE_TYPE_UNKNOWN
;
263 TmpDevPath
= DevicePath
;
268 while (!IsDevicePathEnd (TmpDevPath
)) {
269 if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_SATA_DP
) {
273 if (DevInfo
!= NULL
) {
274 SataDevPath
= (SATA_DEVICE_PATH
*) TmpDevPath
;
275 DevInfoAta
= (OPAL_DEVICE_ATA
*) DevInfo
;
276 DevInfoAta
->Port
= SataDevPath
->HBAPortNumber
;
277 DevInfoAta
->PortMultiplierPort
= SataDevPath
->PortMultiplierPortNumber
;
279 DeviceType
= OPAL_DEVICE_TYPE_ATA
;
280 *DevInfoLength
= sizeof (OPAL_DEVICE_ATA
);
282 } else if (TmpDevPath
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath
->SubType
== MSG_NVME_NAMESPACE_DP
) {
286 if (DevInfo
!= NULL
) {
287 NvmeDevPath
= (NVME_NAMESPACE_DEVICE_PATH
*) TmpDevPath
;
288 DevInfoNvme
= (OPAL_DEVICE_NVME
*) DevInfo
;
289 DevInfoNvme
->NvmeNamespaceId
= NvmeDevPath
->NamespaceId
;
291 DeviceType
= OPAL_DEVICE_TYPE_NVME
;
292 *DevInfoLength
= sizeof (OPAL_DEVICE_NVME
);
295 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
302 TmpDevPath
= DevicePath
;
303 TmpDevPath2
= NextDevicePathNode (DevicePath
);
304 while (!IsDevicePathEnd (TmpDevPath2
)) {
305 if (TmpDevPath
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath
->SubType
== HW_PCI_DP
) {
306 PciDevPath
= (PCI_DEVICE_PATH
*) TmpDevPath
;
307 if ((TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_NVME_NAMESPACE_DP
)||
308 (TmpDevPath2
->Type
== MESSAGING_DEVICE_PATH
&& TmpDevPath2
->SubType
== MSG_SATA_DP
)) {
309 if (DevInfo
!= NULL
) {
310 PciDevice
= &DevInfo
->Device
;
311 PciDevice
->Segment
= 0;
312 PciDevice
->Bus
= BusNum
;
313 PciDevice
->Device
= PciDevPath
->Device
;
314 PciDevice
->Function
= PciDevPath
->Function
;
317 if (DevInfo
!= NULL
) {
318 PciDevice
= (OPAL_PCI_DEVICE
*) ((UINTN
) DevInfo
+ *DevInfoLength
);
319 PciDevice
->Segment
= 0;
320 PciDevice
->Bus
= BusNum
;
321 PciDevice
->Device
= PciDevPath
->Device
;
322 PciDevice
->Function
= PciDevPath
->Function
;
324 *DevInfoLength
+= sizeof (OPAL_PCI_DEVICE
);
325 if (TmpDevPath2
->Type
== HARDWARE_DEVICE_PATH
&& TmpDevPath2
->SubType
== HW_PCI_DP
) {
326 BusNum
= PciRead8 (PCI_LIB_ADDRESS (BusNum
, PciDevPath
->Device
, PciDevPath
->Function
, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET
));
331 TmpDevPath
= NextDevicePathNode (TmpDevPath
);
332 TmpDevPath2
= NextDevicePathNode (TmpDevPath2
);
335 ASSERT (DeviceType
!= OPAL_DEVICE_TYPE_UNKNOWN
);
340 Save boot script for ATA OPAL device.
342 @param[in] DevInfo Pointer to ATA Opal device information.
346 OpalDeviceAtaSaveBootScript (
347 IN OPAL_DEVICE_ATA
*DevInfo
357 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
359 OPAL_HC_PCI_REGISTER_SAVE
*HcRegisterSaveListPtr
;
364 Bus
= DevInfo
->Device
.Bus
;
365 Device
= DevInfo
->Device
.Device
;
366 Function
= DevInfo
->Device
.Function
;
368 HcRegisterSaveListPtr
= (OPAL_HC_PCI_REGISTER_SAVE
*) mSataHcRegisterSaveTemplate
;
369 Count
= sizeof (mSataHcRegisterSaveTemplate
) / sizeof (OPAL_HC_PCI_REGISTER_SAVE
);
371 for (Index
= 0; Index
< Count
; Index
++) {
372 Offset
= HcRegisterSaveListPtr
[Index
].Address
;
373 Width
= HcRegisterSaveListPtr
[Index
].Width
;
376 case S3BootScriptWidthUint8
:
377 Data
= (UINT32
)PciRead8 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
379 case S3BootScriptWidthUint16
:
380 Data
= (UINT32
)PciRead16 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
382 case S3BootScriptWidthUint32
:
383 Data
= PciRead32 (PCI_LIB_ADDRESS(Bus
,Device
,Function
,Offset
));
390 Address
= S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus
, Device
, Function
, Offset
);
391 Status
= S3BootScriptSavePciCfgWrite (Width
, Address
, 1, &Data
);
392 ASSERT_EFI_ERROR (Status
);
397 Build ATA OPAL device info and save them to LockBox.
399 @param[in] BarAddr Bar address allocated.
403 BuildOpalDeviceInfoAta (
409 OPAL_DEVICE_ATA
*DevInfoAta
;
410 OPAL_DEVICE_ATA
*TempDevInfoAta
;
411 UINTN DevInfoLengthAta
;
412 UINT16 DevInfoLength
;
413 OPAL_DRIVER_DEVICE
*TmpDev
;
416 // Build ATA OPAL device info and save them to LockBox.
418 DevInfoLengthAta
= 0;
419 TmpDev
= mOpalDriver
.DeviceList
;
420 while (TmpDev
!= NULL
) {
421 DeviceType
= ExtractDeviceInfoFromDevicePath (
422 TmpDev
->OpalDisk
.OpalDevicePath
,
426 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
427 DevInfoLengthAta
+= DevInfoLength
;
430 TmpDev
= TmpDev
->Next
;
433 if (DevInfoLengthAta
== 0) {
437 DevInfoAta
= AllocateZeroPool (DevInfoLengthAta
);
438 ASSERT (DevInfoAta
!= NULL
);
440 TempDevInfoAta
= DevInfoAta
;
441 TmpDev
= mOpalDriver
.DeviceList
;
442 while (TmpDev
!= NULL
) {
443 DeviceType
= ExtractDeviceInfoFromDevicePath (
444 TmpDev
->OpalDisk
.OpalDevicePath
,
448 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
449 ExtractDeviceInfoFromDevicePath (
450 TmpDev
->OpalDisk
.OpalDevicePath
,
452 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
454 TempDevInfoAta
->Length
= DevInfoLength
;
455 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
456 TempDevInfoAta
->BarAddr
= BarAddr
;
458 TempDevInfoAta
->Password
,
459 TmpDev
->OpalDisk
.Password
,
460 TmpDev
->OpalDisk
.PasswordLength
462 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
463 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
464 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
467 TmpDev
= TmpDev
->Next
;
470 Status
= SaveLockBox (
475 ASSERT_EFI_ERROR (Status
);
477 Status
= SetLockBoxAttributes (
479 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
481 ASSERT_EFI_ERROR (Status
);
483 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
484 FreePool (DevInfoAta
);
488 Build NVMe OPAL device info and save them to LockBox.
490 @param[in] BarAddr Bar address allocated.
494 BuildOpalDeviceInfoNvme (
500 OPAL_DEVICE_NVME
*DevInfoNvme
;
501 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
502 UINTN DevInfoLengthNvme
;
503 UINT16 DevInfoLength
;
504 OPAL_DRIVER_DEVICE
*TmpDev
;
507 // Build NVMe OPAL device info and save them to LockBox.
509 DevInfoLengthNvme
= 0;
510 TmpDev
= mOpalDriver
.DeviceList
;
511 while (TmpDev
!= NULL
) {
512 DeviceType
= ExtractDeviceInfoFromDevicePath (
513 TmpDev
->OpalDisk
.OpalDevicePath
,
517 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
518 DevInfoLengthNvme
+= DevInfoLength
;
521 TmpDev
= TmpDev
->Next
;
524 if (DevInfoLengthNvme
== 0) {
528 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
529 ASSERT (DevInfoNvme
!= NULL
);
531 TempDevInfoNvme
= DevInfoNvme
;
532 TmpDev
= mOpalDriver
.DeviceList
;
533 while (TmpDev
!= NULL
) {
534 DeviceType
= ExtractDeviceInfoFromDevicePath (
535 TmpDev
->OpalDisk
.OpalDevicePath
,
539 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
540 ExtractDeviceInfoFromDevicePath (
541 TmpDev
->OpalDisk
.OpalDevicePath
,
543 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
545 TempDevInfoNvme
->Length
= DevInfoLength
;
546 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
547 TempDevInfoNvme
->BarAddr
= BarAddr
;
549 TempDevInfoNvme
->Password
,
550 TmpDev
->OpalDisk
.Password
,
551 TmpDev
->OpalDisk
.PasswordLength
553 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
554 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
557 TmpDev
= TmpDev
->Next
;
560 Status
= SaveLockBox (
561 &mOpalDeviceNvmeGuid
,
565 ASSERT_EFI_ERROR (Status
);
567 Status
= SetLockBoxAttributes (
568 &mOpalDeviceNvmeGuid
,
569 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
571 ASSERT_EFI_ERROR (Status
);
573 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
574 FreePool (DevInfoNvme
);
578 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
580 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
582 @param Event Event whose notification function is being invoked.
583 @param Context Pointer to the notification function's context.
588 OpalEndOfDxeEventNotify (
594 EFI_PHYSICAL_ADDRESS Address
;
596 OPAL_DRIVER_DEVICE
*TmpDev
;
598 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
600 mOpalEndOfDxe
= TRUE
;
602 if (mOpalRequestVariable
!= NULL
) {
604 // Free the OPAL request variable buffer here
605 // as the OPAL requests should have been processed.
607 FreePool (mOpalRequestVariable
);
608 mOpalRequestVariable
= NULL
;
609 mOpalRequestVariableSize
= 0;
613 // If no any device, return directly.
615 if (mOpalDriver
.DeviceList
== NULL
) {
616 gBS
->CloseEvent (Event
);
621 // Assume 64K size and alignment are enough.
624 Address
= 0xFFFFFFFF;
625 Status
= gDS
->AllocateMemorySpace (
626 EfiGcdAllocateMaxAddressSearchBottomUp
,
627 EfiGcdMemoryTypeMemoryMappedIo
,
628 16, // 2^16: 64K Alignment
634 ASSERT_EFI_ERROR (Status
);
636 BuildOpalDeviceInfoAta ((UINT32
) Address
);
637 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
642 TmpDev
= mOpalDriver
.DeviceList
;
643 while (TmpDev
!= NULL
) {
644 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
645 TmpDev
= TmpDev
->Next
;
648 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
650 gBS
->CloseEvent (Event
);
654 Get Psid input from the popup window.
656 @param[in] Dev The device which need Psid to process Psid Revert
658 @param[in] PopUpString Pop up string.
659 @param[in] PopUpString2 Pop up string in line 2.
661 @param[out] PressEsc Whether user escape function through Press ESC.
663 @retval Psid string if success. NULL if failed.
667 OpalDriverPopUpPsidInput (
668 IN OPAL_DRIVER_DEVICE
*Dev
,
669 IN CHAR16
*PopUpString
,
670 IN CHAR16
*PopUpString2
,
671 OUT BOOLEAN
*PressEsc
674 EFI_INPUT_KEY InputKey
;
676 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
677 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
680 ZeroMem(Unicode
, sizeof(Unicode
));
681 ZeroMem(Mask
, sizeof(Mask
));
685 gST
->ConOut
->ClearScreen(gST
->ConOut
);
689 Mask
[InputLength
] = L
'_';
690 if (PopUpString2
== NULL
) {
692 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
695 L
"---------------------",
701 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
705 L
"---------------------",
714 if (InputKey
.ScanCode
== SCAN_NULL
) {
718 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
720 // Add the null terminator.
722 Unicode
[InputLength
] = 0;
723 Mask
[InputLength
] = 0;
725 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
726 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
727 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
732 // delete last key entered
734 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
735 if (InputLength
> 0) {
736 Unicode
[InputLength
] = 0;
737 Mask
[InputLength
] = 0;
742 // add Next key entry
744 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
745 Mask
[InputLength
] = InputKey
.UnicodeChar
;
747 if (InputLength
== PSID_CHARACTER_LENGTH
) {
749 // Add the null terminator.
751 Unicode
[InputLength
] = 0;
752 Mask
[InputLength
] = 0;
762 if (InputKey
.ScanCode
== SCAN_ESC
) {
768 gST
->ConOut
->ClearScreen(gST
->ConOut
);
770 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
771 ZeroMem (Unicode
, sizeof (Unicode
));
772 ZeroMem (Mask
, sizeof (Mask
));
776 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
778 ZeroMem (Unicode
, sizeof (Unicode
));
779 ZeroMem (Mask
, sizeof (Mask
));
783 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
784 ZeroMem (Unicode
, sizeof (Unicode
));
785 ZeroMem (Mask
, sizeof (Mask
));
792 Get password input from the popup window.
794 @param[in] Dev The device which need password to unlock or
795 process OPAL request.
796 @param[in] PopUpString1 Pop up string 1.
797 @param[in] PopUpString2 Pop up string 2.
798 @param[out] PressEsc Whether user escape function through Press ESC.
800 @retval Password string if success. NULL if failed.
804 OpalDriverPopUpPasswordInput (
805 IN OPAL_DRIVER_DEVICE
*Dev
,
806 IN CHAR16
*PopUpString1
,
807 IN CHAR16
*PopUpString2
,
808 OUT BOOLEAN
*PressEsc
811 EFI_INPUT_KEY InputKey
;
813 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
814 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
817 ZeroMem(Unicode
, sizeof(Unicode
));
818 ZeroMem(Mask
, sizeof(Mask
));
822 gST
->ConOut
->ClearScreen(gST
->ConOut
);
826 Mask
[InputLength
] = L
'_';
827 if (PopUpString2
== NULL
) {
829 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
832 L
"---------------------",
838 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
842 L
"---------------------",
851 if (InputKey
.ScanCode
== SCAN_NULL
) {
855 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
857 // Add the null terminator.
859 Unicode
[InputLength
] = 0;
860 Mask
[InputLength
] = 0;
862 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
863 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
864 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
869 // delete last key entered
871 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
872 if (InputLength
> 0) {
873 Unicode
[InputLength
] = 0;
874 Mask
[InputLength
] = 0;
879 // add Next key entry
881 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
882 Mask
[InputLength
] = L
'*';
884 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
886 // Add the null terminator.
888 Unicode
[InputLength
] = 0;
889 Mask
[InputLength
] = 0;
899 if (InputKey
.ScanCode
== SCAN_ESC
) {
905 gST
->ConOut
->ClearScreen(gST
->ConOut
);
907 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
908 ZeroMem (Unicode
, sizeof (Unicode
));
912 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
914 ZeroMem (Unicode
, sizeof (Unicode
));
918 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
919 ZeroMem (Unicode
, sizeof (Unicode
));
927 @param[in] Dev The OPAL device.
928 @param[in] RequestString Request string.
930 @return Pop up string.
935 IN OPAL_DRIVER_DEVICE
*Dev
,
936 IN CHAR16
*RequestString
939 if (Dev
->Name16
== NULL
) {
940 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
942 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
949 Check if disk is locked, show popup window and ask for password if it is.
951 @param[in] Dev The device which need to be unlocked.
952 @param[in] RequestString Request string.
956 OpalDriverRequestPassword (
957 IN OPAL_DRIVER_DEVICE
*Dev
,
958 IN CHAR16
*RequestString
966 OPAL_SESSION Session
;
976 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
978 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
982 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
984 ZeroMem(&Session
, sizeof(Session
));
985 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
986 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
987 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
989 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
991 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
995 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
996 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1000 // Current device in the lock status and
1001 // User not input password and press ESC,
1002 // keep device in lock status and continue boot.
1006 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1008 L
"Press ENTER to skip the request and continue boot,",
1009 L
"Press ESC to input password again",
1012 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1014 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1015 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1017 // Keep lock and continue boot.
1022 // Let user input password again.
1028 // Current device in the unlock status and
1029 // User not input password and press ESC,
1030 // Shutdown the device.
1034 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1036 L
"Press ENTER to shutdown, Press ESC to input password again",
1039 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1041 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1042 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1045 // Let user input password again.
1052 if (Password
== NULL
) {
1056 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1059 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1061 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1062 if (Ret
== TcgResultSuccess
) {
1063 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1067 if (Ret
== TcgResultSuccess
) {
1068 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1069 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1071 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1074 if (Password
!= NULL
) {
1075 ZeroMem (Password
, PasswordLen
);
1076 FreePool (Password
);
1079 if (Ret
== TcgResultSuccess
) {
1084 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
1085 // before accept new password.
1087 if (Ret
== TcgResultFailureInvalidType
) {
1088 Count
= MAX_PASSWORD_TRY_COUNT
;
1096 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1098 L
"Invalid password.",
1099 L
"Press ENTER to retry",
1102 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1105 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1108 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1110 L
"Opal password retry count exceeds the limit. Must shutdown!",
1111 L
"Press ENTER to shutdown",
1114 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1116 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1122 Process Enable Feature OPAL request.
1124 @param[in] Dev The device which has Enable Feature OPAL request.
1125 @param[in] RequestString Request string.
1129 ProcessOpalRequestEnableFeature (
1130 IN OPAL_DRIVER_DEVICE
*Dev
,
1131 IN CHAR16
*RequestString
1137 CHAR8
*PasswordConfirm
;
1138 UINT32 PasswordLenConfirm
;
1139 OPAL_SESSION Session
;
1143 CHAR16
*PopUpString
;
1149 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1151 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1155 ZeroMem(&Session
, sizeof(Session
));
1156 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1157 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1158 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1160 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1161 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1165 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1167 L
"Press ENTER to skip the request and continue boot,",
1168 L
"Press ESC to input password again",
1171 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1173 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1174 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1178 // Let user input password again.
1184 if (Password
== NULL
) {
1188 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1190 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1191 if (PasswordConfirm
== NULL
) {
1192 ZeroMem (Password
, PasswordLen
);
1193 FreePool (Password
);
1197 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1198 if ((PasswordLen
!= PasswordLenConfirm
) ||
1199 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1200 ZeroMem (Password
, PasswordLen
);
1201 FreePool (Password
);
1202 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1203 FreePool (PasswordConfirm
);
1206 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1208 L
"Passwords are not the same.",
1209 L
"Press ENTER to retry",
1212 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1217 if (PasswordConfirm
!= NULL
) {
1218 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1219 FreePool (PasswordConfirm
);
1222 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1223 if (Ret
== TcgResultSuccess
) {
1224 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1225 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1227 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1230 if (Password
!= NULL
) {
1231 ZeroMem (Password
, PasswordLen
);
1232 FreePool (Password
);
1235 if (Ret
== TcgResultSuccess
) {
1243 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1246 L
"Press ENTER to retry",
1249 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1252 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1255 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1257 L
"Opal password retry count exceeds the limit.",
1258 L
"Press ENTER to skip the request and continue boot",
1261 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1262 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1267 Process Disable User OPAL request.
1269 @param[in] Dev The device which has Disable User OPAL request.
1270 @param[in] RequestString Request string.
1274 ProcessOpalRequestDisableUser (
1275 IN OPAL_DRIVER_DEVICE
*Dev
,
1276 IN CHAR16
*RequestString
1282 OPAL_SESSION Session
;
1286 BOOLEAN PasswordFailed
;
1287 CHAR16
*PopUpString
;
1293 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1295 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1299 ZeroMem(&Session
, sizeof(Session
));
1300 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1301 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1302 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1304 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1305 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1309 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1311 L
"Press ENTER to skip the request and continue boot,",
1312 L
"Press ESC to input password again",
1315 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1317 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1318 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1322 // Let user input password again.
1328 if (Password
== NULL
) {
1332 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1334 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1335 if (Ret
== TcgResultSuccess
) {
1336 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1337 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1339 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1342 if (Password
!= NULL
) {
1343 ZeroMem (Password
, PasswordLen
);
1344 FreePool (Password
);
1347 if (Ret
== TcgResultSuccess
) {
1355 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1357 L
"Invalid password, request failed.",
1358 L
"Press ENTER to retry",
1361 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1364 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1367 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1369 L
"Opal password retry count exceeds the limit.",
1370 L
"Press ENTER to skip the request and continue boot",
1373 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1374 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1379 Process Psid Revert OPAL request.
1381 @param[in] Dev The device which has Psid Revert OPAL request.
1382 @param[in] RequestString Request string.
1386 ProcessOpalRequestPsidRevert (
1387 IN OPAL_DRIVER_DEVICE
*Dev
,
1388 IN CHAR16
*RequestString
1394 OPAL_SESSION Session
;
1398 CHAR16
*PopUpString
;
1399 CHAR16
*PopUpString2
;
1406 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1408 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1410 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1411 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1412 PopUpString2
= AllocateZeroPool (BufferSize
);
1413 ASSERT (PopUpString2
!= NULL
);
1417 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1418 Dev
->OpalDisk
.EstimateTimeCost
1421 PopUpString2
= NULL
;
1426 ZeroMem(&Session
, sizeof(Session
));
1427 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1428 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1429 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1431 while (Count
< MAX_PSID_TRY_COUNT
) {
1432 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1436 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1438 L
"Press ENTER to skip the request and continue boot,",
1439 L
"Press ESC to input Psid again",
1442 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1444 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1445 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1449 // Let user input Psid again.
1459 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1461 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1462 if (Ret
== TcgResultSuccess
) {
1463 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1465 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1469 ZeroMem (Psid
, PsidLen
);
1473 if (Ret
== TcgResultSuccess
) {
1481 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1483 L
"Invalid Psid, request failed.",
1484 L
"Press ENTER to retry",
1487 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1490 if (Count
>= MAX_PSID_TRY_COUNT
) {
1493 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1495 L
"Opal Psid retry count exceeds the limit.",
1496 L
"Press ENTER to skip the request and continue boot",
1499 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1500 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1504 if (PopUpString2
!= NULL
) {
1505 FreePool (PopUpString2
);
1510 Process Admin Revert OPAL request.
1512 @param[in] Dev The device which has Revert OPAL request.
1513 @param[in] KeepUserData Whether to keep user data or not.
1514 @param[in] RequestString Request string.
1518 ProcessOpalRequestRevert (
1519 IN OPAL_DRIVER_DEVICE
*Dev
,
1520 IN BOOLEAN KeepUserData
,
1521 IN CHAR16
*RequestString
1527 OPAL_SESSION Session
;
1531 BOOLEAN PasswordFailed
;
1532 CHAR16
*PopUpString
;
1533 CHAR16
*PopUpString2
;
1540 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1542 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1544 if ((!KeepUserData
) &&
1545 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1546 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1547 PopUpString2
= AllocateZeroPool (BufferSize
);
1548 ASSERT (PopUpString2
!= NULL
);
1552 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1553 Dev
->OpalDisk
.EstimateTimeCost
1556 PopUpString2
= NULL
;
1561 ZeroMem(&Session
, sizeof(Session
));
1562 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1563 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1564 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1566 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1567 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1571 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1573 L
"Press ENTER to skip the request and continue boot,",
1574 L
"Press ESC to input password again",
1577 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1579 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1580 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1584 // Let user input password again.
1590 if (Password
== NULL
) {
1594 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1596 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1597 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1599 // For pyrite type device which does not support media encryption,
1600 // it does not accept "Keep User Data" parameter.
1601 // So here hardcode a FALSE for this case.
1603 Ret
= OpalUtilRevert(
1610 Dev
->OpalDisk
.MsidLength
1613 Ret
= OpalUtilRevert(
1620 Dev
->OpalDisk
.MsidLength
1623 if (Ret
== TcgResultSuccess
) {
1624 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1625 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1627 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1630 if (Password
!= NULL
) {
1631 ZeroMem (Password
, PasswordLen
);
1632 FreePool (Password
);
1635 if (Ret
== TcgResultSuccess
) {
1643 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1645 L
"Invalid password, request failed.",
1646 L
"Press ENTER to retry",
1649 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1652 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1655 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1657 L
"Opal password retry count exceeds the limit.",
1658 L
"Press ENTER to skip the request and continue boot",
1661 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1662 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1666 if (PopUpString2
!= NULL
) {
1667 FreePool (PopUpString2
);
1672 Process Secure Erase OPAL request.
1674 @param[in] Dev The device which has Secure Erase OPAL request.
1675 @param[in] RequestString Request string.
1679 ProcessOpalRequestSecureErase (
1680 IN OPAL_DRIVER_DEVICE
*Dev
,
1681 IN CHAR16
*RequestString
1687 OPAL_SESSION Session
;
1691 BOOLEAN PasswordFailed
;
1692 CHAR16
*PopUpString
;
1698 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1700 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1704 ZeroMem(&Session
, sizeof(Session
));
1705 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1706 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1707 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1709 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1710 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1714 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1716 L
"Press ENTER to skip the request and continue boot,",
1717 L
"Press ESC to input password again",
1720 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1722 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1723 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1727 // Let user input password again.
1733 if (Password
== NULL
) {
1737 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1739 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1740 if (Ret
== TcgResultSuccess
) {
1741 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1742 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1744 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1747 if (Password
!= NULL
) {
1748 ZeroMem (Password
, PasswordLen
);
1749 FreePool (Password
);
1752 if (Ret
== TcgResultSuccess
) {
1760 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1762 L
"Invalid password, request failed.",
1763 L
"Press ENTER to retry",
1766 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1769 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1772 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1774 L
"Opal password retry count exceeds the limit.",
1775 L
"Press ENTER to skip the request and continue boot",
1778 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1779 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1784 Process Set Admin Pwd OPAL request.
1786 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1787 @param[in] RequestString Request string.
1791 ProcessOpalRequestSetUserPwd (
1792 IN OPAL_DRIVER_DEVICE
*Dev
,
1793 IN CHAR16
*RequestString
1798 UINT32 OldPasswordLen
;
1801 CHAR8
*PasswordConfirm
;
1802 UINT32 PasswordLenConfirm
;
1803 OPAL_SESSION Session
;
1807 CHAR16
*PopUpString
;
1813 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1815 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1819 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1820 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1824 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1826 L
"Press ENTER to skip the request and continue boot,",
1827 L
"Press ESC to input password again",
1830 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1832 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1833 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1837 // Let user input password again.
1843 if (OldPassword
== NULL
) {
1847 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1849 ZeroMem(&Session
, sizeof(Session
));
1850 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1851 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1852 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1853 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1854 if (Ret
== TcgResultSuccess
) {
1855 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1857 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1858 if (Ret
== TcgResultSuccess
) {
1859 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1861 ZeroMem (OldPassword
, OldPasswordLen
);
1862 FreePool (OldPassword
);
1863 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1866 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1868 L
"Incorrect password.",
1869 L
"Press ENTER to retry",
1872 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1878 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1879 if (Password
== NULL
) {
1880 ZeroMem (OldPassword
, OldPasswordLen
);
1881 FreePool (OldPassword
);
1885 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1887 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1888 if (PasswordConfirm
== NULL
) {
1889 ZeroMem (OldPassword
, OldPasswordLen
);
1890 FreePool (OldPassword
);
1891 ZeroMem (Password
, PasswordLen
);
1892 FreePool (Password
);
1896 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1897 if ((PasswordLen
!= PasswordLenConfirm
) ||
1898 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1899 ZeroMem (OldPassword
, OldPasswordLen
);
1900 FreePool (OldPassword
);
1901 ZeroMem (Password
, PasswordLen
);
1902 FreePool (Password
);
1903 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1904 FreePool (PasswordConfirm
);
1907 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1909 L
"Passwords are not the same.",
1910 L
"Press ENTER to retry",
1913 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1918 if (PasswordConfirm
!= NULL
) {
1919 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1920 FreePool (PasswordConfirm
);
1923 ZeroMem(&Session
, sizeof(Session
));
1924 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1925 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1926 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1927 Ret
= OpalUtilSetUserPassword(
1934 if (Ret
== TcgResultSuccess
) {
1935 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1936 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1938 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1941 if (OldPassword
!= NULL
) {
1942 ZeroMem (OldPassword
, OldPasswordLen
);
1943 FreePool (OldPassword
);
1946 if (Password
!= NULL
) {
1947 ZeroMem (Password
, PasswordLen
);
1948 FreePool (Password
);
1951 if (Ret
== TcgResultSuccess
) {
1959 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1962 L
"Press ENTER to retry",
1965 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1968 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1971 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1973 L
"Opal password retry count exceeds the limit.",
1974 L
"Press ENTER to skip the request and continue boot",
1977 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1978 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1983 Process Set Admin Pwd OPAL request.
1985 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1986 @param[in] RequestString Request string.
1990 ProcessOpalRequestSetAdminPwd (
1991 IN OPAL_DRIVER_DEVICE
*Dev
,
1992 IN CHAR16
*RequestString
1997 UINT32 OldPasswordLen
;
2000 CHAR8
*PasswordConfirm
;
2001 UINT32 PasswordLenConfirm
;
2002 OPAL_SESSION Session
;
2006 CHAR16
*PopUpString
;
2012 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
2014 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
2018 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
2019 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
2023 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2025 L
"Press ENTER to skip the request and continue boot,",
2026 L
"Press ESC to input password again",
2029 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
2031 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2032 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2036 // Let user input password again.
2042 if (OldPassword
== NULL
) {
2046 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
2048 ZeroMem(&Session
, sizeof(Session
));
2049 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2050 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2051 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2052 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2053 if (Ret
== TcgResultSuccess
) {
2054 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2056 ZeroMem (OldPassword
, OldPasswordLen
);
2057 FreePool (OldPassword
);
2058 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2061 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2063 L
"Incorrect password.",
2064 L
"Press ENTER to retry",
2067 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2072 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2073 if (Password
== NULL
) {
2074 ZeroMem (OldPassword
, OldPasswordLen
);
2075 FreePool (OldPassword
);
2079 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2081 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2082 if (PasswordConfirm
== NULL
) {
2083 ZeroMem (OldPassword
, OldPasswordLen
);
2084 FreePool (OldPassword
);
2085 ZeroMem (Password
, PasswordLen
);
2086 FreePool (Password
);
2090 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2091 if ((PasswordLen
!= PasswordLenConfirm
) ||
2092 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2093 ZeroMem (OldPassword
, OldPasswordLen
);
2094 FreePool (OldPassword
);
2095 ZeroMem (Password
, PasswordLen
);
2096 FreePool (Password
);
2097 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2098 FreePool (PasswordConfirm
);
2101 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2103 L
"Passwords are not the same.",
2104 L
"Press ENTER to retry",
2107 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2112 if (PasswordConfirm
!= NULL
) {
2113 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2114 FreePool (PasswordConfirm
);
2118 ZeroMem(&Session
, sizeof(Session
));
2119 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2120 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2121 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2122 Ret
= OpalUtilSetAdminPassword(
2129 if (Ret
== TcgResultSuccess
) {
2130 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2131 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2133 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2136 if (OldPassword
!= NULL
) {
2137 ZeroMem (OldPassword
, OldPasswordLen
);
2138 FreePool (OldPassword
);
2141 if (Password
!= NULL
) {
2142 ZeroMem (Password
, PasswordLen
);
2143 FreePool (Password
);
2146 if (Ret
== TcgResultSuccess
) {
2154 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2157 L
"Press ENTER to retry",
2160 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2163 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2166 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2168 L
"Opal password retry count exceeds the limit.",
2169 L
"Press ENTER to skip the request and continue boot",
2172 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2173 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2178 Process OPAL request.
2180 @param[in] Dev The device which has OPAL request.
2184 ProcessOpalRequest (
2185 IN OPAL_DRIVER_DEVICE
*Dev
2189 OPAL_REQUEST_VARIABLE
*TempVariable
;
2190 OPAL_REQUEST_VARIABLE
*Variable
;
2192 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2193 UINTN DevicePathSizeInVariable
;
2194 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2195 UINTN DevicePathSize
;
2196 BOOLEAN KeepUserData
;
2198 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2200 if (mOpalRequestVariable
== NULL
) {
2201 Status
= GetVariable2 (
2202 OPAL_REQUEST_VARIABLE_NAME
,
2203 &gHiiSetupVariableGuid
,
2204 (VOID
**) &Variable
,
2207 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2210 mOpalRequestVariable
= Variable
;
2211 mOpalRequestVariableSize
= VariableSize
;
2214 // Delete the OPAL request variable.
2216 Status
= gRT
->SetVariable (
2217 OPAL_REQUEST_VARIABLE_NAME
,
2218 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2223 ASSERT_EFI_ERROR (Status
);
2225 Variable
= mOpalRequestVariable
;
2226 VariableSize
= mOpalRequestVariableSize
;
2230 // Process the OPAL requests.
2232 TempVariable
= Variable
;
2233 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2234 (VariableSize
>= TempVariable
->Length
) &&
2235 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2236 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2237 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2238 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2239 DevicePathSize
= GetDevicePathSize (DevicePath
);
2240 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2241 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2243 // Found the node for the OPAL device.
2245 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2246 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2248 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2249 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2251 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2252 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2254 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2255 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2256 ProcessOpalRequestRevert (
2259 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2262 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2263 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2265 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2266 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2268 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2269 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2275 VariableSize
-= TempVariable
->Length
;
2276 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2279 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2283 Add new device to the global device list.
2285 @param Dev New create device.
2290 IN OPAL_DRIVER_DEVICE
*Dev
2293 OPAL_DRIVER_DEVICE
*TmpDev
;
2295 if (mOpalDriver
.DeviceList
== NULL
) {
2296 mOpalDriver
.DeviceList
= Dev
;
2298 TmpDev
= mOpalDriver
.DeviceList
;
2299 while (TmpDev
->Next
!= NULL
) {
2300 TmpDev
= TmpDev
->Next
;
2308 Remove one device in the global device list.
2310 @param Dev The device need to be removed.
2315 IN OPAL_DRIVER_DEVICE
*Dev
2318 OPAL_DRIVER_DEVICE
*TmpDev
;
2320 if (mOpalDriver
.DeviceList
== NULL
) {
2324 if (mOpalDriver
.DeviceList
== Dev
) {
2325 mOpalDriver
.DeviceList
= NULL
;
2329 TmpDev
= mOpalDriver
.DeviceList
;
2330 while (TmpDev
->Next
!= NULL
) {
2331 if (TmpDev
->Next
== Dev
) {
2332 TmpDev
->Next
= Dev
->Next
;
2339 Get current device count.
2341 @retval return the current created device count.
2350 OPAL_DRIVER_DEVICE
*TmpDev
;
2353 TmpDev
= mOpalDriver
.DeviceList
;
2355 while (TmpDev
!= NULL
) {
2357 TmpDev
= TmpDev
->Next
;
2364 Get devcie list info.
2366 @retval return the device list pointer.
2369 OpalDriverGetDeviceList(
2373 return mOpalDriver
.DeviceList
;
2377 ReadyToBoot callback to send BlockSid command.
2379 @param Event Pointer to this event
2380 @param Context Event handler private Data
2385 ReadyToBootCallback (
2390 OPAL_DRIVER_DEVICE
*Itr
;
2392 OPAL_SESSION Session
;
2393 UINT32 PpStorageFlag
;
2395 gBS
->CloseEvent (Event
);
2397 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2398 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2400 // Send BlockSID command to each Opal disk
2402 Itr
= mOpalDriver
.DeviceList
;
2403 while (Itr
!= NULL
) {
2404 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2405 ZeroMem(&Session
, sizeof(Session
));
2406 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2407 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2408 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2410 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2411 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2412 if (Result
!= TcgResultSuccess
) {
2413 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2424 Stop this Controller.
2426 @param Dev The device need to be stopped.
2430 OpalDriverStopDevice (
2431 OPAL_DRIVER_DEVICE
*Dev
2437 FreePool(Dev
->Name16
);
2440 // remove OPAL_DRIVER_DEVICE from the list
2441 // it updates the controllerList pointer
2446 // close protocols that were opened
2450 &gEfiStorageSecurityCommandProtocolGuid
,
2451 gOpalDriverBinding
.DriverBindingHandle
,
2457 &gEfiBlockIoProtocolGuid
,
2458 gOpalDriverBinding
.DriverBindingHandle
,
2466 Get devcie name through the component name protocol.
2468 @param[in] AllHandlesBuffer The handle buffer for current system.
2469 @param[in] NumAllHandles The number of handles for the handle buffer.
2470 @param[in] Dev The device which need to get name.
2471 @param[in] UseComp1 Whether use component name or name2 protocol.
2473 @retval TRUE Find the name for this device.
2474 @retval FALSE Not found the name for this device.
2477 OpalDriverGetDeviceNameByProtocol(
2478 EFI_HANDLE
*AllHandlesBuffer
,
2479 UINTN NumAllHandles
,
2480 OPAL_DRIVER_DEVICE
*Dev
,
2484 EFI_HANDLE
* ProtocolHandlesBuffer
;
2485 UINTN NumProtocolHandles
;
2487 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2490 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2493 EFI_HANDLE TmpHandle
;
2496 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2500 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2503 // Find all EFI_HANDLES with protocol
2505 Status
= gBS
->LocateHandleBuffer(
2509 &NumProtocolHandles
,
2510 &ProtocolHandlesBuffer
2512 if (EFI_ERROR(Status
)) {
2518 // Exit early if no supported devices
2520 if (NumProtocolHandles
== 0) {
2525 // Get printable name by iterating through all protocols
2526 // using the handle as the child, and iterate through all handles for the controller
2527 // exit loop early once found, if not found, then delete device
2528 // storage security protocol instances already exist, add them to internal list
2530 Status
= EFI_DEVICE_ERROR
;
2531 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2534 if (Dev
->Name16
!= NULL
) {
2538 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2540 Status
= gBS
->OpenProtocol(
2546 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2548 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2553 // Use all handles array as controller handle
2555 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2556 Status
= Cnp1_2
->GetControllerName(
2558 AllHandlesBuffer
[Index2
],
2560 LANGUAGE_ISO_639_2_ENGLISH
,
2563 if (EFI_ERROR(Status
)) {
2564 Status
= Cnp1_2
->GetControllerName(
2566 AllHandlesBuffer
[Index2
],
2568 LANGUAGE_RFC_3066_ENGLISH
,
2572 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2573 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2574 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2575 ASSERT (Dev
->Name16
!= NULL
);
2576 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2577 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2578 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2581 // Retrieve bridge BDF info and port number or namespace depending on type
2584 Status
= gBS
->OpenProtocol(
2586 &gEfiDevicePathProtocolGuid
,
2587 (VOID
**)&TmpDevPath
,
2590 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2592 if (!EFI_ERROR(Status
)) {
2593 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2597 if (Dev
->Name16
!= NULL
) {
2598 FreePool(Dev
->Name16
);
2601 if (Dev
->NameZ
!= NULL
) {
2602 FreePool(Dev
->NameZ
);
2613 Get devcie name through the component name protocol.
2615 @param[in] Dev The device which need to get name.
2617 @retval TRUE Find the name for this device.
2618 @retval FALSE Not found the name for this device.
2621 OpalDriverGetDriverDeviceName(
2622 OPAL_DRIVER_DEVICE
*Dev
2625 EFI_HANDLE
* AllHandlesBuffer
;
2626 UINTN NumAllHandles
;
2630 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2635 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2637 if (Dev
->Name16
== NULL
) {
2638 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2640 // Find all EFI_HANDLES
2642 Status
= gBS
->LocateHandleBuffer(
2649 if (EFI_ERROR(Status
)) {
2650 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2655 // Try component Name2
2657 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2658 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2659 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2660 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2670 Main entry for this driver.
2672 @param ImageHandle Image Handle this driver.
2673 @param SystemTable Pointer to SystemTable.
2675 @retval EFI_SUCESS This function always complete successfully.
2679 EfiDriverEntryPoint(
2680 IN EFI_HANDLE ImageHandle
,
2681 IN EFI_SYSTEM_TABLE
* SystemTable
2685 EFI_EVENT ReadyToBootEvent
;
2686 EFI_EVENT EndOfDxeEvent
;
2688 Status
= EfiLibInstallDriverBindingComponentName2 (
2691 &gOpalDriverBinding
,
2693 &gOpalComponentName
,
2694 &gOpalComponentName2
2697 if (EFI_ERROR(Status
)) {
2698 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2703 // Initialize Driver object
2705 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2706 mOpalDriver
.Handle
= ImageHandle
;
2708 Status
= gBS
->CreateEventEx (
2711 OpalEndOfDxeEventNotify
,
2713 &gEfiEndOfDxeEventGroupGuid
,
2716 ASSERT_EFI_ERROR (Status
);
2719 // register a ReadyToBoot event callback for sending BlockSid command
2721 Status
= EfiCreateEventReadyToBootEx (
2723 ReadyToBootCallback
,
2724 (VOID
*) &ImageHandle
,
2729 // Install Hii packages.
2737 Tests to see if this driver supports a given controller.
2739 This function checks to see if the controller contains an instance of the
2740 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2741 and returns EFI_SUCCESS if it does.
2743 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2744 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2745 must support a protocol interface that supplies
2746 an I/O abstraction to the driver.
2747 @param[in] RemainingDevicePath This parameter is ignored.
2749 @retval EFI_SUCCESS The device contains required protocols
2750 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2751 RemainingDevicePath is already being managed by the driver
2753 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2754 RemainingDevicePath is already being managed by a different
2755 driver or an application that requires exclusive access.
2756 Currently not implemented.
2757 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2762 OpalEfiDriverBindingSupported(
2763 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2764 IN EFI_HANDLE Controller
,
2765 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2769 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2770 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2772 if (mOpalEndOfDxe
) {
2773 return EFI_UNSUPPORTED
;
2777 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2779 Status
= gBS
->OpenProtocol(
2781 &gEfiStorageSecurityCommandProtocolGuid
,
2782 ( VOID
** )&SecurityCommand
,
2783 This
->DriverBindingHandle
,
2785 EFI_OPEN_PROTOCOL_BY_DRIVER
2788 if (Status
== EFI_ALREADY_STARTED
) {
2792 if (EFI_ERROR(Status
)) {
2797 // Close protocol and reopen in Start call
2801 &gEfiStorageSecurityCommandProtocolGuid
,
2802 This
->DriverBindingHandle
,
2807 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2810 Status
= gBS
->OpenProtocol(
2812 &gEfiBlockIoProtocolGuid
,
2814 This
->DriverBindingHandle
,
2816 EFI_OPEN_PROTOCOL_BY_DRIVER
2819 if (EFI_ERROR(Status
)) {
2820 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2825 // Close protocol and reopen in Start call
2829 &gEfiBlockIoProtocolGuid
,
2830 This
->DriverBindingHandle
,
2838 Enables Opal Management on a supported device if available.
2840 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2841 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2842 This function will complete the other necessary checks, such as verifying the device supports
2843 the correct version of Opal. Upon verification, it will add the device to the
2844 Opal HII list in order to expose Opal managmeent options.
2846 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2847 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2848 must support a protocol interface that supplies
2849 an I/O abstraction to the driver.
2850 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2851 parameter is ignored by device drivers, and is optional for bus
2852 drivers. For a bus driver, if this parameter is NULL, then handles
2853 for all the children of Controller are created by this driver.
2854 If this parameter is not NULL and the first Device Path Node is
2855 not the End of Device Path Node, then only the Handle for the
2856 child device specified by the first Device Path Node of
2857 RemainingDevicePath is created by this driver.
2858 If the first Device Path Node of RemainingDevicePath is
2859 the End of Device Path Node, no child Handle is created by this
2862 @retval EFI_SUCCESS Opal management was enabled.
2863 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2864 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2865 @retval Others The driver failed to start the device.
2870 OpalEfiDriverBindingStart(
2871 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2872 IN EFI_HANDLE Controller
,
2873 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2877 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2878 OPAL_DRIVER_DEVICE
*Dev
;
2879 OPAL_DRIVER_DEVICE
*Itr
;
2882 Itr
= mOpalDriver
.DeviceList
;
2883 while (Itr
!= NULL
) {
2884 if (Controller
== Itr
->Handle
) {
2891 // Create internal device for tracking. This allows all disks to be tracked
2894 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2896 return EFI_OUT_OF_RESOURCES
;
2898 Dev
->Handle
= Controller
;
2901 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2903 Status
= gBS
->OpenProtocol(
2905 &gEfiStorageSecurityCommandProtocolGuid
,
2906 (VOID
**)&Dev
->Sscp
,
2907 This
->DriverBindingHandle
,
2909 EFI_OPEN_PROTOCOL_BY_DRIVER
2911 if (EFI_ERROR(Status
)) {
2917 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2920 Status
= gBS
->OpenProtocol(
2922 &gEfiBlockIoProtocolGuid
,
2924 This
->DriverBindingHandle
,
2926 EFI_OPEN_PROTOCOL_BY_DRIVER
2928 if (EFI_ERROR(Status
)) {
2930 // Close storage security that was opened
2934 &gEfiStorageSecurityCommandProtocolGuid
,
2935 This
->DriverBindingHandle
,
2946 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2950 &gEfiBlockIoProtocolGuid
,
2951 This
->DriverBindingHandle
,
2956 // Acquire Ascii printable name of child, if not found, then ignore device
2958 Result
= OpalDriverGetDriverDeviceName (Dev
);
2963 Status
= OpalDiskInitialize (Dev
);
2964 if (EFI_ERROR (Status
)) {
2968 AddDeviceToTail(Dev
);
2971 // Check if device is locked and prompt for password.
2973 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2976 // Process OPAL request from last boot.
2978 ProcessOpalRequest (Dev
);
2984 // free device, close protocols and exit
2988 &gEfiStorageSecurityCommandProtocolGuid
,
2989 This
->DriverBindingHandle
,
2995 return EFI_DEVICE_ERROR
;
2999 Stop this driver on Controller.
3001 @param This Protocol instance pointer.
3002 @param Controller Handle of device to stop driver on
3003 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
3004 children is zero stop the entire bus driver.
3005 @param ChildHandleBuffer List of Child Handles to Stop.
3007 @retval EFI_SUCCESS This driver is removed Controller.
3008 @retval other This driver could not be removed from this device.
3013 OpalEfiDriverBindingStop(
3014 EFI_DRIVER_BINDING_PROTOCOL
* This
,
3015 EFI_HANDLE Controller
,
3016 UINTN NumberOfChildren
,
3017 EFI_HANDLE
* ChildHandleBuffer
3020 OPAL_DRIVER_DEVICE
* Itr
;
3022 Itr
= mOpalDriver
.DeviceList
;
3025 // does Controller match any of the devices we are managing for Opal
3027 while (Itr
!= NULL
) {
3028 if (Itr
->Handle
== Controller
) {
3029 OpalDriverStopDevice (Itr
);
3036 return EFI_NOT_FOUND
;
3041 Unloads UEFI Driver. Very useful for debugging and testing.
3043 @param ImageHandle Image Handle this driver.
3045 @retval EFI_SUCCESS This function always complete successfully.
3046 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
3050 OpalEfiDriverUnload (
3051 IN EFI_HANDLE ImageHandle
3055 OPAL_DRIVER_DEVICE
*Itr
;
3057 Status
= EFI_SUCCESS
;
3059 if (ImageHandle
!= gImageHandle
) {
3060 return (EFI_INVALID_PARAMETER
);
3064 // Uninstall any interface added to each device by us
3066 while (mOpalDriver
.DeviceList
) {
3067 Itr
= mOpalDriver
.DeviceList
;
3069 // Remove OPAL_DRIVER_DEVICE from the list
3070 // it updates the controllerList pointer
3072 OpalDriverStopDevice(Itr
);
3076 // Uninstall the HII capability
3078 Status
= HiiUninstall();