2 Entrypoint of Opal UEFI Driver and contains all the logic to
3 register for new Opal device instances.
5 Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
6 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
);
439 if (DevInfoAta
== NULL
) {
443 TempDevInfoAta
= DevInfoAta
;
444 TmpDev
= mOpalDriver
.DeviceList
;
445 while (TmpDev
!= NULL
) {
446 DeviceType
= ExtractDeviceInfoFromDevicePath (
447 TmpDev
->OpalDisk
.OpalDevicePath
,
451 if (DeviceType
== OPAL_DEVICE_TYPE_ATA
) {
452 ExtractDeviceInfoFromDevicePath (
453 TmpDev
->OpalDisk
.OpalDevicePath
,
455 (OPAL_DEVICE_COMMON
*) TempDevInfoAta
457 TempDevInfoAta
->Length
= DevInfoLength
;
458 TempDevInfoAta
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
459 TempDevInfoAta
->BarAddr
= BarAddr
;
461 TempDevInfoAta
->Password
,
462 TmpDev
->OpalDisk
.Password
,
463 TmpDev
->OpalDisk
.PasswordLength
465 TempDevInfoAta
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
466 OpalDeviceAtaSaveBootScript (TempDevInfoAta
);
467 TempDevInfoAta
= (OPAL_DEVICE_ATA
*) ((UINTN
) TempDevInfoAta
+ DevInfoLength
);
470 TmpDev
= TmpDev
->Next
;
473 Status
= SaveLockBox (
478 ASSERT_EFI_ERROR (Status
);
480 Status
= SetLockBoxAttributes (
482 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
484 ASSERT_EFI_ERROR (Status
);
486 ZeroMem (DevInfoAta
, DevInfoLengthAta
);
487 FreePool (DevInfoAta
);
491 Build NVMe OPAL device info and save them to LockBox.
493 @param[in] BarAddr Bar address allocated.
497 BuildOpalDeviceInfoNvme (
503 OPAL_DEVICE_NVME
*DevInfoNvme
;
504 OPAL_DEVICE_NVME
*TempDevInfoNvme
;
505 UINTN DevInfoLengthNvme
;
506 UINT16 DevInfoLength
;
507 OPAL_DRIVER_DEVICE
*TmpDev
;
510 // Build NVMe OPAL device info and save them to LockBox.
512 DevInfoLengthNvme
= 0;
513 TmpDev
= mOpalDriver
.DeviceList
;
514 while (TmpDev
!= NULL
) {
515 DeviceType
= ExtractDeviceInfoFromDevicePath (
516 TmpDev
->OpalDisk
.OpalDevicePath
,
520 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
521 DevInfoLengthNvme
+= DevInfoLength
;
524 TmpDev
= TmpDev
->Next
;
527 if (DevInfoLengthNvme
== 0) {
531 DevInfoNvme
= AllocateZeroPool (DevInfoLengthNvme
);
532 ASSERT (DevInfoNvme
!= NULL
);
533 if (DevInfoNvme
== NULL
) {
537 TempDevInfoNvme
= DevInfoNvme
;
538 TmpDev
= mOpalDriver
.DeviceList
;
539 while (TmpDev
!= NULL
) {
540 DeviceType
= ExtractDeviceInfoFromDevicePath (
541 TmpDev
->OpalDisk
.OpalDevicePath
,
545 if (DeviceType
== OPAL_DEVICE_TYPE_NVME
) {
546 ExtractDeviceInfoFromDevicePath (
547 TmpDev
->OpalDisk
.OpalDevicePath
,
549 (OPAL_DEVICE_COMMON
*) TempDevInfoNvme
551 TempDevInfoNvme
->Length
= DevInfoLength
;
552 TempDevInfoNvme
->OpalBaseComId
= TmpDev
->OpalDisk
.OpalBaseComId
;
553 TempDevInfoNvme
->BarAddr
= BarAddr
;
555 TempDevInfoNvme
->Password
,
556 TmpDev
->OpalDisk
.Password
,
557 TmpDev
->OpalDisk
.PasswordLength
559 TempDevInfoNvme
->PasswordLength
= TmpDev
->OpalDisk
.PasswordLength
;
560 TempDevInfoNvme
= (OPAL_DEVICE_NVME
*) ((UINTN
) TempDevInfoNvme
+ DevInfoLength
);
563 TmpDev
= TmpDev
->Next
;
566 Status
= SaveLockBox (
567 &mOpalDeviceNvmeGuid
,
571 ASSERT_EFI_ERROR (Status
);
573 Status
= SetLockBoxAttributes (
574 &mOpalDeviceNvmeGuid
,
575 LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
577 ASSERT_EFI_ERROR (Status
);
579 ZeroMem (DevInfoNvme
, DevInfoLengthNvme
);
580 FreePool (DevInfoNvme
);
584 Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
586 This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
588 @param Event Event whose notification function is being invoked.
589 @param Context Pointer to the notification function's context.
594 OpalEndOfDxeEventNotify (
600 EFI_PHYSICAL_ADDRESS Address
;
602 OPAL_DRIVER_DEVICE
*TmpDev
;
604 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
606 mOpalEndOfDxe
= TRUE
;
608 if (mOpalRequestVariable
!= NULL
) {
610 // Free the OPAL request variable buffer here
611 // as the OPAL requests should have been processed.
613 FreePool (mOpalRequestVariable
);
614 mOpalRequestVariable
= NULL
;
615 mOpalRequestVariableSize
= 0;
619 // If no any device, return directly.
621 if (mOpalDriver
.DeviceList
== NULL
) {
622 gBS
->CloseEvent (Event
);
627 // Assume 64K size and alignment are enough.
630 Address
= 0xFFFFFFFF;
631 Status
= gDS
->AllocateMemorySpace (
632 EfiGcdAllocateMaxAddressSearchBottomUp
,
633 EfiGcdMemoryTypeMemoryMappedIo
,
634 16, // 2^16: 64K Alignment
640 ASSERT_EFI_ERROR (Status
);
642 BuildOpalDeviceInfoAta ((UINT32
) Address
);
643 BuildOpalDeviceInfoNvme ((UINT32
) Address
);
648 TmpDev
= mOpalDriver
.DeviceList
;
649 while (TmpDev
!= NULL
) {
650 ZeroMem (TmpDev
->OpalDisk
.Password
, TmpDev
->OpalDisk
.PasswordLength
);
651 TmpDev
= TmpDev
->Next
;
654 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
656 gBS
->CloseEvent (Event
);
660 Get Psid input from the popup window.
662 @param[in] Dev The device which need Psid to process Psid Revert
664 @param[in] PopUpString Pop up string.
665 @param[in] PopUpString2 Pop up string in line 2.
667 @param[out] PressEsc Whether user escape function through Press ESC.
669 @retval Psid string if success. NULL if failed.
673 OpalDriverPopUpPsidInput (
674 IN OPAL_DRIVER_DEVICE
*Dev
,
675 IN CHAR16
*PopUpString
,
676 IN CHAR16
*PopUpString2
,
677 OUT BOOLEAN
*PressEsc
680 EFI_INPUT_KEY InputKey
;
682 CHAR16 Mask
[PSID_CHARACTER_LENGTH
+ 1];
683 CHAR16 Unicode
[PSID_CHARACTER_LENGTH
+ 1];
686 ZeroMem(Unicode
, sizeof(Unicode
));
687 ZeroMem(Mask
, sizeof(Mask
));
691 gST
->ConOut
->ClearScreen(gST
->ConOut
);
695 Mask
[InputLength
] = L
'_';
696 if (PopUpString2
== NULL
) {
698 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
701 L
"---------------------",
707 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
711 L
"---------------------",
720 if (InputKey
.ScanCode
== SCAN_NULL
) {
724 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
726 // Add the null terminator.
728 Unicode
[InputLength
] = 0;
729 Mask
[InputLength
] = 0;
731 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
732 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
733 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
738 // delete last key entered
740 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
741 if (InputLength
> 0) {
742 Unicode
[InputLength
] = 0;
743 Mask
[InputLength
] = 0;
748 // add Next key entry
750 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
751 Mask
[InputLength
] = InputKey
.UnicodeChar
;
753 if (InputLength
== PSID_CHARACTER_LENGTH
) {
755 // Add the null terminator.
757 Unicode
[InputLength
] = 0;
758 Mask
[InputLength
] = 0;
768 if (InputKey
.ScanCode
== SCAN_ESC
) {
774 gST
->ConOut
->ClearScreen(gST
->ConOut
);
776 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
777 ZeroMem (Unicode
, sizeof (Unicode
));
778 ZeroMem (Mask
, sizeof (Mask
));
782 Ascii
= AllocateZeroPool (PSID_CHARACTER_LENGTH
+ 1);
784 ZeroMem (Unicode
, sizeof (Unicode
));
785 ZeroMem (Mask
, sizeof (Mask
));
789 UnicodeStrToAsciiStrS (Unicode
, Ascii
, PSID_CHARACTER_LENGTH
+ 1);
790 ZeroMem (Unicode
, sizeof (Unicode
));
791 ZeroMem (Mask
, sizeof (Mask
));
798 Get password input from the popup window.
800 @param[in] Dev The device which need password to unlock or
801 process OPAL request.
802 @param[in] PopUpString1 Pop up string 1.
803 @param[in] PopUpString2 Pop up string 2.
804 @param[out] PressEsc Whether user escape function through Press ESC.
806 @retval Password string if success. NULL if failed.
810 OpalDriverPopUpPasswordInput (
811 IN OPAL_DRIVER_DEVICE
*Dev
,
812 IN CHAR16
*PopUpString1
,
813 IN CHAR16
*PopUpString2
,
814 OUT BOOLEAN
*PressEsc
817 EFI_INPUT_KEY InputKey
;
819 CHAR16 Mask
[OPAL_MAX_PASSWORD_SIZE
+ 1];
820 CHAR16 Unicode
[OPAL_MAX_PASSWORD_SIZE
+ 1];
823 ZeroMem(Unicode
, sizeof(Unicode
));
824 ZeroMem(Mask
, sizeof(Mask
));
828 gST
->ConOut
->ClearScreen(gST
->ConOut
);
832 Mask
[InputLength
] = L
'_';
833 if (PopUpString2
== NULL
) {
835 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
838 L
"---------------------",
844 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
848 L
"---------------------",
857 if (InputKey
.ScanCode
== SCAN_NULL
) {
861 if (InputKey
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
863 // Add the null terminator.
865 Unicode
[InputLength
] = 0;
866 Mask
[InputLength
] = 0;
868 } else if ((InputKey
.UnicodeChar
== CHAR_NULL
) ||
869 (InputKey
.UnicodeChar
== CHAR_TAB
) ||
870 (InputKey
.UnicodeChar
== CHAR_LINEFEED
)
875 // delete last key entered
877 if (InputKey
.UnicodeChar
== CHAR_BACKSPACE
) {
878 if (InputLength
> 0) {
879 Unicode
[InputLength
] = 0;
880 Mask
[InputLength
] = 0;
885 // add Next key entry
887 Unicode
[InputLength
] = InputKey
.UnicodeChar
;
888 Mask
[InputLength
] = L
'*';
890 if (InputLength
== OPAL_MAX_PASSWORD_SIZE
) {
892 // Add the null terminator.
894 Unicode
[InputLength
] = 0;
895 Mask
[InputLength
] = 0;
905 if (InputKey
.ScanCode
== SCAN_ESC
) {
911 gST
->ConOut
->ClearScreen(gST
->ConOut
);
913 if (InputLength
== 0 || InputKey
.ScanCode
== SCAN_ESC
) {
914 ZeroMem (Unicode
, sizeof (Unicode
));
918 Ascii
= AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE
+ 1);
920 ZeroMem (Unicode
, sizeof (Unicode
));
924 UnicodeStrToAsciiStrS (Unicode
, Ascii
, OPAL_MAX_PASSWORD_SIZE
+ 1);
925 ZeroMem (Unicode
, sizeof (Unicode
));
933 @param[in] Dev The OPAL device.
934 @param[in] RequestString Request string.
936 @return Pop up string.
941 IN OPAL_DRIVER_DEVICE
*Dev
,
942 IN CHAR16
*RequestString
945 if (Dev
->Name16
== NULL
) {
946 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s Disk", RequestString
);
948 UnicodeSPrint (mPopUpString
, sizeof (mPopUpString
), L
"%s %s", RequestString
, Dev
->Name16
);
955 Check if disk is locked, show popup window and ask for password if it is.
957 @param[in] Dev The device which need to be unlocked.
958 @param[in] RequestString Request string.
962 OpalDriverRequestPassword (
963 IN OPAL_DRIVER_DEVICE
*Dev
,
964 IN CHAR16
*RequestString
972 OPAL_SESSION Session
;
982 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
984 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
988 IsEnabled
= OpalFeatureEnabled (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
990 ZeroMem(&Session
, sizeof(Session
));
991 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
992 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
993 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
995 IsLocked
= OpalDeviceLocked (&Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.LockingFeature
);
997 if (IsLocked
&& PcdGetBool (PcdSkipOpalDxeUnlock
)) {
1001 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1002 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1006 // Current device in the lock status and
1007 // User not input password and press ESC,
1008 // keep device in lock status and continue boot.
1012 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1014 L
"Press ENTER to skip the request and continue boot,",
1015 L
"Press ESC to input password again",
1018 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1020 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1021 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1023 // Keep lock and continue boot.
1028 // Let user input password again.
1034 // Current device in the unlock status and
1035 // User not input password and press ESC,
1036 // Shutdown the device.
1040 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1042 L
"Press ENTER to shutdown, Press ESC to input password again",
1045 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1047 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1048 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1051 // Let user input password again.
1058 if (Password
== NULL
) {
1062 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1065 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1067 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, TRUE
, TRUE
);
1068 if (Ret
== TcgResultSuccess
) {
1069 Ret
= OpalUtilUpdateGlobalLockingRange(&Session
, Password
, PasswordLen
, FALSE
, FALSE
);
1073 if (Ret
== TcgResultSuccess
) {
1074 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1075 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1077 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1080 if (Password
!= NULL
) {
1081 ZeroMem (Password
, PasswordLen
);
1082 FreePool (Password
);
1085 if (Ret
== TcgResultSuccess
) {
1090 // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
1091 // before accept new password.
1093 if (Ret
== TcgResultFailureInvalidType
) {
1094 Count
= MAX_PASSWORD_TRY_COUNT
;
1102 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1104 L
"Invalid password.",
1105 L
"Press ENTER to retry",
1108 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1111 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1114 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1116 L
"Opal password retry count exceeds the limit. Must shutdown!",
1117 L
"Press ENTER to shutdown",
1120 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1122 gRT
->ResetSystem (EfiResetShutdown
, EFI_SUCCESS
, 0, NULL
);
1128 Process Enable Feature OPAL request.
1130 @param[in] Dev The device which has Enable Feature OPAL request.
1131 @param[in] RequestString Request string.
1135 ProcessOpalRequestEnableFeature (
1136 IN OPAL_DRIVER_DEVICE
*Dev
,
1137 IN CHAR16
*RequestString
1143 CHAR8
*PasswordConfirm
;
1144 UINT32 PasswordLenConfirm
;
1145 OPAL_SESSION Session
;
1149 CHAR16
*PopUpString
;
1155 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1157 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1161 ZeroMem(&Session
, sizeof(Session
));
1162 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1163 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1164 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1166 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1167 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1171 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1173 L
"Press ENTER to skip the request and continue boot,",
1174 L
"Press ESC to input password again",
1177 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1179 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1180 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1184 // Let user input password again.
1190 if (Password
== NULL
) {
1194 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1196 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1197 if (PasswordConfirm
== NULL
) {
1198 ZeroMem (Password
, PasswordLen
);
1199 FreePool (Password
);
1203 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1204 if ((PasswordLen
!= PasswordLenConfirm
) ||
1205 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1206 ZeroMem (Password
, PasswordLen
);
1207 FreePool (Password
);
1208 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1209 FreePool (PasswordConfirm
);
1212 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1214 L
"Passwords are not the same.",
1215 L
"Press ENTER to retry",
1218 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1223 if (PasswordConfirm
!= NULL
) {
1224 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1225 FreePool (PasswordConfirm
);
1228 Ret
= OpalSupportEnableOpalFeature (&Session
, Dev
->OpalDisk
.Msid
, Dev
->OpalDisk
.MsidLength
, Password
, PasswordLen
);
1229 if (Ret
== TcgResultSuccess
) {
1230 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1231 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1233 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1236 if (Password
!= NULL
) {
1237 ZeroMem (Password
, PasswordLen
);
1238 FreePool (Password
);
1241 if (Ret
== TcgResultSuccess
) {
1249 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1252 L
"Press ENTER to retry",
1255 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1258 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1261 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1263 L
"Opal password retry count exceeds the limit.",
1264 L
"Press ENTER to skip the request and continue boot",
1267 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1268 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1273 Process Disable User OPAL request.
1275 @param[in] Dev The device which has Disable User OPAL request.
1276 @param[in] RequestString Request string.
1280 ProcessOpalRequestDisableUser (
1281 IN OPAL_DRIVER_DEVICE
*Dev
,
1282 IN CHAR16
*RequestString
1288 OPAL_SESSION Session
;
1292 BOOLEAN PasswordFailed
;
1293 CHAR16
*PopUpString
;
1299 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1301 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1305 ZeroMem(&Session
, sizeof(Session
));
1306 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1307 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1308 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1310 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1311 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1315 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1317 L
"Press ENTER to skip the request and continue boot,",
1318 L
"Press ESC to input password again",
1321 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1323 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1324 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1328 // Let user input password again.
1334 if (Password
== NULL
) {
1338 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1340 Ret
= OpalUtilDisableUser(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1341 if (Ret
== TcgResultSuccess
) {
1342 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1343 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1345 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1348 if (Password
!= NULL
) {
1349 ZeroMem (Password
, PasswordLen
);
1350 FreePool (Password
);
1353 if (Ret
== TcgResultSuccess
) {
1361 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1363 L
"Invalid password, request failed.",
1364 L
"Press ENTER to retry",
1367 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1370 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1373 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1375 L
"Opal password retry count exceeds the limit.",
1376 L
"Press ENTER to skip the request and continue boot",
1379 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1380 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1385 Process Psid Revert OPAL request.
1387 @param[in] Dev The device which has Psid Revert OPAL request.
1388 @param[in] RequestString Request string.
1392 ProcessOpalRequestPsidRevert (
1393 IN OPAL_DRIVER_DEVICE
*Dev
,
1394 IN CHAR16
*RequestString
1400 OPAL_SESSION Session
;
1404 CHAR16
*PopUpString
;
1405 CHAR16
*PopUpString2
;
1412 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1414 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1416 if (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
) {
1417 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1418 PopUpString2
= AllocateZeroPool (BufferSize
);
1419 ASSERT (PopUpString2
!= NULL
);
1423 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1424 Dev
->OpalDisk
.EstimateTimeCost
1427 PopUpString2
= NULL
;
1432 ZeroMem(&Session
, sizeof(Session
));
1433 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1434 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1435 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1437 while (Count
< MAX_PSID_TRY_COUNT
) {
1438 Psid
= OpalDriverPopUpPsidInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1442 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1444 L
"Press ENTER to skip the request and continue boot,",
1445 L
"Press ESC to input Psid again",
1448 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1450 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1451 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1455 // Let user input Psid again.
1465 PsidLen
= (UINT32
) AsciiStrLen(Psid
);
1467 Ret
= OpalUtilPsidRevert(&Session
, Psid
, PsidLen
);
1468 if (Ret
== TcgResultSuccess
) {
1469 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1471 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1475 ZeroMem (Psid
, PsidLen
);
1479 if (Ret
== TcgResultSuccess
) {
1487 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1489 L
"Invalid Psid, request failed.",
1490 L
"Press ENTER to retry",
1493 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1496 if (Count
>= MAX_PSID_TRY_COUNT
) {
1499 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1501 L
"Opal Psid retry count exceeds the limit.",
1502 L
"Press ENTER to skip the request and continue boot",
1505 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1506 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1510 if (PopUpString2
!= NULL
) {
1511 FreePool (PopUpString2
);
1516 Process Admin Revert OPAL request.
1518 @param[in] Dev The device which has Revert OPAL request.
1519 @param[in] KeepUserData Whether to keep user data or not.
1520 @param[in] RequestString Request string.
1524 ProcessOpalRequestRevert (
1525 IN OPAL_DRIVER_DEVICE
*Dev
,
1526 IN BOOLEAN KeepUserData
,
1527 IN CHAR16
*RequestString
1533 OPAL_SESSION Session
;
1537 BOOLEAN PasswordFailed
;
1538 CHAR16
*PopUpString
;
1539 CHAR16
*PopUpString2
;
1546 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1548 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1550 if ((!KeepUserData
) &&
1551 (Dev
->OpalDisk
.EstimateTimeCost
> MAX_ACCEPTABLE_REVERTING_TIME
)) {
1552 BufferSize
= StrSize (L
"Warning: Revert action will take about ####### seconds, DO NOT power off system during the revert action!");
1553 PopUpString2
= AllocateZeroPool (BufferSize
);
1554 ASSERT (PopUpString2
!= NULL
);
1558 L
"WARNING: Revert action will take about %d seconds, DO NOT power off system during the revert action!",
1559 Dev
->OpalDisk
.EstimateTimeCost
1562 PopUpString2
= NULL
;
1567 ZeroMem(&Session
, sizeof(Session
));
1568 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1569 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1570 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1572 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1573 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, PopUpString2
, &PressEsc
);
1577 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1579 L
"Press ENTER to skip the request and continue boot,",
1580 L
"Press ESC to input password again",
1583 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1585 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1586 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1590 // Let user input password again.
1596 if (Password
== NULL
) {
1600 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1602 if ((Dev
->OpalDisk
.SupportedAttributes
.PyriteSsc
== 1) &&
1603 (Dev
->OpalDisk
.LockingFeature
.MediaEncryption
== 0)) {
1605 // For pyrite type device which does not support media encryption,
1606 // it does not accept "Keep User Data" parameter.
1607 // So here hardcode a FALSE for this case.
1609 Ret
= OpalUtilRevert(
1616 Dev
->OpalDisk
.MsidLength
1619 Ret
= OpalUtilRevert(
1626 Dev
->OpalDisk
.MsidLength
1629 if (Ret
== TcgResultSuccess
) {
1630 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1631 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1633 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1636 if (Password
!= NULL
) {
1637 ZeroMem (Password
, PasswordLen
);
1638 FreePool (Password
);
1641 if (Ret
== TcgResultSuccess
) {
1649 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1651 L
"Invalid password, request failed.",
1652 L
"Press ENTER to retry",
1655 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1658 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1661 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1663 L
"Opal password retry count exceeds the limit.",
1664 L
"Press ENTER to skip the request and continue boot",
1667 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1668 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1672 if (PopUpString2
!= NULL
) {
1673 FreePool (PopUpString2
);
1678 Process Secure Erase OPAL request.
1680 @param[in] Dev The device which has Secure Erase OPAL request.
1681 @param[in] RequestString Request string.
1685 ProcessOpalRequestSecureErase (
1686 IN OPAL_DRIVER_DEVICE
*Dev
,
1687 IN CHAR16
*RequestString
1693 OPAL_SESSION Session
;
1697 BOOLEAN PasswordFailed
;
1698 CHAR16
*PopUpString
;
1704 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1706 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1710 ZeroMem(&Session
, sizeof(Session
));
1711 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1712 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1713 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1715 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1716 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, NULL
, &PressEsc
);
1720 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1722 L
"Press ENTER to skip the request and continue boot,",
1723 L
"Press ESC to input password again",
1726 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1728 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1729 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1733 // Let user input password again.
1739 if (Password
== NULL
) {
1743 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1745 Ret
= OpalUtilSecureErase(&Session
, Password
, PasswordLen
, &PasswordFailed
);
1746 if (Ret
== TcgResultSuccess
) {
1747 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1748 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1750 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1753 if (Password
!= NULL
) {
1754 ZeroMem (Password
, PasswordLen
);
1755 FreePool (Password
);
1758 if (Ret
== TcgResultSuccess
) {
1766 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1768 L
"Invalid password, request failed.",
1769 L
"Press ENTER to retry",
1772 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1775 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1778 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1780 L
"Opal password retry count exceeds the limit.",
1781 L
"Press ENTER to skip the request and continue boot",
1784 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1785 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1790 Process Set Admin Pwd OPAL request.
1792 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1793 @param[in] RequestString Request string.
1797 ProcessOpalRequestSetUserPwd (
1798 IN OPAL_DRIVER_DEVICE
*Dev
,
1799 IN CHAR16
*RequestString
1804 UINT32 OldPasswordLen
;
1807 CHAR8
*PasswordConfirm
;
1808 UINT32 PasswordLenConfirm
;
1809 OPAL_SESSION Session
;
1813 CHAR16
*PopUpString
;
1819 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
1821 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
1825 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
1826 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
1830 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1832 L
"Press ENTER to skip the request and continue boot,",
1833 L
"Press ESC to input password again",
1836 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1838 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
1839 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1843 // Let user input password again.
1849 if (OldPassword
== NULL
) {
1853 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
1855 ZeroMem(&Session
, sizeof(Session
));
1856 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1857 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1858 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1859 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
1860 if (Ret
== TcgResultSuccess
) {
1861 DEBUG ((DEBUG_INFO
, "Verify with USER1 authority : Success\n"));
1863 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
1864 if (Ret
== TcgResultSuccess
) {
1865 DEBUG ((DEBUG_INFO
, "Verify with ADMIN1 authority: Success\n"));
1867 ZeroMem (OldPassword
, OldPasswordLen
);
1868 FreePool (OldPassword
);
1869 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
1872 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1874 L
"Incorrect password.",
1875 L
"Press ENTER to retry",
1878 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1884 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
1885 if (Password
== NULL
) {
1886 ZeroMem (OldPassword
, OldPasswordLen
);
1887 FreePool (OldPassword
);
1891 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
1893 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
1894 if (PasswordConfirm
== NULL
) {
1895 ZeroMem (OldPassword
, OldPasswordLen
);
1896 FreePool (OldPassword
);
1897 ZeroMem (Password
, PasswordLen
);
1898 FreePool (Password
);
1902 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
1903 if ((PasswordLen
!= PasswordLenConfirm
) ||
1904 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
1905 ZeroMem (OldPassword
, OldPasswordLen
);
1906 FreePool (OldPassword
);
1907 ZeroMem (Password
, PasswordLen
);
1908 FreePool (Password
);
1909 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1910 FreePool (PasswordConfirm
);
1913 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1915 L
"Passwords are not the same.",
1916 L
"Press ENTER to retry",
1919 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1924 if (PasswordConfirm
!= NULL
) {
1925 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
1926 FreePool (PasswordConfirm
);
1929 ZeroMem(&Session
, sizeof(Session
));
1930 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
1931 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
1932 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1933 Ret
= OpalUtilSetUserPassword(
1940 if (Ret
== TcgResultSuccess
) {
1941 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
1942 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
1944 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
1947 if (OldPassword
!= NULL
) {
1948 ZeroMem (OldPassword
, OldPasswordLen
);
1949 FreePool (OldPassword
);
1952 if (Password
!= NULL
) {
1953 ZeroMem (Password
, PasswordLen
);
1954 FreePool (Password
);
1957 if (Ret
== TcgResultSuccess
) {
1965 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1968 L
"Press ENTER to retry",
1971 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1974 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
1977 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1979 L
"Opal password retry count exceeds the limit.",
1980 L
"Press ENTER to skip the request and continue boot",
1983 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1984 gST
->ConOut
->ClearScreen(gST
->ConOut
);
1989 Process Set Admin Pwd OPAL request.
1991 @param[in] Dev The device which has Set Admin Pwd Feature OPAL request.
1992 @param[in] RequestString Request string.
1996 ProcessOpalRequestSetAdminPwd (
1997 IN OPAL_DRIVER_DEVICE
*Dev
,
1998 IN CHAR16
*RequestString
2003 UINT32 OldPasswordLen
;
2006 CHAR8
*PasswordConfirm
;
2007 UINT32 PasswordLenConfirm
;
2008 OPAL_SESSION Session
;
2012 CHAR16
*PopUpString
;
2018 DEBUG ((DEBUG_INFO
, "%a()\n", __FUNCTION__
));
2020 PopUpString
= OpalGetPopUpString (Dev
, RequestString
);
2024 while (Count
< MAX_PASSWORD_TRY_COUNT
) {
2025 OldPassword
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your password", &PressEsc
);
2029 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2031 L
"Press ENTER to skip the request and continue boot,",
2032 L
"Press ESC to input password again",
2035 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
2037 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
2038 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2042 // Let user input password again.
2048 if (OldPassword
== NULL
) {
2052 OldPasswordLen
= (UINT32
) AsciiStrLen(OldPassword
);
2054 ZeroMem(&Session
, sizeof(Session
));
2055 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2056 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2057 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2058 Ret
= OpalUtilVerifyPassword (&Session
, OldPassword
, OldPasswordLen
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
2059 if (Ret
== TcgResultSuccess
) {
2060 DEBUG ((DEBUG_INFO
, "Verify: Success\n"));
2062 ZeroMem (OldPassword
, OldPasswordLen
);
2063 FreePool (OldPassword
);
2064 DEBUG ((DEBUG_INFO
, "Verify: Failure\n"));
2067 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2069 L
"Incorrect password.",
2070 L
"Press ENTER to retry",
2073 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2078 Password
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please type in your new password", &PressEsc
);
2079 if (Password
== NULL
) {
2080 ZeroMem (OldPassword
, OldPasswordLen
);
2081 FreePool (OldPassword
);
2085 PasswordLen
= (UINT32
) AsciiStrLen(Password
);
2087 PasswordConfirm
= OpalDriverPopUpPasswordInput (Dev
, PopUpString
, L
"Please confirm your new password", &PressEsc
);
2088 if (PasswordConfirm
== NULL
) {
2089 ZeroMem (OldPassword
, OldPasswordLen
);
2090 FreePool (OldPassword
);
2091 ZeroMem (Password
, PasswordLen
);
2092 FreePool (Password
);
2096 PasswordLenConfirm
= (UINT32
) AsciiStrLen(PasswordConfirm
);
2097 if ((PasswordLen
!= PasswordLenConfirm
) ||
2098 (CompareMem (Password
, PasswordConfirm
, PasswordLen
) != 0)) {
2099 ZeroMem (OldPassword
, OldPasswordLen
);
2100 FreePool (OldPassword
);
2101 ZeroMem (Password
, PasswordLen
);
2102 FreePool (Password
);
2103 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2104 FreePool (PasswordConfirm
);
2107 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2109 L
"Passwords are not the same.",
2110 L
"Press ENTER to retry",
2113 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2118 if (PasswordConfirm
!= NULL
) {
2119 ZeroMem (PasswordConfirm
, PasswordLenConfirm
);
2120 FreePool (PasswordConfirm
);
2124 ZeroMem(&Session
, sizeof(Session
));
2125 Session
.Sscp
= Dev
->OpalDisk
.Sscp
;
2126 Session
.MediaId
= Dev
->OpalDisk
.MediaId
;
2127 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
2128 Ret
= OpalUtilSetAdminPassword(
2135 if (Ret
== TcgResultSuccess
) {
2136 OpalSupportUpdatePassword (&Dev
->OpalDisk
, Password
, PasswordLen
);
2137 DEBUG ((DEBUG_INFO
, "%s Success\n", RequestString
));
2139 DEBUG ((DEBUG_INFO
, "%s Failure\n", RequestString
));
2142 if (OldPassword
!= NULL
) {
2143 ZeroMem (OldPassword
, OldPasswordLen
);
2144 FreePool (OldPassword
);
2147 if (Password
!= NULL
) {
2148 ZeroMem (Password
, PasswordLen
);
2149 FreePool (Password
);
2152 if (Ret
== TcgResultSuccess
) {
2160 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2163 L
"Press ENTER to retry",
2166 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2169 if (Count
>= MAX_PASSWORD_TRY_COUNT
) {
2172 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
2174 L
"Opal password retry count exceeds the limit.",
2175 L
"Press ENTER to skip the request and continue boot",
2178 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
2179 gST
->ConOut
->ClearScreen(gST
->ConOut
);
2184 Process OPAL request.
2186 @param[in] Dev The device which has OPAL request.
2190 ProcessOpalRequest (
2191 IN OPAL_DRIVER_DEVICE
*Dev
2195 OPAL_REQUEST_VARIABLE
*TempVariable
;
2196 OPAL_REQUEST_VARIABLE
*Variable
;
2198 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInVariable
;
2199 UINTN DevicePathSizeInVariable
;
2200 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
2201 UINTN DevicePathSize
;
2202 BOOLEAN KeepUserData
;
2204 DEBUG ((DEBUG_INFO
, "%a() - enter\n", __FUNCTION__
));
2206 if (mOpalRequestVariable
== NULL
) {
2207 Status
= GetVariable2 (
2208 OPAL_REQUEST_VARIABLE_NAME
,
2209 &gHiiSetupVariableGuid
,
2210 (VOID
**) &Variable
,
2213 if (EFI_ERROR (Status
) || (Variable
== NULL
)) {
2216 mOpalRequestVariable
= Variable
;
2217 mOpalRequestVariableSize
= VariableSize
;
2220 // Delete the OPAL request variable.
2222 Status
= gRT
->SetVariable (
2223 OPAL_REQUEST_VARIABLE_NAME
,
2224 (EFI_GUID
*) &gHiiSetupVariableGuid
,
2229 ASSERT_EFI_ERROR (Status
);
2231 Variable
= mOpalRequestVariable
;
2232 VariableSize
= mOpalRequestVariableSize
;
2236 // Process the OPAL requests.
2238 TempVariable
= Variable
;
2239 while ((VariableSize
> sizeof (OPAL_REQUEST_VARIABLE
)) &&
2240 (VariableSize
>= TempVariable
->Length
) &&
2241 (TempVariable
->Length
> sizeof (OPAL_REQUEST_VARIABLE
))) {
2242 DevicePathInVariable
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) TempVariable
+ sizeof (OPAL_REQUEST_VARIABLE
));
2243 DevicePathSizeInVariable
= GetDevicePathSize (DevicePathInVariable
);
2244 DevicePath
= Dev
->OpalDisk
.OpalDevicePath
;
2245 DevicePathSize
= GetDevicePathSize (DevicePath
);
2246 if ((DevicePathSize
== DevicePathSizeInVariable
) &&
2247 (CompareMem (DevicePath
, DevicePathInVariable
, DevicePathSize
) == 0)) {
2249 // Found the node for the OPAL device.
2251 if (TempVariable
->OpalRequest
.SetAdminPwd
!= 0) {
2252 ProcessOpalRequestSetAdminPwd (Dev
, L
"Update Admin Pwd:");
2254 if (TempVariable
->OpalRequest
.SetUserPwd
!= 0) {
2255 ProcessOpalRequestSetUserPwd (Dev
, L
"Set User Pwd:");
2257 if (TempVariable
->OpalRequest
.SecureErase
!= 0) {
2258 ProcessOpalRequestSecureErase (Dev
, L
"Secure Erase:");
2260 if (TempVariable
->OpalRequest
.Revert
!= 0) {
2261 KeepUserData
= (BOOLEAN
) TempVariable
->OpalRequest
.KeepUserData
;
2262 ProcessOpalRequestRevert (
2265 KeepUserData
? L
"Admin Revert(keep):" : L
"Admin Revert:"
2268 if (TempVariable
->OpalRequest
.PsidRevert
!= 0) {
2269 ProcessOpalRequestPsidRevert (Dev
, L
"Psid Revert:");
2271 if (TempVariable
->OpalRequest
.DisableUser
!= 0) {
2272 ProcessOpalRequestDisableUser (Dev
, L
"Disable User:");
2274 if (TempVariable
->OpalRequest
.EnableFeature
!= 0) {
2275 ProcessOpalRequestEnableFeature (Dev
, L
"Enable Feature:");
2281 VariableSize
-= TempVariable
->Length
;
2282 TempVariable
= (OPAL_REQUEST_VARIABLE
*) ((UINTN
) TempVariable
+ TempVariable
->Length
);
2285 DEBUG ((DEBUG_INFO
, "%a() - exit\n", __FUNCTION__
));
2289 Add new device to the global device list.
2291 @param Dev New create device.
2296 IN OPAL_DRIVER_DEVICE
*Dev
2299 OPAL_DRIVER_DEVICE
*TmpDev
;
2301 if (mOpalDriver
.DeviceList
== NULL
) {
2302 mOpalDriver
.DeviceList
= Dev
;
2304 TmpDev
= mOpalDriver
.DeviceList
;
2305 while (TmpDev
->Next
!= NULL
) {
2306 TmpDev
= TmpDev
->Next
;
2314 Remove one device in the global device list.
2316 @param Dev The device need to be removed.
2321 IN OPAL_DRIVER_DEVICE
*Dev
2324 OPAL_DRIVER_DEVICE
*TmpDev
;
2326 if (mOpalDriver
.DeviceList
== NULL
) {
2330 if (mOpalDriver
.DeviceList
== Dev
) {
2331 mOpalDriver
.DeviceList
= NULL
;
2335 TmpDev
= mOpalDriver
.DeviceList
;
2336 while (TmpDev
->Next
!= NULL
) {
2337 if (TmpDev
->Next
== Dev
) {
2338 TmpDev
->Next
= Dev
->Next
;
2345 Get current device count.
2347 @retval return the current created device count.
2356 OPAL_DRIVER_DEVICE
*TmpDev
;
2359 TmpDev
= mOpalDriver
.DeviceList
;
2361 while (TmpDev
!= NULL
) {
2363 TmpDev
= TmpDev
->Next
;
2370 Get devcie list info.
2372 @retval return the device list pointer.
2375 OpalDriverGetDeviceList(
2379 return mOpalDriver
.DeviceList
;
2383 ReadyToBoot callback to send BlockSid command.
2385 @param Event Pointer to this event
2386 @param Context Event handler private Data
2391 ReadyToBootCallback (
2396 OPAL_DRIVER_DEVICE
*Itr
;
2398 OPAL_SESSION Session
;
2399 UINT32 PpStorageFlag
;
2401 gBS
->CloseEvent (Event
);
2403 PpStorageFlag
= Tcg2PhysicalPresenceLibGetManagementFlags ();
2404 if ((PpStorageFlag
& TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID
) != 0) {
2406 // Send BlockSID command to each Opal disk
2408 Itr
= mOpalDriver
.DeviceList
;
2409 while (Itr
!= NULL
) {
2410 if (Itr
->OpalDisk
.SupportedAttributes
.BlockSid
) {
2411 ZeroMem(&Session
, sizeof(Session
));
2412 Session
.Sscp
= Itr
->OpalDisk
.Sscp
;
2413 Session
.MediaId
= Itr
->OpalDisk
.MediaId
;
2414 Session
.OpalBaseComId
= Itr
->OpalDisk
.OpalBaseComId
;
2416 DEBUG ((DEBUG_INFO
, "OpalPassword: ReadyToBoot point, send BlockSid command to device!\n"));
2417 Result
= OpalBlockSid (&Session
, TRUE
); // HardwareReset must always be TRUE
2418 if (Result
!= TcgResultSuccess
) {
2419 DEBUG ((DEBUG_ERROR
, "OpalBlockSid fail\n"));
2430 Stop this Controller.
2432 @param Dev The device need to be stopped.
2436 OpalDriverStopDevice (
2437 OPAL_DRIVER_DEVICE
*Dev
2443 FreePool(Dev
->Name16
);
2446 // remove OPAL_DRIVER_DEVICE from the list
2447 // it updates the controllerList pointer
2452 // close protocols that were opened
2456 &gEfiStorageSecurityCommandProtocolGuid
,
2457 gOpalDriverBinding
.DriverBindingHandle
,
2463 &gEfiBlockIoProtocolGuid
,
2464 gOpalDriverBinding
.DriverBindingHandle
,
2472 Get devcie name through the component name protocol.
2474 @param[in] AllHandlesBuffer The handle buffer for current system.
2475 @param[in] NumAllHandles The number of handles for the handle buffer.
2476 @param[in] Dev The device which need to get name.
2477 @param[in] UseComp1 Whether use component name or name2 protocol.
2479 @retval TRUE Find the name for this device.
2480 @retval FALSE Not found the name for this device.
2483 OpalDriverGetDeviceNameByProtocol(
2484 EFI_HANDLE
*AllHandlesBuffer
,
2485 UINTN NumAllHandles
,
2486 OPAL_DRIVER_DEVICE
*Dev
,
2490 EFI_HANDLE
* ProtocolHandlesBuffer
;
2491 UINTN NumProtocolHandles
;
2493 EFI_COMPONENT_NAME2_PROTOCOL
* Cnp1_2
; // efi component name and componentName2 have same layout
2496 EFI_DEVICE_PATH_PROTOCOL
* TmpDevPath
;
2499 EFI_HANDLE TmpHandle
;
2502 if (Dev
== NULL
|| AllHandlesBuffer
== NULL
|| NumAllHandles
== 0) {
2506 Protocol
= UseComp1
? gEfiComponentNameProtocolGuid
: gEfiComponentName2ProtocolGuid
;
2509 // Find all EFI_HANDLES with protocol
2511 Status
= gBS
->LocateHandleBuffer(
2515 &NumProtocolHandles
,
2516 &ProtocolHandlesBuffer
2518 if (EFI_ERROR(Status
)) {
2524 // Exit early if no supported devices
2526 if (NumProtocolHandles
== 0) {
2531 // Get printable name by iterating through all protocols
2532 // using the handle as the child, and iterate through all handles for the controller
2533 // exit loop early once found, if not found, then delete device
2534 // storage security protocol instances already exist, add them to internal list
2536 Status
= EFI_DEVICE_ERROR
;
2537 for (Index1
= 0; Index1
< NumProtocolHandles
; Index1
++) {
2540 if (Dev
->Name16
!= NULL
) {
2544 TmpHandle
= ProtocolHandlesBuffer
[Index1
];
2546 Status
= gBS
->OpenProtocol(
2552 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2554 if (EFI_ERROR(Status
) || Cnp1_2
== NULL
) {
2559 // Use all handles array as controller handle
2561 for (Index2
= 0; Index2
< NumAllHandles
; Index2
++) {
2562 Status
= Cnp1_2
->GetControllerName(
2564 AllHandlesBuffer
[Index2
],
2566 LANGUAGE_ISO_639_2_ENGLISH
,
2569 if (EFI_ERROR(Status
)) {
2570 Status
= Cnp1_2
->GetControllerName(
2572 AllHandlesBuffer
[Index2
],
2574 LANGUAGE_RFC_3066_ENGLISH
,
2578 if (!EFI_ERROR(Status
) && DevName
!= NULL
) {
2579 StrLength
= StrLen(DevName
) + 1; // Add one for NULL terminator
2580 Dev
->Name16
= AllocateZeroPool(StrLength
* sizeof (CHAR16
));
2581 ASSERT (Dev
->Name16
!= NULL
);
2582 StrCpyS (Dev
->Name16
, StrLength
, DevName
);
2583 Dev
->NameZ
= (CHAR8
*)AllocateZeroPool(StrLength
);
2584 UnicodeStrToAsciiStrS (DevName
, Dev
->NameZ
, StrLength
);
2587 // Retrieve bridge BDF info and port number or namespace depending on type
2590 Status
= gBS
->OpenProtocol(
2592 &gEfiDevicePathProtocolGuid
,
2593 (VOID
**)&TmpDevPath
,
2596 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2598 if (!EFI_ERROR(Status
)) {
2599 Dev
->OpalDevicePath
= DuplicateDevicePath (TmpDevPath
);
2603 if (Dev
->Name16
!= NULL
) {
2604 FreePool(Dev
->Name16
);
2607 if (Dev
->NameZ
!= NULL
) {
2608 FreePool(Dev
->NameZ
);
2619 Get devcie name through the component name protocol.
2621 @param[in] Dev The device which need to get name.
2623 @retval TRUE Find the name for this device.
2624 @retval FALSE Not found the name for this device.
2627 OpalDriverGetDriverDeviceName(
2628 OPAL_DRIVER_DEVICE
*Dev
2631 EFI_HANDLE
* AllHandlesBuffer
;
2632 UINTN NumAllHandles
;
2636 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
2641 // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
2643 if (Dev
->Name16
== NULL
) {
2644 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "Name is null, update it\n"));
2646 // Find all EFI_HANDLES
2648 Status
= gBS
->LocateHandleBuffer(
2655 if (EFI_ERROR(Status
)) {
2656 DEBUG ((DEBUG_INFO
, "LocateHandleBuffer for AllHandles failed %r\n", Status
));
2661 // Try component Name2
2663 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, FALSE
)) {
2664 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName2 failed to get device name, try ComponentName\n"));
2665 if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer
, NumAllHandles
, Dev
, TRUE
)) {
2666 DEBUG((DEBUG_ERROR
| DEBUG_INIT
, "ComponentName failed to get device name, skip device\n"));
2676 Main entry for this driver.
2678 @param ImageHandle Image Handle this driver.
2679 @param SystemTable Pointer to SystemTable.
2681 @retval EFI_SUCESS This function always complete successfully.
2685 EfiDriverEntryPoint(
2686 IN EFI_HANDLE ImageHandle
,
2687 IN EFI_SYSTEM_TABLE
* SystemTable
2691 EFI_EVENT ReadyToBootEvent
;
2692 EFI_EVENT EndOfDxeEvent
;
2694 Status
= EfiLibInstallDriverBindingComponentName2 (
2697 &gOpalDriverBinding
,
2699 &gOpalComponentName
,
2700 &gOpalComponentName2
2703 if (EFI_ERROR(Status
)) {
2704 DEBUG((DEBUG_ERROR
, "Install protocols to Opal driver Handle failed\n"));
2709 // Initialize Driver object
2711 ZeroMem(&mOpalDriver
, sizeof(mOpalDriver
));
2712 mOpalDriver
.Handle
= ImageHandle
;
2714 Status
= gBS
->CreateEventEx (
2717 OpalEndOfDxeEventNotify
,
2719 &gEfiEndOfDxeEventGroupGuid
,
2722 ASSERT_EFI_ERROR (Status
);
2725 // register a ReadyToBoot event callback for sending BlockSid command
2727 Status
= EfiCreateEventReadyToBootEx (
2729 ReadyToBootCallback
,
2730 (VOID
*) &ImageHandle
,
2735 // Install Hii packages.
2743 Tests to see if this driver supports a given controller.
2745 This function checks to see if the controller contains an instance of the
2746 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL
2747 and returns EFI_SUCCESS if it does.
2749 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2750 @param[in] ControllerHandle The Handle of the controller to test. This Handle
2751 must support a protocol interface that supplies
2752 an I/O abstraction to the driver.
2753 @param[in] RemainingDevicePath This parameter is ignored.
2755 @retval EFI_SUCCESS The device contains required protocols
2756 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
2757 RemainingDevicePath is already being managed by the driver
2759 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
2760 RemainingDevicePath is already being managed by a different
2761 driver or an application that requires exclusive access.
2762 Currently not implemented.
2763 @retval EFI_UNSUPPORTED The device does not contain requires protocols
2768 OpalEfiDriverBindingSupported(
2769 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2770 IN EFI_HANDLE Controller
,
2771 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2775 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
* SecurityCommand
;
2776 EFI_BLOCK_IO_PROTOCOL
* BlkIo
;
2778 if (mOpalEndOfDxe
) {
2779 return EFI_UNSUPPORTED
;
2783 // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
2785 Status
= gBS
->OpenProtocol(
2787 &gEfiStorageSecurityCommandProtocolGuid
,
2788 ( VOID
** )&SecurityCommand
,
2789 This
->DriverBindingHandle
,
2791 EFI_OPEN_PROTOCOL_BY_DRIVER
2794 if (Status
== EFI_ALREADY_STARTED
) {
2798 if (EFI_ERROR(Status
)) {
2803 // Close protocol and reopen in Start call
2807 &gEfiStorageSecurityCommandProtocolGuid
,
2808 This
->DriverBindingHandle
,
2813 // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2816 Status
= gBS
->OpenProtocol(
2818 &gEfiBlockIoProtocolGuid
,
2820 This
->DriverBindingHandle
,
2822 EFI_OPEN_PROTOCOL_BY_DRIVER
2825 if (EFI_ERROR(Status
)) {
2826 DEBUG((DEBUG_INFO
, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));
2831 // Close protocol and reopen in Start call
2835 &gEfiBlockIoProtocolGuid
,
2836 This
->DriverBindingHandle
,
2844 Enables Opal Management on a supported device if available.
2846 The start function is designed to be called after the Opal UEFI Driver has confirmed the
2847 "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
2848 This function will complete the other necessary checks, such as verifying the device supports
2849 the correct version of Opal. Upon verification, it will add the device to the
2850 Opal HII list in order to expose Opal managmeent options.
2852 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
2853 @param[in] ControllerHandle The Handle of the controller to start. This Handle
2854 must support a protocol interface that supplies
2855 an I/O abstraction to the driver.
2856 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
2857 parameter is ignored by device drivers, and is optional for bus
2858 drivers. For a bus driver, if this parameter is NULL, then handles
2859 for all the children of Controller are created by this driver.
2860 If this parameter is not NULL and the first Device Path Node is
2861 not the End of Device Path Node, then only the Handle for the
2862 child device specified by the first Device Path Node of
2863 RemainingDevicePath is created by this driver.
2864 If the first Device Path Node of RemainingDevicePath is
2865 the End of Device Path Node, no child Handle is created by this
2868 @retval EFI_SUCCESS Opal management was enabled.
2869 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
2870 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
2871 @retval Others The driver failed to start the device.
2876 OpalEfiDriverBindingStart(
2877 IN EFI_DRIVER_BINDING_PROTOCOL
* This
,
2878 IN EFI_HANDLE Controller
,
2879 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath
2883 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
2884 OPAL_DRIVER_DEVICE
*Dev
;
2885 OPAL_DRIVER_DEVICE
*Itr
;
2888 Itr
= mOpalDriver
.DeviceList
;
2889 while (Itr
!= NULL
) {
2890 if (Controller
== Itr
->Handle
) {
2897 // Create internal device for tracking. This allows all disks to be tracked
2900 Dev
= (OPAL_DRIVER_DEVICE
*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE
));
2902 return EFI_OUT_OF_RESOURCES
;
2904 Dev
->Handle
= Controller
;
2907 // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
2909 Status
= gBS
->OpenProtocol(
2911 &gEfiStorageSecurityCommandProtocolGuid
,
2912 (VOID
**)&Dev
->Sscp
,
2913 This
->DriverBindingHandle
,
2915 EFI_OPEN_PROTOCOL_BY_DRIVER
2917 if (EFI_ERROR(Status
)) {
2923 // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
2926 Status
= gBS
->OpenProtocol(
2928 &gEfiBlockIoProtocolGuid
,
2930 This
->DriverBindingHandle
,
2932 EFI_OPEN_PROTOCOL_BY_DRIVER
2934 if (EFI_ERROR(Status
)) {
2936 // Close storage security that was opened
2940 &gEfiStorageSecurityCommandProtocolGuid
,
2941 This
->DriverBindingHandle
,
2952 Dev
->MediaId
= BlkIo
->Media
->MediaId
;
2956 &gEfiBlockIoProtocolGuid
,
2957 This
->DriverBindingHandle
,
2962 // Acquire Ascii printable name of child, if not found, then ignore device
2964 Result
= OpalDriverGetDriverDeviceName (Dev
);
2969 Status
= OpalDiskInitialize (Dev
);
2970 if (EFI_ERROR (Status
)) {
2974 AddDeviceToTail(Dev
);
2977 // Check if device is locked and prompt for password.
2979 OpalDriverRequestPassword (Dev
, L
"Unlock:");
2982 // Process OPAL request from last boot.
2984 ProcessOpalRequest (Dev
);
2990 // free device, close protocols and exit
2994 &gEfiStorageSecurityCommandProtocolGuid
,
2995 This
->DriverBindingHandle
,
3001 return EFI_DEVICE_ERROR
;
3005 Stop this driver on Controller.
3007 @param This Protocol instance pointer.
3008 @param Controller Handle of device to stop driver on
3009 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
3010 children is zero stop the entire bus driver.
3011 @param ChildHandleBuffer List of Child Handles to Stop.
3013 @retval EFI_SUCCESS This driver is removed Controller.
3014 @retval other This driver could not be removed from this device.
3019 OpalEfiDriverBindingStop(
3020 EFI_DRIVER_BINDING_PROTOCOL
* This
,
3021 EFI_HANDLE Controller
,
3022 UINTN NumberOfChildren
,
3023 EFI_HANDLE
* ChildHandleBuffer
3026 OPAL_DRIVER_DEVICE
* Itr
;
3028 Itr
= mOpalDriver
.DeviceList
;
3031 // does Controller match any of the devices we are managing for Opal
3033 while (Itr
!= NULL
) {
3034 if (Itr
->Handle
== Controller
) {
3035 OpalDriverStopDevice (Itr
);
3042 return EFI_NOT_FOUND
;
3047 Unloads UEFI Driver. Very useful for debugging and testing.
3049 @param ImageHandle Image Handle this driver.
3051 @retval EFI_SUCCESS This function always complete successfully.
3052 @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
3056 OpalEfiDriverUnload (
3057 IN EFI_HANDLE ImageHandle
3061 OPAL_DRIVER_DEVICE
*Itr
;
3063 Status
= EFI_SUCCESS
;
3065 if (ImageHandle
!= gImageHandle
) {
3066 return (EFI_INVALID_PARAMETER
);
3070 // Uninstall any interface added to each device by us
3072 while (mOpalDriver
.DeviceList
) {
3073 Itr
= mOpalDriver
.DeviceList
;
3075 // Remove OPAL_DRIVER_DEVICE from the list
3076 // it updates the controllerList pointer
3078 OpalDriverStopDevice(Itr
);
3082 // Uninstall the HII capability
3084 Status
= HiiUninstall();