summaryrefslogtreecommitdiff
path: root/Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2017-04-27 11:09:17 +0800
committerGuo Mang <mang.guo@intel.com>2017-04-27 11:09:17 +0800
commitaf874ef836cedf1034bc51eb65a99e9ea4fdc904 (patch)
tree7eeb479ee29e982303803cef8f33f0ba0476eaec /Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
parentb0724f89e3b05de1d6492e79ec89f6d467cb14f0 (diff)
downloadedk2-platforms-af874ef836cedf1034bc51eb65a99e9ea4fdc904.tar.xz
SecurityPkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c')
-rw-r--r--Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c1483
1 files changed, 1483 insertions, 0 deletions
diff --git a/Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c b/Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
new file mode 100644
index 0000000000..4881e72c55
--- /dev/null
+++ b/Core/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
@@ -0,0 +1,1483 @@
+/** @file
+ Implementation of the HII for the Opal UEFI Driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "OpalHii.h"
+#include "OpalDriver.h"
+#include "OpalHiiPrivate.h"
+
+//
+// This is the generated IFR binary Data for each formset defined in VFR.
+// This Data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 OpalPasswordFormBin[];
+
+//
+// This is the generated String package Data for all .UNI files.
+// This Data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 OpalPasswordDxeStrings[];
+
+CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig";
+
+EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
+
+//
+// Handle to the list of HII packages (forms and strings) for this driver
+//
+EFI_HII_HANDLE gHiiPackageListHandle = NULL;
+
+//
+// Package List GUID containing all form and string packages
+//
+const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
+const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
+
+//
+// Structure that contains state of the HII
+// This structure is updated by Hii.cpp and its contents
+// is rendered in the HII.
+//
+OPAL_HII_CONFIGURATION gHiiConfiguration;
+
+CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};
+UINT32 gHiiOldPasswordLength = 0;
+
+//
+// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
+//
+HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ OPAL_PASSWORD_CONFIG_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+
+/**
+ Sets the current system state of global config variables.
+
+**/
+VOID
+HiiSetCurrentConfiguration(
+ VOID
+ )
+{
+ UINT32 PpStorageFlag;
+ EFI_STRING NewString;
+
+ gHiiConfiguration.NumDisks = GetDeviceCount();
+
+ //
+ // Update the BlockSID status string.
+ //
+ PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
+
+ if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ } else {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ }
+ HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);
+ FreePool (NewString);
+
+ if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ } else {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ }
+ HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);
+ FreePool (NewString);
+
+ if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ } else {
+ NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
+ if (NewString == NULL) {
+ DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
+ return;
+ }
+ }
+ HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);
+ FreePool (NewString);
+}
+
+/**
+ Install the HII related resources.
+
+ @retval EFI_SUCCESS Install all the resources success.
+ @retval other Error occur when install the resources.
+**/
+EFI_STATUS
+HiiInstall(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DriverHandle;
+
+ //
+ // Clear the global configuration.
+ //
+ ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
+
+ //
+ // Obtain the driver handle that the BIOS assigned us
+ //
+ DriverHandle = HiiGetDriverImageHandleCB();
+
+ //
+ // Populate the config access protocol with the three functions we are publishing
+ //
+ gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
+ gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
+ gHiiConfigAccessProtocol.Callback = DriverCallback;
+
+ //
+ // Associate the required protocols with our driver handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &DriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &gHiiConfigAccessProtocol, // HII callback
+ &gEfiDevicePathProtocolGuid,
+ &gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ return OpalHiiAddPackages();
+}
+
+/**
+ Install the HII form and string packages.
+
+ @retval EFI_SUCCESS Install all the resources success.
+ @retval EFI_OUT_OF_RESOURCES Out of resource error.
+**/
+EFI_STATUS
+OpalHiiAddPackages(
+ VOID
+ )
+{
+ EFI_HANDLE DriverHandle;
+ CHAR16 *NewString;
+
+ DriverHandle = HiiGetDriverImageHandleCB();
+
+ //
+ // Publish the HII form and HII string packages
+ //
+ gHiiPackageListHandle = HiiAddPackages(
+ &gHiiPackageListGuid,
+ DriverHandle,
+ OpalPasswordDxeStrings,
+ OpalPasswordFormBin,
+ (VOID*)NULL
+ );
+
+ //
+ // Make sure the packages installed successfully
+ //
+ if (gHiiPackageListHandle == NULL) {
+ DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Update Version String in main window
+ //
+ NewString = HiiGetDriverNameCB ();
+ if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
+ DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Uninstall the HII capability.
+
+ @retval EFI_SUCCESS Uninstall all the resources success.
+ @retval others Other errors occur when unistall the hii resource.
+**/
+EFI_STATUS
+HiiUninstall(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Remove the packages we've provided to the BIOS
+ //
+ HiiRemovePackages(gHiiPackageListHandle);
+
+ //
+ // Remove the protocols from our driver handle
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ HiiGetDriverImageHandleCB(),
+ &gEfiHiiConfigAccessProtocolGuid,
+ &gHiiConfigAccessProtocol, // HII callback
+ &gEfiDevicePathProtocolGuid,
+ &gHiiVendorDevicePath, // required for HII callback
+ NULL
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
+ }
+
+ return Status;
+}
+
+/**
+ Updates the main menu form.
+
+ @retval EFI_SUCCESS update the main form success.
+**/
+EFI_STATUS
+HiiPopulateMainMenuForm (
+ VOID
+ )
+{
+ UINT8 Index;
+ CHAR8 *DiskName;
+ EFI_STRING_ID DiskNameId;
+ OPAL_DISK *OpalDisk;
+
+ HiiSetCurrentConfiguration();
+
+ gHiiConfiguration.SupportedDisks = 0;
+
+ for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
+ OpalDisk = HiiGetOpalDiskCB (Index);
+ if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
+ gHiiConfiguration.SupportedDisks |= (1 << Index);
+ DiskNameId = GetDiskNameStringId (Index);
+ DiskName = HiiDiskGetNameCB (Index);
+ if ((DiskName == NULL) || (DiskNameId == 0)) {
+ return EFI_UNSUPPORTED;
+ }
+ HiiSetFormString(DiskNameId, DiskName);
+ }
+ }
+
+ OpalHiiSetBrowserData ();
+ return EFI_SUCCESS;
+}
+
+/**
+ Update the disk action info.
+
+ @param ActionString
+ @param SelectedAction
+
+ @retval EFI_SUCCESS Uninstall all the resources success.
+**/
+EFI_STATUS
+HiiSelectDiskAction (
+ CHAR8 *ActionString,
+ UINT8 SelectedAction
+ )
+{
+ OPAL_DISK *OpalDisk;
+ OPAL_DISK_ACTIONS AvailActions;
+
+ OpalHiiGetBrowserData ();
+
+ HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");
+
+ gHiiConfiguration.SelectedAction = SelectedAction;
+ gHiiConfiguration.AvailableFields = 0;
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+ if (OpalDisk == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ switch (SelectedAction) {
+ case HII_KEY_ID_GOTO_LOCK:
+ case HII_KEY_ID_GOTO_UNLOCK:
+ case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
+ case HII_KEY_ID_GOTO_SET_USER_PWD:
+ case HII_KEY_ID_GOTO_SECURE_ERASE:
+ case HII_KEY_ID_GOTO_DISABLE_USER:
+ case HII_KEY_ID_GOTO_ENABLE_FEATURE: // User is required to enter Password to enable Feature
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
+ break;
+
+ case HII_KEY_ID_GOTO_PSID_REVERT:
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;
+ break;
+
+ case HII_KEY_ID_GOTO_REVERT:
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
+ gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;
+ if (AvailActions.RevertKeepDataForced) {
+ gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;
+ }
+ break;
+ }
+
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get disk name string id.
+
+ @param DiskIndex The input disk index info.
+
+ @retval The disk name string id.
+
+**/
+EFI_STRING_ID
+GetDiskNameStringId(
+ UINT8 DiskIndex
+ )
+{
+ switch (DiskIndex) {
+ case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
+ case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
+ case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
+ case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
+ case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
+ case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
+ }
+ return 0;
+}
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ EFI_BROWSER_ACTION Action,
+ EFI_QUESTION_ID QuestionId,
+ UINT8 Type,
+ EFI_IFR_TYPE_VALUE *Value,
+ EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ HII_KEY HiiKey;
+ UINT8 HiiKeyId;
+ UINT32 PpRequest;
+
+ if (ActionRequest != NULL) {
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
+ //
+ if ((QuestionId & HII_KEY_FLAG) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ HiiKey.Raw = QuestionId;
+ HiiKeyId = (UINT8) HiiKey.KeyBits.Id;
+
+ if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_VAR_SUPPORTED_DISKS:
+ DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
+ return HiiPopulateMainMenuForm ();
+
+ case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
+ return HiiPopulateDiskInfoForm();
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_GOTO_DISK_INFO:
+ return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
+
+ case HII_KEY_ID_GOTO_LOCK:
+ return HiiSelectDiskAction("Action: Lock", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_UNLOCK:
+ return HiiSelectDiskAction("Action: Unlock", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
+ return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SET_USER_PWD:
+ return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SECURE_ERASE:
+ return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_PSID_REVERT:
+ return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_REVERT:
+ return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_DISABLE_USER:
+ return HiiSelectDiskAction("Action: Disable User", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_ENABLE_FEATURE:
+ return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);
+
+ case HII_KEY_ID_ENTER_PASSWORD:
+ return HiiPasswordEntered(Value->string);
+
+ case HII_KEY_ID_ENTER_PSID:
+ return HiiPsidRevert(Value->string);
+
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_BLOCKSID:
+ switch (Value->u8) {
+ case 0:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
+ break;
+
+ case 1:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
+ break;
+
+ case 2:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
+ break;
+
+ case 3:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
+ break;
+
+ case 4:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
+ break;
+
+ case 5:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
+ break;
+
+ case 6:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
+ break;
+
+ default:
+ PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
+ DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
+ break;
+ }
+ HiiSetBlockSidAction(PpRequest);
+
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+ return EFI_SUCCESS;
+
+ default:
+ break;
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Update the global Disk index info.
+
+ @param Index The input disk index info.
+
+ @retval EFI_SUCCESS Update the disk index info success.
+
+**/
+EFI_STATUS
+HiiSelectDisk(
+ UINT8 Index
+ )
+{
+ OpalHiiGetBrowserData();
+ gHiiConfiguration.SelectedDiskIndex = Index;
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Draws the disk info form.
+
+ @retval EFI_SUCCESS Draw the disk info success.
+
+**/
+EFI_STATUS
+HiiPopulateDiskInfoForm(
+ VOID
+ )
+{
+ OPAL_DISK* OpalDisk;
+ OPAL_DISK_ACTIONS AvailActions;
+ TCG_RESULT Ret;
+ CHAR8 *DiskName;
+
+ OpalHiiGetBrowserData();
+
+ DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
+ if (DiskName == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
+
+ ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));
+
+ gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+
+ if (OpalDisk != NULL) {
+ OpalDiskUpdateStatus (OpalDisk);
+ Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
+ if (Ret == TcgResultSuccess) {
+ //
+ // Update actions, always allow PSID Revert
+ //
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
+
+ //
+ // Always allow unlock to handle device migration
+ //
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
+
+ if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
+ if (OpalDisk->Owner == OpalOwnershipNobody) {
+ gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
+
+ //
+ // Update strings
+ //
+ HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
+ } else {
+ DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
+ }
+ } else {
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
+
+ HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
+
+ //
+ // Determine revert options for disk
+ // Default initialize keep user Data to be true
+ //
+ gHiiConfiguration.KeepUserData = 1;
+ }
+ }
+ }
+
+ //
+ // Pass the current configuration to the BIOS
+ //
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reverts the Opal disk to factory default.
+
+ @param PsidStringId The string id for the PSID info.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiPsidRevert(
+ EFI_STRING_ID PsidStringId
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_PSID Psid;
+ OPAL_DISK *OpalDisk;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+ CHAR16 *UnicodeStr;
+ UINT8 TmpBuf[PSID_CHARACTER_STRING_END_LENGTH];
+
+ Ret = TcgResultFailure;
+
+ UnicodeStr = HiiGetString (gHiiPackageListHandle, PsidStringId, NULL);
+ ZeroMem (TmpBuf, sizeof (TmpBuf));
+ UnicodeStrToAsciiStrS (UnicodeStr, (CHAR8*)TmpBuf, PSID_CHARACTER_STRING_END_LENGTH);
+ CopyMem (Psid.Psid, TmpBuf, PSID_CHARACTER_LENGTH);
+ HiiSetString (gHiiPackageListHandle, PsidStringId, L"", NULL);
+ ZeroMem (TmpBuf, sizeof (TmpBuf));
+ ZeroMem (UnicodeStr, StrSize (UnicodeStr));
+ FreePool (UnicodeStr);
+
+ OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
+ if (OpalDisk != NULL) {
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);
+ }
+
+ ZeroMem (Psid.Psid, PSID_CHARACTER_LENGTH);
+
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set password for the disk.
+
+ @param OpalDisk The disk need to set the password.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiSetPassword(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_RESULT Ret;
+ BOOLEAN ExistingPassword;
+ OPAL_SESSION Session;
+
+ ExistingPassword = FALSE;
+
+ //
+ // PassLength = 0 means check whether exist old password.
+ //
+ if (PassLength == 0) {
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {
+ ExistingPassword = FALSE;
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {
+ ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ //
+ // Set user Password option shall only be shown if an Admin Password exists
+ // so a Password is always required (Admin or Existing User Password)
+ //
+ ExistingPassword = TRUE;
+ }
+
+ //
+ // Return error if there is a previous Password
+ // see UEFI 2.4 errata B, Figure 121. Password Flowchart
+ //
+ return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");
+ //
+ // Password entered.
+ // No current Owner, so set new Password, must be admin Password
+ //
+ if (OpalDisk->Owner == OpalOwnershipNobody) {
+ Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // 1st Password entered
+ //
+ if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {
+
+ //
+ // Unknown ownership - prompt for old Password, then new
+ // old Password is not set yet - first time through
+ // assume authority provided is admin1, overwritten if user1 authority works below
+ //
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ //
+ // First try to login as USER1 to Locking SP to see if we're simply updating its Password
+ //
+ Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);
+ if (Ret == TcgResultSuccess) {
+ //
+ // User1 worked so authority 1 means user 1
+ //
+ CopyMem(gHiiOldPassword, Password, PassLength);
+ gHiiOldPasswordLength = PassLength;
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Else try admin1 below
+ //
+ Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
+ if (Ret == TcgResultSuccess) {
+ CopyMem(gHiiOldPassword, Password, PassLength);
+ gHiiOldPasswordLength = PassLength;
+
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");
+
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ return EFI_NOT_READY;
+ }
+ }
+
+ //
+ // New Password entered
+ //
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ Ret = OpalSupportSetPassword(
+ &Session,
+ gHiiOldPassword,
+ gHiiOldPasswordLength,
+ Password,
+ PassLength,
+ OpalDisk->OpalDevicePath,
+ FALSE
+ );
+ } else {
+ Ret = OpalSupportSetPassword(
+ &Session,
+ gHiiOldPassword,
+ gHiiOldPasswordLength,
+ Password,
+ PassLength,
+ OpalDisk->OpalDevicePath,
+ TRUE
+ );
+ }
+
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
+ }
+
+ //
+ // Reset old Password storage
+ //
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+ return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;
+}
+
+/**
+ Secure Erases Opal Disk.
+
+ @param OpalDisk The disk need to erase data.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiSecureErase(
+ OPAL_DISK *OpalDisk,
+ const VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION AdminSpSession;
+
+ if (PassLength == 0) {
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&AdminSpSession, sizeof(AdminSpSession));
+ AdminSpSession.Sscp = OpalDisk->Sscp;
+ AdminSpSession.MediaId = OpalDisk->MediaId;
+ AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );
+ }
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+/**
+ Disables User for Opal Disk.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiDisableUser(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );
+ }
+ HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Revert Opal Disk as Admin1.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+ @param KeepUserData Whether need to keey user data.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiRevert(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength,
+ BOOLEAN KeepUserData
+ )
+{
+ CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
+ // return error to indicate there is an existing Password
+ return EFI_DEVICE_ERROR;
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportRevert(
+ &Session,
+ KeepUserData,
+ Password,
+ PassLength,
+ OpalDisk->Msid,
+ OpalDisk->MsidLength,
+ &PasswordFailed,
+ OpalDisk->OpalDevicePath
+ );
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );
+ }
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Unlocks Opal Disk.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiUnlock(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ if (Ret == TcgResultSuccess) {
+ DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));
+ return EFI_DEVICE_ERROR;
+ } else {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+}
+
+/**
+ Use the input password to do the specified action.
+
+ @param Str The input password saved in.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiPasswordEntered(
+ EFI_STRING_ID Str
+ )
+{
+ OPAL_DISK* OpalDisk;
+ CHAR8 Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];
+ CHAR16* UniStr;
+ UINT32 PassLength;
+ EFI_STATUS Status;
+
+ OpalHiiGetBrowserData();
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+ if (OpalDisk == NULL) {
+ DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));
+ return EFI_NOT_FOUND;
+ }
+
+ if (Str == 0) {
+ DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem(Password, sizeof(Password));
+
+ UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);
+ if (UniStr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ HiiSetString(gHiiPackageListHandle, Str, L"", NULL);
+
+ PassLength = (UINT32) StrLen (UniStr);
+ if (PassLength >= sizeof(Password)) {
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");
+ ZeroMem (UniStr, StrSize (UniStr));
+ FreePool(UniStr);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ UnicodeStrToAsciiStrS (UniStr, Password, sizeof (Password));
+ ZeroMem (UniStr, StrSize (UniStr));
+ FreePool(UniStr);
+
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {
+ Status = HiiUnlock (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {
+ Status = HiiSecureErase (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {
+ Status = HiiDisableUser (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {
+ if (OpalDisk->SupportedAttributes.PyriteSsc == 1 && OpalDisk->LockingFeature.MediaEncryption == 0) {
+ //
+ // For pyrite type device which also not supports media encryption, it not accept "Keep User Data" parameter.
+ // So here hardcode a FALSE for this case.
+ //
+ Status = HiiRevert(OpalDisk, Password, PassLength, FALSE);
+ } else {
+ Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);
+ }
+ } else {
+ Status = HiiSetPassword(OpalDisk, Password, PassLength);
+ }
+
+ ZeroMem (Password, sizeof (Password));
+
+ OpalHiiSetBrowserData ();
+
+ return Status;
+}
+
+/**
+ Send BlockSid request through TPM physical presence module.
+
+ @param PpRequest TPM physical presence operation request.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiSetBlockSidAction (
+ IN UINT32 PpRequest
+ )
+{
+ UINT32 ReturnCode;
+ EFI_STATUS Status;
+
+ ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
+ if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
+ Status = EFI_SUCCESS;
+ } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Configuration A null-terminated Unicode string in <ConfigResp>
+ format.
+ @param Progress A pointer to a string filled in with the offset of
+ the most recent '&' before the first failing
+ name/value pair (or the beginning of the string if
+ the failure is in the first name/value pair) or
+ the terminating NULL if all was successful.
+
+ @retval EFI_SUCCESS The Results is processed successfully.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ CONST EFI_STRING Configuration,
+ EFI_STRING *Progress
+ )
+{
+ if (Configuration == NULL || Progress == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ *Progress = Configuration;
+ if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ *Progress = Configuration + StrLen (Configuration);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function allows a caller to extract the current configuration for one
+ or more named elements from the target driver.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param Progress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ '&' before the first failing name/value pair (or
+ the beginning of the string if the failure is in
+ the first name/value pair) if the request was not
+ successful.
+ @param Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values filled
+ in for the names in the Request string. String to
+ be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ CONST EFI_STRING Request,
+ EFI_STRING *Progress,
+ EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for valid parameters
+ //
+ if (Progress == NULL || Results == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ *Progress = Request;
+ if ((Request != NULL) &&
+ !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
+ //
+ Status = gHiiConfigRouting->BlockToConfig(
+ gHiiConfigRouting,
+ Request,
+ (UINT8*)&gHiiConfiguration,
+ sizeof(OPAL_HII_CONFIGURATION),
+ Results,
+ Progress
+ );
+
+ return (Status);
+}
+
+
+/**
+
+ Pass the current system state to the bios via the hii_G_Configuration.
+
+**/
+VOID
+OpalHiiSetBrowserData (
+ VOID
+ )
+{
+ HiiSetBrowserData(
+ &gHiiSetupVariableGuid,
+ (CHAR16*)L"OpalHiiConfig",
+ sizeof(gHiiConfiguration),
+ (UINT8*)&gHiiConfiguration,
+ NULL
+ );
+}
+
+
+/**
+
+ Populate the hii_g_Configuraton with the browser Data.
+
+**/
+VOID
+OpalHiiGetBrowserData (
+ VOID
+ )
+{
+ HiiGetBrowserData(
+ &gHiiSetupVariableGuid,
+ (CHAR16*)L"OpalHiiConfig",
+ sizeof(gHiiConfiguration),
+ (UINT8*)&gHiiConfiguration
+ );
+}
+
+/**
+ Set a string Value in a form.
+
+ @param DestStringId The stringid which need to update.
+ @param SrcAsciiStr The string nned to update.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiSetFormString(
+ EFI_STRING_ID DestStringId,
+ CHAR8 *SrcAsciiStr
+ )
+{
+ UINT32 Len;
+ UINT32 UniSize;
+ CHAR16* UniStr;
+
+ //
+ // Determine the Length of the sting
+ //
+ Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
+
+ //
+ // Allocate space for the unicode string, including terminator
+ //
+ UniSize = (Len + 1) * sizeof(CHAR16);
+ UniStr = (CHAR16*)AllocateZeroPool(UniSize);
+
+ //
+ // Copy into unicode string, then copy into string id
+ //
+ AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);
+
+ //
+ // Update the string in the form
+ //
+ if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
+ DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
+ FreePool(UniStr);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ //
+ // Free the memory
+ //
+ FreePool(UniStr);
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Initialize the Opal disk base on the hardware info get from device.
+
+ @param Dev The Opal device.
+
+ @retval EFI_SUCESS Initialize the device success.
+ @retval EFI_DEVICE_ERROR Get info from device failed.
+
+**/
+EFI_STATUS
+OpalDiskInitialize (
+ IN OPAL_DRIVER_DEVICE *Dev
+ )
+{
+ TCG_RESULT TcgResult;
+ OPAL_SESSION Session;
+
+ ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
+ Dev->OpalDisk.Sscp = Dev->Sscp;
+ Dev->OpalDisk.MediaId = Dev->MediaId;
+ Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = Dev->Sscp;
+ Session.MediaId = Dev->MediaId;
+
+ TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+ Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
+
+ TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return OpalDiskUpdateStatus (&Dev->OpalDisk);
+}
+
+/**
+ Update the device info.
+
+ @param OpalDisk The Opal device.
+
+ @retval EFI_SUCESS Initialize the device success.
+ @retval EFI_DEVICE_ERROR Get info from device failed.
+ @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
+
+**/
+EFI_STATUS
+OpalDiskUpdateStatus (
+ OPAL_DISK *OpalDisk
+ )
+{
+ TCG_RESULT TcgResult;
+ OPAL_SESSION Session;
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (OpalDisk->MsidLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ //
+ // Base on the Msid info to get the ownership, so Msid info must get first.
+ //
+ OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
+ }
+
+ return EFI_SUCCESS;
+}
+