2 Implementation of the HII for the Opal UEFI Driver.
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "OpalDriver.h"
17 #include "OpalHiiPrivate.h"
20 // This is the generated IFR binary Data for each formset defined in VFR.
21 // This Data array is ready to be used as input of HiiAddPackages() to
22 // create a packagelist (which contains Form packages, String packages, etc).
24 extern UINT8 OpalPasswordFormBin
[];
27 // This is the generated String package Data for all .UNI files.
28 // This Data array is ready to be used as input of HiiAddPackages() to
29 // create a packagelist (which contains Form packages, String packages, etc).
31 extern UINT8 OpalPasswordDxeStrings
[];
33 CHAR16 OpalPasswordStorageName
[] = L
"OpalHiiConfig";
35 EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol
;
38 // Handle to the list of HII packages (forms and strings) for this driver
40 EFI_HII_HANDLE gHiiPackageListHandle
= NULL
;
43 // Package List GUID containing all form and string packages
45 const EFI_GUID gHiiPackageListGuid
= PACKAGE_LIST_GUID
;
46 const EFI_GUID gHiiSetupVariableGuid
= SETUP_VARIABLE_GUID
;
49 // Structure that contains state of the HII
50 // This structure is updated by Hii.cpp and its contents
51 // is rendered in the HII.
53 OPAL_HII_CONFIGURATION gHiiConfiguration
;
55 CHAR8 gHiiOldPassword
[MAX_PASSWORD_CHARACTER_LENGTH
] = {0};
56 UINT32 gHiiOldPasswordLength
= 0;
59 // The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
61 HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath
= {
67 (UINT8
)(sizeof(VENDOR_DEVICE_PATH
)),
68 (UINT8
)((sizeof(VENDOR_DEVICE_PATH
)) >> 8)
71 OPAL_PASSWORD_CONFIG_GUID
75 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
77 (UINT8
)(END_DEVICE_PATH_LENGTH
),
78 (UINT8
)((END_DEVICE_PATH_LENGTH
) >> 8)
85 Sets the current system state of global config variables.
89 HiiSetCurrentConfiguration(
94 OPAL_EXTRA_INFO_VAR OpalExtraInfo
;
97 gHiiConfiguration
.NumDisks
= GetDeviceCount();
99 DataSize
= sizeof (OPAL_EXTRA_INFO_VAR
);
100 Status
= gRT
->GetVariable (
101 OPAL_EXTRA_INFO_VAR_NAME
,
102 &gOpalExtraInfoVariableGuid
,
107 if (!EFI_ERROR (Status
)) {
108 gHiiConfiguration
.EnableBlockSid
= OpalExtraInfo
.EnableBlockSid
;
113 Install the HII related resources.
115 @retval EFI_SUCCESS Install all the resources success.
116 @retval other Error occur when install the resources.
124 EFI_HANDLE DriverHandle
;
127 // Clear the global configuration.
129 ZeroMem(&gHiiConfiguration
, sizeof(gHiiConfiguration
));
132 // Obtain the driver handle that the BIOS assigned us
134 DriverHandle
= HiiGetDriverImageHandleCB();
137 // Populate the config access protocol with the three functions we are publishing
139 gHiiConfigAccessProtocol
.ExtractConfig
= ExtractConfig
;
140 gHiiConfigAccessProtocol
.RouteConfig
= RouteConfig
;
141 gHiiConfigAccessProtocol
.Callback
= DriverCallback
;
144 // Associate the required protocols with our driver handle
146 Status
= gBS
->InstallMultipleProtocolInterfaces(
148 &gEfiHiiConfigAccessProtocolGuid
,
149 &gHiiConfigAccessProtocol
, // HII callback
150 &gEfiDevicePathProtocolGuid
,
151 &gHiiVendorDevicePath
, // required for HII callback allow all disks to be shown in same hii
155 if (EFI_ERROR(Status
)) {
159 return OpalHiiAddPackages();
163 Install the HII form and string packages.
165 @retval EFI_SUCCESS Install all the resources success.
166 @retval EFI_OUT_OF_RESOURCES Out of resource error.
173 EFI_HANDLE DriverHandle
;
176 DriverHandle
= HiiGetDriverImageHandleCB();
179 // Publish the HII form and HII string packages
181 gHiiPackageListHandle
= HiiAddPackages(
182 &gHiiPackageListGuid
,
184 OpalPasswordDxeStrings
,
190 // Make sure the packages installed successfully
192 if (gHiiPackageListHandle
== NULL
) {
193 DEBUG ((DEBUG_INFO
, "OpalHiiAddPackages failed\n"));
194 return EFI_OUT_OF_RESOURCES
;
198 // Update Version String in main window
200 NewString
= HiiGetDriverNameCB ();
201 if (HiiSetString(gHiiPackageListHandle
, STRING_TOKEN(STR_MAIN_OPAL_VERSION
), NewString
, NULL
) == 0) {
202 DEBUG ((DEBUG_INFO
, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
203 return EFI_OUT_OF_RESOURCES
;
210 Uninstall the HII capability.
212 @retval EFI_SUCCESS Uninstall all the resources success.
213 @retval others Other errors occur when unistall the hii resource.
223 // Remove the packages we've provided to the BIOS
225 HiiRemovePackages(gHiiPackageListHandle
);
228 // Remove the protocols from our driver handle
230 Status
= gBS
->UninstallMultipleProtocolInterfaces(
231 HiiGetDriverImageHandleCB(),
232 &gEfiHiiConfigAccessProtocolGuid
,
233 &gHiiConfigAccessProtocol
, // HII callback
234 &gEfiDevicePathProtocolGuid
,
235 &gHiiVendorDevicePath
, // required for HII callback
238 if (EFI_ERROR(Status
)) {
239 DEBUG ((DEBUG_INFO
, "Cannot uninstall Hii Protocols: %r\n", Status
));
246 Updates the main menu form.
248 @retval EFI_SUCCESS update the main form success.
251 HiiPopulateMainMenuForm (
257 EFI_STRING_ID DiskNameId
;
260 HiiSetCurrentConfiguration();
262 gHiiConfiguration
.SupportedDisks
= 0;
264 for (Index
= 0; Index
< gHiiConfiguration
.NumDisks
; Index
++) {
265 OpalDisk
= HiiGetOpalDiskCB (Index
);
266 if ((OpalDisk
!= NULL
) && OpalFeatureSupported (&OpalDisk
->SupportedAttributes
)) {
267 gHiiConfiguration
.SupportedDisks
|= (1 << Index
);
268 DiskNameId
= GetDiskNameStringId (Index
);
269 DiskName
= HiiDiskGetNameCB (Index
);
270 if ((DiskName
== NULL
) || (DiskNameId
== 0)) {
271 return EFI_UNSUPPORTED
;
273 HiiSetFormString(DiskNameId
, DiskName
);
277 OpalHiiSetBrowserData ();
282 Update the disk action info.
285 @param SelectedAction
287 @retval EFI_SUCCESS Uninstall all the resources success.
290 HiiSelectDiskAction (
296 OPAL_DISK_ACTIONS AvailActions
;
298 OpalHiiGetBrowserData ();
300 HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL
), ActionString
);
301 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), " ");
303 gHiiConfiguration
.SelectedAction
= SelectedAction
;
304 gHiiConfiguration
.AvailableFields
= 0;
306 OpalDisk
= HiiGetOpalDiskCB(gHiiConfiguration
.SelectedDiskIndex
);
307 if (OpalDisk
== NULL
) {
308 return EFI_INVALID_PARAMETER
;
311 if (OpalSupportGetAvailableActions (&OpalDisk
->SupportedAttributes
, &OpalDisk
->LockingFeature
, OpalDisk
->Owner
, &AvailActions
) != TcgResultSuccess
) {
312 return EFI_DEVICE_ERROR
;
315 switch (SelectedAction
) {
316 case HII_KEY_ID_GOTO_LOCK
:
317 case HII_KEY_ID_GOTO_UNLOCK
:
318 case HII_KEY_ID_GOTO_SET_ADMIN_PWD
:
319 case HII_KEY_ID_GOTO_SET_USER_PWD
:
320 case HII_KEY_ID_GOTO_SECURE_ERASE
:
321 case HII_KEY_ID_GOTO_DISABLE_USER
:
322 case HII_KEY_ID_GOTO_ENABLE_FEATURE
: // User is required to enter Password to enable Feature
323 gHiiConfiguration
.AvailableFields
|= HII_FIELD_PASSWORD
;
326 case HII_KEY_ID_GOTO_PSID_REVERT
:
327 gHiiConfiguration
.AvailableFields
|= HII_FIELD_PSID
;
330 case HII_KEY_ID_GOTO_REVERT
:
331 gHiiConfiguration
.AvailableFields
|= HII_FIELD_PASSWORD
;
332 gHiiConfiguration
.AvailableFields
|= HII_FIELD_KEEP_USER_DATA
;
333 if (AvailActions
.RevertKeepDataForced
) {
334 gHiiConfiguration
.AvailableFields
|= HII_FIELD_KEEP_USER_DATA_FORCED
;
339 OpalHiiSetBrowserData ();
345 Get disk name string id.
347 @param DiskIndex The input disk index info.
349 @retval The disk name string id.
358 case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0
);
359 case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1
);
360 case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2
);
361 case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3
);
362 case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4
);
363 case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5
);
369 This function processes the results of changes in configuration.
371 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
372 @param Action Specifies the type of action taken by the browser.
373 @param QuestionId A unique value which is sent to the original
374 exporting driver so that it can identify the type
376 @param Type The type of value for the question.
377 @param Value A pointer to the data being sent to the original
379 @param ActionRequest On return, points to the action requested by the
382 @retval EFI_SUCCESS The callback successfully handled the action.
383 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
384 variable and its data.
385 @retval EFI_DEVICE_ERROR The variable could not be saved.
386 @retval EFI_UNSUPPORTED The specified Action is not supported by the
393 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
394 EFI_BROWSER_ACTION Action
,
395 EFI_QUESTION_ID QuestionId
,
397 EFI_IFR_TYPE_VALUE
*Value
,
398 EFI_BROWSER_ACTION_REQUEST
*ActionRequest
404 if (ActionRequest
!= NULL
) {
405 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
407 return EFI_INVALID_PARAMETER
;
411 // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
413 if ((QuestionId
& HII_KEY_FLAG
) == 0) {
417 HiiKey
.Raw
= QuestionId
;
418 HiiKeyId
= (UINT8
) HiiKey
.KeyBits
.Id
;
420 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
422 case HII_KEY_ID_VAR_SUPPORTED_DISKS
:
423 DEBUG ((DEBUG_INFO
, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
424 return HiiPopulateMainMenuForm ();
426 case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS
:
427 return HiiPopulateDiskInfoForm();
429 } else if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
431 case HII_KEY_ID_GOTO_DISK_INFO
:
432 return HiiSelectDisk((UINT8
)HiiKey
.KeyBits
.Index
);
434 case HII_KEY_ID_GOTO_LOCK
:
435 return HiiSelectDiskAction("Action: Lock", HiiKeyId
);
437 case HII_KEY_ID_GOTO_UNLOCK
:
438 return HiiSelectDiskAction("Action: Unlock", HiiKeyId
);
440 case HII_KEY_ID_GOTO_SET_ADMIN_PWD
:
441 return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId
);
443 case HII_KEY_ID_GOTO_SET_USER_PWD
:
444 return HiiSelectDiskAction("Action: Set User Password", HiiKeyId
);
446 case HII_KEY_ID_GOTO_SECURE_ERASE
:
447 return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId
);
449 case HII_KEY_ID_GOTO_PSID_REVERT
:
450 return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId
);
452 case HII_KEY_ID_GOTO_REVERT
:
453 return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId
);
455 case HII_KEY_ID_GOTO_DISABLE_USER
:
456 return HiiSelectDiskAction("Action: Disable User", HiiKeyId
);
458 case HII_KEY_ID_GOTO_ENABLE_FEATURE
:
459 return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId
);
461 case HII_KEY_ID_ENTER_PASSWORD
:
462 return HiiPasswordEntered(Value
->string
);
464 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
466 case HII_KEY_ID_ENTER_PSID
:
468 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
471 case HII_KEY_ID_BLOCKSID
:
472 HiiSetBlockSid(Value
->b
);
473 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
;
478 return EFI_UNSUPPORTED
;
482 Update the global Disk index info.
484 @param Index The input disk index info.
486 @retval EFI_SUCCESS Update the disk index info success.
494 OpalHiiGetBrowserData();
495 gHiiConfiguration
.SelectedDiskIndex
= Index
;
496 OpalHiiSetBrowserData ();
502 Draws the disk info form.
504 @retval EFI_SUCCESS Draw the disk info success.
508 HiiPopulateDiskInfoForm(
513 OPAL_DISK_ACTIONS AvailActions
;
517 OpalHiiGetBrowserData();
519 DiskName
= HiiDiskGetNameCB (gHiiConfiguration
.SelectedDiskIndex
);
520 if (DiskName
== NULL
) {
521 return EFI_UNSUPPORTED
;
523 HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME
), DiskName
);
525 ZeroMem(gHiiConfiguration
.Psid
, sizeof(gHiiConfiguration
.Psid
));
527 gHiiConfiguration
.SelectedDiskAvailableActions
= HII_ACTION_NONE
;
529 OpalDisk
= HiiGetOpalDiskCB(gHiiConfiguration
.SelectedDiskIndex
);
531 if (OpalDisk
!= NULL
) {
532 OpalDiskUpdateStatus (OpalDisk
);
533 Ret
= OpalSupportGetAvailableActions(&OpalDisk
->SupportedAttributes
, &OpalDisk
->LockingFeature
, OpalDisk
->Owner
, &AvailActions
);
534 if (Ret
== TcgResultSuccess
) {
536 // Update actions, always allow PSID Revert
538 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.PsidRevert
== 1) ? HII_ACTION_PSID_REVERT
: HII_ACTION_NONE
;
541 // Always allow unlock to handle device migration
543 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.Unlock
== 1) ? HII_ACTION_UNLOCK
: HII_ACTION_NONE
;
545 if (!OpalFeatureEnabled (&OpalDisk
->SupportedAttributes
, &OpalDisk
->LockingFeature
)) {
546 if (OpalDisk
->Owner
== OpalOwnershipNobody
) {
547 gHiiConfiguration
.SelectedDiskAvailableActions
|= HII_ACTION_ENABLE_FEATURE
;
552 HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT
), "PSID Revert to factory default");
554 DEBUG ((DEBUG_INFO
, "Feature disabled but ownership != nobody\n"));
557 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.Revert
== 1) ? HII_ACTION_REVERT
: HII_ACTION_NONE
;
558 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.AdminPass
== 1) ? HII_ACTION_SET_ADMIN_PWD
: HII_ACTION_NONE
;
559 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.UserPass
== 1) ? HII_ACTION_SET_USER_PWD
: HII_ACTION_NONE
;
560 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.SecureErase
== 1) ? HII_ACTION_SECURE_ERASE
: HII_ACTION_NONE
;
561 gHiiConfiguration
.SelectedDiskAvailableActions
|= (AvailActions
.DisableUser
== 1) ? HII_ACTION_DISABLE_USER
: HII_ACTION_NONE
;
563 HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT
), "PSID Revert to factory default and Disable");
566 // Determine revert options for disk
567 // Default initialize keep user Data to be true
569 gHiiConfiguration
.KeepUserData
= 1;
575 // Pass the current configuration to the BIOS
577 OpalHiiSetBrowserData ();
583 Reverts the Opal disk to factory default.
585 @retval EFI_SUCCESS Do the required action success.
593 CHAR8 Response
[DEFAULT_RESPONSE_SIZE
];
597 OPAL_SESSION Session
;
598 UINT8 TmpBuf
[PSID_CHARACTER_STRING_END_LENGTH
];
600 Ret
= TcgResultFailure
;
602 OpalHiiGetBrowserData();
604 ZeroMem (TmpBuf
, sizeof (TmpBuf
));
605 UnicodeStrToAsciiStrS (gHiiConfiguration
.Psid
, (CHAR8
*)TmpBuf
, PSID_CHARACTER_STRING_END_LENGTH
);
606 CopyMem (Psid
.Psid
, TmpBuf
, PSID_CHARACTER_LENGTH
);
608 OpalDisk
= HiiGetOpalDiskCB (gHiiConfiguration
.SelectedDiskIndex
);
609 if (OpalDisk
!= NULL
) {
610 ZeroMem(&Session
, sizeof(Session
));
611 Session
.Sscp
= OpalDisk
->Sscp
;
612 Session
.MediaId
= OpalDisk
->MediaId
;
613 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
615 Ret
= OpalSupportPsidRevert(&Session
, Psid
.Psid
, (UINT32
)sizeof(Psid
.Psid
), OpalDisk
->OpalDevicePath
);
618 if (Ret
== TcgResultSuccess
) {
619 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "PSID Revert: Success" );
621 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "PSID Revert: Failure" );
624 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
630 Set password for the disk.
632 @param OpalDisk The disk need to set the password.
633 @param Password The input password.
634 @param PassLength The input password length.
636 @retval EFI_SUCCESS Do the required action success.
646 CHAR8 Response
[DEFAULT_RESPONSE_SIZE
];
648 BOOLEAN ExistingPassword
;
649 OPAL_SESSION Session
;
651 ExistingPassword
= FALSE
;
654 // PassLength = 0 means check whether exist old password.
656 if (PassLength
== 0) {
657 ZeroMem(gHiiOldPassword
, sizeof(gHiiOldPassword
));
658 gHiiOldPasswordLength
= 0;
660 if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_ENABLE_FEATURE
) {
661 ExistingPassword
= FALSE
;
662 } else if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_SET_ADMIN_PWD
) {
663 ExistingPassword
= OpalUtilAdminPasswordExists(OpalDisk
->Owner
, &OpalDisk
->LockingFeature
);
664 } else if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_SET_USER_PWD
) {
666 // Set user Password option shall only be shown if an Admin Password exists
667 // so a Password is always required (Admin or Existing User Password)
669 ExistingPassword
= TRUE
;
673 // Return error if there is a previous Password
674 // see UEFI 2.4 errata B, Figure 121. Password Flowchart
676 return ExistingPassword
? EFI_DEVICE_ERROR
: EFI_SUCCESS
;
679 ZeroMem(&Session
, sizeof(Session
));
680 Session
.Sscp
= OpalDisk
->Sscp
;
681 Session
.MediaId
= OpalDisk
->MediaId
;
682 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
684 AsciiSPrint(Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Set Password: Failure");
687 // No current Owner, so set new Password, must be admin Password
689 if (OpalDisk
->Owner
== OpalOwnershipNobody
) {
690 Ret
= OpalSupportEnableOpalFeature (&Session
, OpalDisk
->Msid
, OpalDisk
->MsidLength
,Password
, PassLength
, OpalDisk
->OpalDevicePath
);
691 if (Ret
== TcgResultSuccess
) {
692 AsciiSPrint(Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Set Password: Success");
695 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
700 // 1st Password entered
702 if (OpalDisk
->Owner
== OpalOwnershipUnknown
&& gHiiOldPasswordLength
== 0) {
705 // Unknown ownership - prompt for old Password, then new
706 // old Password is not set yet - first time through
707 // assume authority provided is admin1, overwritten if user1 authority works below
709 if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_SET_USER_PWD
) {
711 // First try to login as USER1 to Locking SP to see if we're simply updating its Password
713 Ret
= OpalUtilVerifyPassword (&Session
, Password
, PassLength
, OPAL_LOCKING_SP_USER1_AUTHORITY
);
714 if (Ret
== TcgResultSuccess
) {
716 // User1 worked so authority 1 means user 1
718 CopyMem(gHiiOldPassword
, Password
, PassLength
);
719 gHiiOldPasswordLength
= PassLength
;
726 // Else try admin1 below
728 Ret
= OpalUtilVerifyPassword (&Session
, Password
, PassLength
, OPAL_LOCKING_SP_ADMIN1_AUTHORITY
);
729 if (Ret
== TcgResultSuccess
) {
730 CopyMem(gHiiOldPassword
, Password
, PassLength
);
731 gHiiOldPasswordLength
= PassLength
;
735 DEBUG ((DEBUG_INFO
, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));
736 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), "Authentication Failure");
738 ZeroMem(gHiiOldPassword
, sizeof(gHiiOldPassword
));
739 gHiiOldPasswordLength
= 0;
741 return EFI_NOT_READY
;
746 // New Password entered
748 if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_SET_USER_PWD
) {
749 Ret
= OpalSupportSetPassword(
752 gHiiOldPasswordLength
,
755 OpalDisk
->OpalDevicePath
,
759 Ret
= OpalSupportSetPassword(
762 gHiiOldPasswordLength
,
765 OpalDisk
->OpalDevicePath
,
770 if (Ret
== TcgResultSuccess
) {
771 AsciiSPrint(Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Set Password: Success");
775 // Reset old Password storage
777 ZeroMem(gHiiOldPassword
, sizeof(gHiiOldPassword
));
778 gHiiOldPasswordLength
= 0;
780 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
781 return Ret
== TcgResultSuccess
? EFI_SUCCESS
: EFI_NOT_READY
;
785 Secure Erases Opal Disk.
787 @param OpalDisk The disk need to erase data.
788 @param Password The input password.
789 @param PassLength The input password length.
791 @retval EFI_SUCCESS Do the required action success.
797 const VOID
*Password
,
801 CHAR8 Response
[DEFAULT_RESPONSE_SIZE
];
802 BOOLEAN PasswordFailed
;
804 OPAL_SESSION AdminSpSession
;
806 if (PassLength
== 0) {
807 return EFI_DEVICE_ERROR
; // return error to indicate there is an existing Password
810 ZeroMem(&AdminSpSession
, sizeof(AdminSpSession
));
811 AdminSpSession
.Sscp
= OpalDisk
->Sscp
;
812 AdminSpSession
.MediaId
= OpalDisk
->MediaId
;
813 AdminSpSession
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
815 Ret
= OpalUtilSecureErase(&AdminSpSession
, Password
, PassLength
, &PasswordFailed
);
816 if (Ret
== TcgResultSuccess
) {
817 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Secure Erase: Success" );
819 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Secure Erase: Failure" );
821 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
824 // If Password failed, return invalid passowrd
826 if (PasswordFailed
) {
827 DEBUG ((DEBUG_INFO
, "returning EFI_NOT_READY to indicate Password was not correct\n"));
828 return EFI_NOT_READY
;
832 // Indicates Password was valid and is not changing to UEFI
833 // Response string will indicate action error
835 return EFI_DEVICE_ERROR
;
840 Disables User for Opal Disk.
842 @param OpalDisk The disk need to the action.
843 @param Password The input password.
844 @param PassLength The input password length.
846 @retval EFI_SUCCESS Do the required action success.
856 CHAR8 Response
[ DEFAULT_RESPONSE_SIZE
];
857 BOOLEAN PasswordFailed
;
859 OPAL_SESSION Session
;
861 if (PassLength
== 0) {
862 return EFI_DEVICE_ERROR
; // return error to indicate there is an existing Password
865 ZeroMem(&Session
, sizeof(Session
));
866 Session
.Sscp
= OpalDisk
->Sscp
;
867 Session
.MediaId
= OpalDisk
->MediaId
;
868 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
870 Ret
= OpalSupportDisableUser(&Session
, Password
, PassLength
, &PasswordFailed
, OpalDisk
->OpalDevicePath
);
871 if (Ret
== TcgResultSuccess
) {
872 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Disable User: Success" );
874 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Disable User: Failure" );
876 HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS
), Response
);
879 // If Password failed, return invalid passowrd
881 if (PasswordFailed
) {
882 DEBUG ((DEBUG_INFO
, "returning EFI_NOT_READY to indicate Password was not correct\n"));
883 return EFI_NOT_READY
;
887 // Indicates Password was valid and is not changing to UEFI
888 // Response string will indicate action error
890 return EFI_DEVICE_ERROR
;
894 Revert Opal Disk as Admin1.
896 @param OpalDisk The disk need to the action.
897 @param Password The input password.
898 @param PassLength The input password length.
899 @param KeepUserData Whether need to keey user data.
901 @retval EFI_SUCCESS Do the required action success.
912 CHAR8 Response
[ DEFAULT_RESPONSE_SIZE
];
913 BOOLEAN PasswordFailed
;
915 OPAL_SESSION Session
;
917 if (PassLength
== 0) {
918 DEBUG ((DEBUG_INFO
, "Returning error to indicate there is an existing Password\n"));
919 // return error to indicate there is an existing Password
920 return EFI_DEVICE_ERROR
;
923 ZeroMem(&Session
, sizeof(Session
));
924 Session
.Sscp
= OpalDisk
->Sscp
;
925 Session
.MediaId
= OpalDisk
->MediaId
;
926 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
928 Ret
= OpalSupportRevert(
934 OpalDisk
->MsidLength
,
936 OpalDisk
->OpalDevicePath
938 if (Ret
== TcgResultSuccess
) {
939 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Revert: Success" );
941 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Revert: Failure" );
943 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
946 // If Password failed, return invalid passowrd
948 if (PasswordFailed
) {
949 DEBUG ((DEBUG_INFO
, "returning EFI_NOT_READY to indicate Password was not correct\n"));
950 return EFI_NOT_READY
;
954 // Indicates Password was valid and is not changing to UEFI
955 // Response string will indicate action error
957 return EFI_DEVICE_ERROR
;
963 @param OpalDisk The disk need to the action.
964 @param Password The input password.
965 @param PassLength The input password length.
967 @retval EFI_SUCCESS Do the required action success.
977 CHAR8 Response
[DEFAULT_RESPONSE_SIZE
];
979 OPAL_SESSION Session
;
981 if (PassLength
== 0) {
982 DEBUG ((DEBUG_INFO
, "Returning error to indicate there is an existing Password\n"));
983 return EFI_DEVICE_ERROR
; // return error to indicate there is an existing Password
986 ZeroMem(&Session
, sizeof(Session
));
987 Session
.Sscp
= OpalDisk
->Sscp
;
988 Session
.MediaId
= OpalDisk
->MediaId
;
989 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
991 Ret
= OpalSupportUnlock(&Session
, Password
, PassLength
, OpalDisk
->OpalDevicePath
);
992 if (Ret
== TcgResultSuccess
) {
993 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Unlock: Success" );
995 AsciiSPrint( Response
, DEFAULT_RESPONSE_SIZE
, "%a", "Unlock: Failure" );
998 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), Response
);
1000 if (Ret
== TcgResultSuccess
) {
1001 DEBUG ((DEBUG_INFO
, "returning error to indicate Password was correct but is not changing\n"));
1002 return EFI_DEVICE_ERROR
;
1004 DEBUG ((DEBUG_INFO
, "returning EFI_NOT_READY to indicate Password was not correct\n"));
1005 return EFI_NOT_READY
;
1010 Use the input password to do the specified action.
1012 @param Str The input password saved in.
1014 @retval EFI_SUCCESS Do the required action success.
1015 @retval Others Other error occur.
1023 OPAL_DISK
* OpalDisk
;
1024 CHAR8 Password
[MAX_PASSWORD_CHARACTER_LENGTH
+ 1];
1029 OpalHiiGetBrowserData();
1031 OpalDisk
= HiiGetOpalDiskCB(gHiiConfiguration
.SelectedDiskIndex
);
1032 if (OpalDisk
== NULL
) {
1033 DEBUG ((DEBUG_INFO
, "ERROR: disk %u not found\n", gHiiConfiguration
.SelectedDiskIndex
));
1034 return EFI_NOT_FOUND
;
1038 DEBUG ((DEBUG_INFO
, "ERROR: str=NULL\n"));
1039 return EFI_INVALID_PARAMETER
;
1042 ZeroMem(Password
, sizeof(Password
));
1044 UniStr
= HiiGetString(gHiiPackageListHandle
, Str
, NULL
);
1045 if (UniStr
== NULL
) {
1046 return EFI_NOT_FOUND
;
1048 PassLength
= (UINT32
) StrLen (UniStr
);
1049 if (PassLength
>= sizeof(Password
)) {
1050 HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS
), "Password too long");
1051 gBS
->FreePool(UniStr
);
1052 return EFI_BUFFER_TOO_SMALL
;
1055 UnicodeStrToAsciiStrS (UniStr
, Password
, sizeof (Password
));
1056 gBS
->FreePool(UniStr
);
1058 if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_UNLOCK
) {
1059 Status
= HiiUnlock (OpalDisk
, Password
, PassLength
);
1060 } else if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_SECURE_ERASE
) {
1061 Status
= HiiSecureErase (OpalDisk
, Password
, PassLength
);
1062 } else if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_DISABLE_USER
) {
1063 Status
= HiiDisableUser (OpalDisk
, Password
, PassLength
);
1064 } else if (gHiiConfiguration
.SelectedAction
== HII_KEY_ID_GOTO_REVERT
) {
1065 if (OpalDisk
->SupportedAttributes
.PyriteSsc
== 1 && OpalDisk
->LockingFeature
.MediaEncryption
== 0) {
1067 // For pyrite type device which also not supports media encryption, it not accept "Keep User Data" parameter.
1068 // So here hardcode a FALSE for this case.
1070 Status
= HiiRevert(OpalDisk
, Password
, PassLength
, FALSE
);
1072 Status
= HiiRevert(OpalDisk
, Password
, PassLength
, gHiiConfiguration
.KeepUserData
);
1075 Status
= HiiSetPassword(OpalDisk
, Password
, PassLength
);
1078 OpalHiiSetBrowserData ();
1084 Update block sid info.
1086 @param Enable Enable/disable BlockSid.
1088 @retval EFI_SUCCESS Do the required action success.
1089 @retval Others Other error occur.
1098 OPAL_EXTRA_INFO_VAR OpalExtraInfo
;
1101 Status
= EFI_SUCCESS
;
1103 OpalExtraInfo
.EnableBlockSid
= Enable
;
1104 DataSize
= sizeof (OPAL_EXTRA_INFO_VAR
);
1105 Status
= gRT
->SetVariable (
1106 OPAL_EXTRA_INFO_VAR_NAME
,
1107 &gOpalExtraInfoVariableGuid
,
1108 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1117 This function processes the results of changes in configuration.
1119 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1120 @param Configuration A null-terminated Unicode string in <ConfigResp>
1122 @param Progress A pointer to a string filled in with the offset of
1123 the most recent '&' before the first failing
1124 name/value pair (or the beginning of the string if
1125 the failure is in the first name/value pair) or
1126 the terminating NULL if all was successful.
1128 @retval EFI_SUCCESS The Results is processed successfully.
1129 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1130 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1137 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1138 CONST EFI_STRING Configuration
,
1139 EFI_STRING
*Progress
1142 if (Configuration
== NULL
|| Progress
== NULL
) {
1143 return (EFI_INVALID_PARAMETER
);
1146 *Progress
= Configuration
;
1147 if (!HiiIsConfigHdrMatch (Configuration
, &gHiiSetupVariableGuid
, OpalPasswordStorageName
)) {
1148 return EFI_NOT_FOUND
;
1151 *Progress
= Configuration
+ StrLen (Configuration
);
1157 This function allows a caller to extract the current configuration for one
1158 or more named elements from the target driver.
1160 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1161 @param Request A null-terminated Unicode string in
1162 <ConfigRequest> format.
1163 @param Progress On return, points to a character in the Request
1164 string. Points to the string's null terminator if
1165 request was successful. Points to the most recent
1166 '&' before the first failing name/value pair (or
1167 the beginning of the string if the failure is in
1168 the first name/value pair) if the request was not
1170 @param Results A null-terminated Unicode string in
1171 <ConfigAltResp> format which has all values filled
1172 in for the names in the Request string. String to
1173 be allocated by the called function.
1175 @retval EFI_SUCCESS The Results is filled with the requested values.
1176 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
1177 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
1178 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1185 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1186 CONST EFI_STRING Request
,
1187 EFI_STRING
*Progress
,
1194 // Check for valid parameters
1196 if (Progress
== NULL
|| Results
== NULL
) {
1197 return (EFI_INVALID_PARAMETER
);
1200 *Progress
= Request
;
1201 if ((Request
!= NULL
) &&
1202 !HiiIsConfigHdrMatch (Request
, &gHiiSetupVariableGuid
, OpalPasswordStorageName
)) {
1203 return EFI_NOT_FOUND
;
1207 // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
1209 Status
= gHiiConfigRouting
->BlockToConfig(
1212 (UINT8
*)&gHiiConfiguration
,
1213 sizeof(OPAL_HII_CONFIGURATION
),
1224 Pass the current system state to the bios via the hii_G_Configuration.
1228 OpalHiiSetBrowserData (
1233 &gHiiSetupVariableGuid
,
1234 (CHAR16
*)L
"OpalHiiConfig",
1235 sizeof(gHiiConfiguration
),
1236 (UINT8
*)&gHiiConfiguration
,
1244 Populate the hii_g_Configuraton with the browser Data.
1248 OpalHiiGetBrowserData (
1253 &gHiiSetupVariableGuid
,
1254 (CHAR16
*)L
"OpalHiiConfig",
1255 sizeof(gHiiConfiguration
),
1256 (UINT8
*)&gHiiConfiguration
1261 Set a string Value in a form.
1263 @param DestStringId The stringid which need to update.
1264 @param SrcAsciiStr The string nned to update.
1266 @retval EFI_SUCCESS Do the required action success.
1267 @retval Others Other error occur.
1272 EFI_STRING_ID DestStringId
,
1281 // Determine the Length of the sting
1283 Len
= ( UINT32
)AsciiStrLen( SrcAsciiStr
);
1286 // Allocate space for the unicode string, including terminator
1288 UniSize
= (Len
+ 1) * sizeof(CHAR16
);
1289 UniStr
= (CHAR16
*)AllocateZeroPool(UniSize
);
1292 // Copy into unicode string, then copy into string id
1294 AsciiStrToUnicodeStrS ( SrcAsciiStr
, UniStr
, Len
+ 1);
1297 // Update the string in the form
1299 if (HiiSetString(gHiiPackageListHandle
, DestStringId
, UniStr
, NULL
) == 0) {
1300 DEBUG ((DEBUG_INFO
, "HiiSetFormString( ) failed\n"));
1302 return (EFI_OUT_OF_RESOURCES
);
1310 return (EFI_SUCCESS
);
1314 Initialize the Opal disk base on the hardware info get from device.
1316 @param Dev The Opal device.
1318 @retval EFI_SUCESS Initialize the device success.
1319 @retval EFI_DEVICE_ERROR Get info from device failed.
1323 OpalDiskInitialize (
1324 IN OPAL_DRIVER_DEVICE
*Dev
1327 TCG_RESULT TcgResult
;
1328 OPAL_SESSION Session
;
1330 ZeroMem(&Dev
->OpalDisk
, sizeof(OPAL_DISK
));
1331 Dev
->OpalDisk
.Sscp
= Dev
->Sscp
;
1332 Dev
->OpalDisk
.MediaId
= Dev
->MediaId
;
1333 Dev
->OpalDisk
.OpalDevicePath
= Dev
->OpalDevicePath
;
1335 ZeroMem(&Session
, sizeof(Session
));
1336 Session
.Sscp
= Dev
->Sscp
;
1337 Session
.MediaId
= Dev
->MediaId
;
1339 TcgResult
= OpalGetSupportedAttributesInfo (&Session
, &Dev
->OpalDisk
.SupportedAttributes
, &Dev
->OpalDisk
.OpalBaseComId
);
1340 if (TcgResult
!= TcgResultSuccess
) {
1341 return EFI_DEVICE_ERROR
;
1343 Session
.OpalBaseComId
= Dev
->OpalDisk
.OpalBaseComId
;
1345 TcgResult
= OpalUtilGetMsid (&Session
, Dev
->OpalDisk
.Msid
, OPAL_MSID_LENGHT
, &Dev
->OpalDisk
.MsidLength
);
1346 if (TcgResult
!= TcgResultSuccess
) {
1347 return EFI_DEVICE_ERROR
;
1350 return OpalDiskUpdateStatus (&Dev
->OpalDisk
);
1354 Update the device info.
1356 @param OpalDisk The Opal device.
1358 @retval EFI_SUCESS Initialize the device success.
1359 @retval EFI_DEVICE_ERROR Get info from device failed.
1360 @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
1364 OpalDiskUpdateStatus (
1368 TCG_RESULT TcgResult
;
1369 OPAL_SESSION Session
;
1371 ZeroMem(&Session
, sizeof(Session
));
1372 Session
.Sscp
= OpalDisk
->Sscp
;
1373 Session
.MediaId
= OpalDisk
->MediaId
;
1374 Session
.OpalBaseComId
= OpalDisk
->OpalBaseComId
;
1376 TcgResult
= OpalGetLockingInfo(&Session
, &OpalDisk
->LockingFeature
);
1377 if (TcgResult
!= TcgResultSuccess
) {
1378 return EFI_DEVICE_ERROR
;
1381 if (OpalDisk
->MsidLength
== 0) {
1382 return EFI_INVALID_PARAMETER
;
1385 // Base on the Msid info to get the ownership, so Msid info must get first.
1387 OpalDisk
->Owner
= OpalUtilDetermineOwnership(&Session
, OpalDisk
->Msid
, OpalDisk
->MsidLength
);