diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c new file mode 100644 index 0000000000..ef963d0e0b --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c @@ -0,0 +1,398 @@ +/** @file + UEFI Component Name(2) protocol implementation for Opal driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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 "OpalDriver.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gOpalComponentName = { + OpalEfiDriverComponentNameGetDriverName, + OpalEfiDriverComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOpalComponentName2 = { + OpalEfiDriverComponentName2GetDriverName, + OpalEfiDriverComponentName2GetControllerName, + "en" +}; + + +/// The name of the driver in all the languages we support. +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOpalDriverNameTable[] = { + { LANGUAGE_RFC_3066_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE }, + { LANGUAGE_ISO_639_2_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE }, + { 0, 0 } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentNameGetDriverName( + EFI_COMPONENT_NAME_PROTOCOL* This, + CHAR8* Language, + CHAR16** DriverName + ) +{ + return LookupUnicodeString2( + Language, + This->SupportedLanguages, + mOpalDriverNameTable, + DriverName, + TRUE + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentName2GetDriverName( + EFI_COMPONENT_NAME2_PROTOCOL* This, + CHAR8* Language, + CHAR16** DriverName + ) +{ + return LookupUnicodeString2( + Language, + This->SupportedLanguages, + mOpalDriverNameTable, + DriverName, + FALSE + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +GetControllerName( + EFI_HANDLE ControllerHandle, + EFI_HANDLE ChildHandle, + CHAR8* Language, + CHAR16** ControllerName + ) +{ + if (Language == NULL || ControllerName == NULL || ControllerHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + // don't support any controller or children names + return EFI_UNSUPPORTED; +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentNameGetControllerName( + EFI_COMPONENT_NAME_PROTOCOL* This, + EFI_HANDLE ControllerHandle, + EFI_HANDLE ChildHandle, + CHAR8* Language, + CHAR16** ControllerName + ) +{ + return (GetControllerName( ControllerHandle, ChildHandle, Language, ControllerName)); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentName2GetControllerName( + EFI_COMPONENT_NAME2_PROTOCOL* This, + EFI_HANDLE ControllerHandle, + EFI_HANDLE ChildHandle, + CHAR8* Language, + CHAR16** ControllerName + ) +{ + return (GetControllerName(ControllerHandle, ChildHandle, Language, ControllerName)); +} + diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c new file mode 100644 index 0000000000..e06ce4a6a1 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c @@ -0,0 +1,1083 @@ +/** @file + Entrypoint of Opal UEFI Driver and contains all the logic to + register for new Opal device instances. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an +// HII GUI to manage Opal features if the device is Opal capable +// If the Opal device is being managed by the UEFI Driver, it shall provide a popup +// window during boot requesting a user password + +#include "OpalDriver.h" +#include "OpalDriverPrivate.h" +#include "OpalHii.h" + +OPAL_DRIVER mOpalDriver; + +// flag to track hii installation +BOOLEAN gHiiInstalled = FALSE; + + +#define MAX_PASSWORD_SIZE 32 +#define MAX_PASSWORD_TRY_COUNT 5 + +// +// Globals +// +EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = { + OpalEfiDriverBindingSupported, + OpalEfiDriverBindingStart, + OpalEfiDriverBindingStop, + 0x1b, + NULL, + NULL +}; + + +/** + Add new device to the global device list. + + @param Dev New create device. + +**/ +VOID +AddDeviceToTail( + IN OPAL_DRIVER_DEVICE *Dev + ) +{ + OPAL_DRIVER_DEVICE *TmpDev; + + if (mOpalDriver.DeviceList == NULL) { + mOpalDriver.DeviceList = Dev; + } else { + TmpDev = mOpalDriver.DeviceList; + while (TmpDev->Next != NULL) { + TmpDev = TmpDev->Next; + } + + TmpDev->Next = Dev; + } +} + +/** + Remove one device in the global device list. + + @param Dev The device need to be removed. + +**/ +VOID +RemoveDevice ( + IN OPAL_DRIVER_DEVICE *Dev + ) +{ + OPAL_DRIVER_DEVICE *TmpDev; + + if (mOpalDriver.DeviceList == NULL) { + return; + } + + if (mOpalDriver.DeviceList == Dev) { + mOpalDriver.DeviceList = NULL; + return; + } + + TmpDev = mOpalDriver.DeviceList; + while (TmpDev->Next != NULL) { + if (TmpDev->Next == Dev) { + TmpDev->Next = Dev->Next; + break; + } + } +} + +/** + Get current device count. + + @retval return the current created device count. + +**/ +UINT8 +GetDeviceCount ( + VOID + ) +{ + UINT8 Count; + OPAL_DRIVER_DEVICE *TmpDev; + + Count = 0; + TmpDev = mOpalDriver.DeviceList; + + while (TmpDev != NULL) { + Count++; + TmpDev = TmpDev->Next; + } + + return Count; +} + +/** + Get password input from the popup windows, and unlock the device. + + @param[in] Dev The device which need to be unlock. + @param[out] PressEsc Whether user escape function through Press ESC. + + @retval Password string if success. NULL if failed. + +**/ +CHAR8 * +OpalDriverPopUpHddPassword ( + IN OPAL_DRIVER_DEVICE *Dev, + OUT BOOLEAN *PressEsc + ) +{ + EFI_INPUT_KEY InputKey; + UINTN InputLength; + CHAR16 Mask[MAX_PASSWORD_SIZE + 1]; + CHAR16 Unicode[MAX_PASSWORD_SIZE + 1]; + CHAR8 *Ascii; + CHAR16 *PopUpString; + UINTN StrLength; + + ZeroMem(Unicode, sizeof(Unicode)); + ZeroMem(Mask, sizeof(Mask)); + + StrLength = StrLen(Dev->Name16); + PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2); + *PressEsc = FALSE; + + if (Dev->Name16 == NULL) { + UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk"); + } else { + UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16); + } + + gST->ConOut->ClearScreen(gST->ConOut); + + InputLength = 0; + while (TRUE) { + Mask[InputLength] = L'_'; + CreatePopUp( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + L"---------------------", + Mask, + NULL + ); + + // + // Check key. + // + if (InputKey.ScanCode == SCAN_NULL) { + // + // password finished + // + if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) { + // + // Add the null terminator. + // + Unicode[InputLength] = 0; + InputLength++; + break; + } else if ((InputKey.UnicodeChar == CHAR_NULL) || + (InputKey.UnicodeChar == CHAR_TAB) || + (InputKey.UnicodeChar == CHAR_LINEFEED) + ) { + continue; + } else { + // + // delete last key entered + // + if (InputKey.UnicodeChar == CHAR_BACKSPACE) { + if (InputLength > 0) { + Unicode[InputLength] = 0; + Mask[InputLength] = 0; + InputLength--; + } + } else { + // + // add Next key entry + // + Unicode[InputLength] = InputKey.UnicodeChar; + Mask[InputLength] = L'*'; + InputLength++; + if (InputLength == MAX_PASSWORD_SIZE) { + // + // Add the null terminator. + // + Unicode[InputLength] = 0; + Mask[InputLength] = 0; + break; + } + } + } + } + + // + // exit on ESC + // + if (InputKey.ScanCode == SCAN_ESC) { + *PressEsc = TRUE; + break; + } + } + + gST->ConOut->ClearScreen(gST->ConOut); + + if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) { + return NULL; + } + + Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1); + if (Ascii == NULL) { + return NULL; + } + + UnicodeStrToAsciiStr(Unicode, Ascii); + + return Ascii; +} + +/** + Check if disk is locked, show popup window and ask for password if it is + + @param[in] Dev The device which need to be unlock. + +**/ +VOID +OpalDriverRequestPassword ( + OPAL_DRIVER_DEVICE *Dev + ) +{ + UINT8 Count; + BOOLEAN IsEnabled; + CHAR8 *Password; + UINT32 PasswordLen; + TCG_RESULT Ret; + EFI_INPUT_KEY Key; + OPAL_SESSION Session; + BOOLEAN PressEsc; + + if (Dev == NULL) { + return; + } + + Count = 0; + + IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); + if (IsEnabled) { + ZeroMem(&Session, sizeof(Session)); + Session.Sscp = Dev->OpalDisk.Sscp; + Session.MediaId = Dev->OpalDisk.MediaId; + Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; + + while (Count < MAX_PASSWORD_TRY_COUNT) { + Password = OpalDriverPopUpHddPassword (Dev, &PressEsc); + if (PressEsc) { + // + // User not input password and press ESC, keep device in lock status and continue boot. + // + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Confirm: Not unlock device and continue boot?.", + L"Press ENTER to confirm, Press Esc to input password", + NULL + ); + } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); + + if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + gST->ConOut->ClearScreen(gST->ConOut); + // + // Keep lock and continue boot. + // + return; + } else { + // + // Let user input password again. + // + continue; + } + } + + if (Password == NULL) { + Count ++; + continue; + } + PasswordLen = (UINT32) AsciiStrLen(Password); + + if (OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature)) { + Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); + } else { + Ret = OpalSupportLock(&Session, Password, PasswordLen, Dev->OpalDevicePath); + if (Ret == TcgResultSuccess) { + Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath); + } + } + + if (Password != NULL) { + ZeroMem (Password, PasswordLen); + FreePool (Password); + } + + if (Ret == TcgResultSuccess) { + break; + } + + Count++; + + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Invalid password.", + L"Press ENTER to retry", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + } + + if (Count >= MAX_PASSWORD_TRY_COUNT) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Opal password retry count is expired. Keep lock and continue boot.", + L"Press ENTER to continue", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + gST->ConOut->ClearScreen(gST->ConOut); + } + } +} + +/** + Get devcie list info. + + @retval return the device list pointer. +**/ +OPAL_DRIVER_DEVICE* +OpalDriverGetDeviceList( + VOID + ) +{ + return mOpalDriver.DeviceList; +} + +/** + ReadyToBoot callback to send BlockSid command. + + @param Event Pointer to this event + @param Context Event hanlder private Data + +**/ +VOID +EFIAPI +ReadyToBootCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + OPAL_DRIVER_DEVICE* Itr; + UINT8 Count; + TCG_RESULT Result; + OPAL_EXTRA_INFO_VAR OpalExtraInfo; + UINTN DataSize; + OPAL_SESSION Session; + + Count = 0; + + gBS->CloseEvent (Event); + + DataSize = sizeof (OPAL_EXTRA_INFO_VAR); + Status = gRT->GetVariable ( + OPAL_EXTRA_INFO_VAR_NAME, + &gOpalExtraInfoVariableGuid, + NULL, + &DataSize, + &OpalExtraInfo + ); + if (EFI_ERROR (Status)) { + return; + } + + if (OpalExtraInfo.EnableBlockSid == TRUE) { + // + // Send BlockSID command to each Opal disk + // + Itr = mOpalDriver.DeviceList; + Count = 0; + while (Itr != NULL) { + ZeroMem(&Session, sizeof(Session)); + Session.Sscp = Itr->OpalDisk.Sscp; + Session.MediaId = Itr->OpalDisk.MediaId; + Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId; + + Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE + if (Result != TcgResultSuccess) { + DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n")); + break; + } + + Itr = Itr->Next; + Count++; + } + } +} + +/** + Stop this Controller. + + @param Dev The device need to be stopped. + +**/ +VOID +OpalDriverStopDevice ( + OPAL_DRIVER_DEVICE *Dev + ) +{ + // + // free each name + // + FreePool(Dev->Name16); + + // + // remove OPAL_DRIVER_DEVICE from the list + // it updates the controllerList pointer + // + RemoveDevice(Dev); + + // + // close protocols that were opened + // + gBS->CloseProtocol( + Dev->Handle, + &gEfiStorageSecurityCommandProtocolGuid, + gOpalDriverBinding.DriverBindingHandle, + Dev->Handle + ); + + gBS->CloseProtocol( + Dev->Handle, + &gEfiBlockIoProtocolGuid, + gOpalDriverBinding.DriverBindingHandle, + Dev->Handle + ); + + FreePool(Dev); +} + +/** + Get devcie name through the component name protocol. + + @param[in] AllHandlesBuffer The handle buffer for current system. + @param[in] NumAllHandles The number of handles for the handle buffer. + @param[in] Dev The device which need to get name. + @param[in] UseComp1 Whether use component name or name2 protocol. + + @retval TRUE Find the name for this device. + @retval FALSE Not found the name for this device. +**/ +BOOLEAN +OpalDriverGetDeviceNameByProtocol( + EFI_HANDLE *AllHandlesBuffer, + UINTN NumAllHandles, + OPAL_DRIVER_DEVICE *Dev, + BOOLEAN UseComp1 + ) +{ + EFI_HANDLE* ProtocolHandlesBuffer; + UINTN NumProtocolHandles; + EFI_STATUS Status; + EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout + EFI_GUID Protocol; + UINTN StrLength; + EFI_DEVICE_PATH_PROTOCOL* TmpDevPath; + UINTN Index1; + UINTN Index2; + EFI_HANDLE TmpHandle; + CHAR16 *DevName; + + if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) { + return FALSE; + } + + Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid; + + // + // Find all EFI_HANDLES with protocol + // + Status = gBS->LocateHandleBuffer( + ByProtocol, + &Protocol, + NULL, + &NumProtocolHandles, + &ProtocolHandlesBuffer + ); + if (EFI_ERROR(Status)) { + return FALSE; + } + + + // + // Exit early if no supported devices + // + if (NumProtocolHandles == 0) { + return FALSE; + } + + // + // Get printable name by iterating through all protocols + // using the handle as the child, and iterate through all handles for the controller + // exit loop early once found, if not found, then delete device + // storage security protocol instances already exist, add them to internal list + // + Status = EFI_DEVICE_ERROR; + for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) { + DevName = NULL; + + if (Dev->Name16 != NULL) { + return TRUE; + } + + TmpHandle = ProtocolHandlesBuffer[Index1]; + + Status = gBS->OpenProtocol( + TmpHandle, + &Protocol, + (VOID**)&Cnp1_2, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR(Status) || Cnp1_2 == NULL) { + continue; + } + + // + // Use all handles array as controller handle + // + for (Index2 = 0; Index2 < NumAllHandles; Index2++) { + Status = Cnp1_2->GetControllerName( + Cnp1_2, + AllHandlesBuffer[Index2], + Dev->Handle, + LANGUAGE_ISO_639_2_ENGLISH, + &DevName + ); + if (EFI_ERROR(Status)) { + Status = Cnp1_2->GetControllerName( + Cnp1_2, + AllHandlesBuffer[Index2], + Dev->Handle, + LANGUAGE_RFC_3066_ENGLISH, + &DevName + ); + } + if (!EFI_ERROR(Status) && DevName != NULL) { + StrLength = StrLen(DevName) + 1; // Add one for NULL terminator + Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16)); + ASSERT (Dev->Name16 != NULL); + StrCpyS (Dev->Name16, StrLength, DevName); + Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength); + UnicodeStrToAsciiStr(DevName, Dev->NameZ); + + // + // Retrieve bridge BDF info and port number or namespace depending on type + // + TmpDevPath = NULL; + Status = gBS->OpenProtocol( + Dev->Handle, + &gEfiDevicePathProtocolGuid, + (VOID**)&TmpDevPath, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR(Status)) { + Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath); + return TRUE; + } + + if (Dev->Name16 != NULL) { + FreePool(Dev->Name16); + Dev->Name16 = NULL; + } + if (Dev->NameZ != NULL) { + FreePool(Dev->NameZ); + Dev->NameZ = NULL; + } + } + } + } + + return FALSE; +} + +/** + Get devcie name through the component name protocol. + + @param[in] Dev The device which need to get name. + + @retval TRUE Find the name for this device. + @retval FALSE Not found the name for this device. +**/ +BOOLEAN +OpalDriverGetDriverDeviceName( + OPAL_DRIVER_DEVICE *Dev + ) +{ + EFI_HANDLE* AllHandlesBuffer; + UINTN NumAllHandles; + EFI_STATUS Status; + + if (Dev == NULL) { + DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n")); + return FALSE; + } + + // + // Iterate through ComponentName2 handles to get name, if fails, try ComponentName + // + if (Dev->Name16 == NULL) { + DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n")); + // + // Find all EFI_HANDLES + // + Status = gBS->LocateHandleBuffer( + AllHandles, + NULL, + NULL, + &NumAllHandles, + &AllHandlesBuffer + ); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status )); + return FALSE; + } + + // + // Try component Name2 + // + if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) { + DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n")); + if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) { + DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n")); + return FALSE; + } + } + } + + return TRUE; +} + +/** + Main entry for this driver. + + @param ImageHandle Image Handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS This function always complete successfully. +**/ +EFI_STATUS +EFIAPI +EfiDriverEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE* SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gOpalDriverBinding, + ImageHandle, + &gOpalComponentName, + &gOpalComponentName2 + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n")); + return Status ; + } + + // + // Initialize Driver object + // + ZeroMem(&mOpalDriver, sizeof(mOpalDriver)); + mOpalDriver.Handle = ImageHandle; + + // + // register a ReadyToBoot event callback for sending BlockSid command + // + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + ReadyToBootCallback, + (VOID *) &ImageHandle, + &ReadyToBootEvent + ); + + return Status; +} + +/** + Tests to see if this driver supports a given controller. + + This function checks to see if the controller contains an instance of the + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL + and returns EFI_SUCCESS if it does. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The Handle of the controller to test. This Handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath This parameter is ignored. + + @retval EFI_SUCCESS The device contains required protocols + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device does not contain requires protocols + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingSupported( + IN EFI_DRIVER_BINDING_PROTOCOL* This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL* SecurityCommand; + EFI_BLOCK_IO_PROTOCOL* BlkIo; + + // + // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle. + // + Status = gBS->OpenProtocol( + Controller, + &gEfiStorageSecurityCommandProtocolGuid, + ( VOID ** )&SecurityCommand, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Close protocol and reopen in Start call + // + gBS->CloseProtocol( + Controller, + &gEfiStorageSecurityCommandProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL + // function APIs + // + Status = gBS->OpenProtocol( + Controller, + &gEfiBlockIoProtocolGuid, + (VOID **)&BlkIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n")); + return Status; + } + + // + // Close protocol and reopen in Start call + // + gBS->CloseProtocol( + Controller, + &gEfiBlockIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + return EFI_SUCCESS; +} + +/** + Enables Opal Management on a supported device if available. + + The start function is designed to be called after the Opal UEFI Driver has confirmed the + "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols. + This function will complete the other necessary checks, such as verifying the device supports + the correct version of Opal. Upon verification, it will add the device to the + Opal HII list in order to expose Opal managmeent options. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The Handle of the controller to start. This Handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the Handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child Handle is created by this + driver. + + @retval EFI_SUCCESS Opal management was enabled. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failed to start the device. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingStart( + IN EFI_DRIVER_BINDING_PROTOCOL* This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + OPAL_DRIVER_DEVICE *Dev; + OPAL_DRIVER_DEVICE *Itr; + BOOLEAN Result; + + Itr = mOpalDriver.DeviceList; + while (Itr != NULL) { + if (Controller == Itr->Handle) { + return EFI_SUCCESS; + } + Itr = Itr->Next; + } + + // + // Create internal device for tracking. This allows all disks to be tracked + // by same HII form + // + Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE)); + if (Dev == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Dev->Handle = Controller; + + // + // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks + // + Status = gBS->OpenProtocol( + Controller, + &gEfiStorageSecurityCommandProtocolGuid, + (VOID **)&Dev->Sscp, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR(Status)) { + FreePool(Dev); + return Status; + } + + // + // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL + // function APIs + // + Status = gBS->OpenProtocol( + Controller, + &gEfiBlockIoProtocolGuid, + (VOID **)&BlkIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR(Status)) { + // + // Close storage security that was opened + // + gBS->CloseProtocol( + Controller, + &gEfiStorageSecurityCommandProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + FreePool(Dev); + return Status; + } + + // + // Save mediaId + // + Dev->MediaId = BlkIo->Media->MediaId; + + gBS->CloseProtocol( + Controller, + &gEfiBlockIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Acquire Ascii printable name of child, if not found, then ignore device + // + Result = OpalDriverGetDriverDeviceName (Dev); + if (!Result) { + goto Done; + } + + Status = OpalDiskInitialize (Dev); + if (EFI_ERROR (Status)) { + goto Done; + } + + AddDeviceToTail(Dev); + + // + // Install Hii if it hasn't already been installed + // + if (!gHiiInstalled) { + HiiInstall(); + gHiiInstalled = TRUE; + } + + // + // check if device is locked and prompt for password + // + OpalDriverRequestPassword (Dev); + + return EFI_SUCCESS; + +Done: + // + // free device, close protocols and exit + // + gBS->CloseProtocol( + Controller, + &gEfiStorageSecurityCommandProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + FreePool(Dev); + + return EFI_DEVICE_ERROR; +} + +/** + Stop this driver on Controller. + + @param This Protocol instance pointer. + @param Controller Handle of device to stop driver on + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed Controller. + @retval other This driver could not be removed from this device. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingStop( + EFI_DRIVER_BINDING_PROTOCOL* This, + EFI_HANDLE Controller, + UINTN NumberOfChildren, + EFI_HANDLE* ChildHandleBuffer + ) +{ + OPAL_DRIVER_DEVICE* Itr; + + Itr = mOpalDriver.DeviceList; + + // + // does Controller match any of the devices we are managing for Opal + // + while (Itr != NULL) { + if (Itr->Handle == Controller) { + OpalDriverStopDevice (Itr); + return EFI_SUCCESS; + } + + Itr = Itr->Next; + } + + return EFI_NOT_FOUND; +} + + +/** + Unloads UEFI Driver. Very useful for debugging and testing. + + @param ImageHandle Image Handle this driver. + + @retval EFI_SUCCESS This function always complete successfully. + @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid. +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + OPAL_DRIVER_DEVICE *Itr; + + Status = EFI_SUCCESS; + + if (ImageHandle != gImageHandle) { + return (EFI_INVALID_PARAMETER); + } + + // + // Uninstall any interface added to each device by us + // + while (mOpalDriver.DeviceList) { + Itr = mOpalDriver.DeviceList; + // + // Remove OPAL_DRIVER_DEVICE from the list + // it updates the controllerList pointer + // + OpalDriverStopDevice(Itr); + } + + // + // Uninstall the HII capability + // + Status = HiiUninstall(); + + return Status; +} + diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h new file mode 100644 index 0000000000..213c139e01 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h @@ -0,0 +1,413 @@ +/** @file + Values defined and used by the Opal UEFI Driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef _OPAL_DRIVER_H_ +#define _OPAL_DRIVER_H_ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EFI_DRIVER_NAME_UNICODE L"1.0 UEFI Opal Driver" + +// UEFI 2.1 +#define LANGUAGE_RFC_3066_ENGLISH ((CHAR8*)"en") + +// UEFI/EFI < 2.1 +#define LANGUAGE_ISO_639_2_ENGLISH ((CHAR8*)"eng") + + +#define UNLOCK_VAR_NAME (const CHAR16*)L"UNLOCK" +#define OPAL_FILTER_DRIVER_VAR_NAME L"FILTER_DRIVER" + + +#define CONCAT_(x, y) x ## y +#define CONCAT(x, y) CONCAT_(x, y) + +#define UNICODE_STR(x) CONCAT( L, x ) + +extern EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gOpalComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gOpalComponentName2; + +/** + Unloads UEFI Driver. Very useful for debugging and testing. + + @param ImageHandle Image handle this driver. + + @retval EFI_SUCCESS This function always complete successfully. + @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid. +**/ +EFI_STATUS +EFIAPI +EfiDriverUnload( + EFI_HANDLE ImageHandle + ); + + +/** + Test to see if this driver supports Controller. + + @param This Protocol instance pointer. + @param ControllerHandle Handle of device to test + @param RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS This driver supports this device. + @retval EFI_ALREADY_STARTED This driver is already running on this device. + @retval other This driver does not support this device. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingSupported( + EFI_DRIVER_BINDING_PROTOCOL* This, + EFI_HANDLE Controller, + EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath + ); + +/** + Enables Opal Management on a supported device if available. + + The start function is designed to be called after the Opal UEFI Driver has confirmed the + "controller", which is a child handle, contains the EF_STORAGE_SECURITY_COMMAND protocols. + This function will complete the other necessary checks, such as verifying the device supports + the correct version of Opal. Upon verification, it will add the device to the + Opal HII list in order to expose Opal managmeent options. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS Opal management was enabled. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failed to start the device. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingStart( + EFI_DRIVER_BINDING_PROTOCOL* This, + EFI_HANDLE Controller, + EFI_DEVICE_PATH_PROTOCOL* RemainingDevicePath + ); + +/** + Stop this driver on Controller. + + @param This Protocol instance pointer. + @param Controller Handle of device to stop driver on + @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of + children is zero stop the entire bus driver. + @param ChildHandleBuffer List of Child Handles to Stop. + + @retval EFI_SUCCESS This driver is removed Controller. + @retval other This driver could not be removed from this device. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverBindingStop( + EFI_DRIVER_BINDING_PROTOCOL* This, + EFI_HANDLE Controller, + UINTN NumberOfChildren, + EFI_HANDLE* ChildHandleBuffer + ); + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentNameGetDriverName( + EFI_COMPONENT_NAME_PROTOCOL* This, + CHAR8* Language, + CHAR16** DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentNameGetControllerName( + EFI_COMPONENT_NAME_PROTOCOL* This, + EFI_HANDLE ControllerHandle, + EFI_HANDLE ChildHandle, + CHAR8* Language, + CHAR16** ControllerName + ); + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentName2GetDriverName( + EFI_COMPONENT_NAME2_PROTOCOL* This, + CHAR8* Language, + CHAR16** DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +OpalEfiDriverComponentName2GetControllerName( + EFI_COMPONENT_NAME2_PROTOCOL* This, + EFI_HANDLE ControllerHandle, + EFI_HANDLE ChildHandle, + CHAR8* Language, + CHAR16** ControllerName + ); + +#endif //_OPAL_DRIVER_H_ diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h new file mode 100644 index 0000000000..19ebc32623 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h @@ -0,0 +1,102 @@ +/** @file + Private structures and functions used within OPAL_DRIVER + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef _OPAL_DRIVER_PRIVATE_H_ +#define _OPAL_DRIVER_PRIVATE_H_ +#include "OpalDriver.h" + +#define OPAL_MSID_LENGHT 128 + +#pragma pack(1) +// +// Structure that is used to represent an OPAL_DISK. +// +typedef struct { + UINT32 MsidLength; // Byte length of MSID Pin for device + UINT8 Msid[OPAL_MSID_LENGHT]; // MSID Pin for device + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp; + UINT32 MediaId; // MediaId is used by Ssc Protocol. + EFI_DEVICE_PATH_PROTOCOL *OpalDevicePath; + UINT16 OpalBaseComId; // Opal SSC 1 base com id. + OPAL_OWNER_SHIP Owner; + OPAL_DISK_SUPPORT_ATTRIBUTE SupportedAttributes; + TCG_LOCKING_FEATURE_DESCRIPTOR LockingFeature; // Locking Feature Descriptor retrieved from performing a Level 0 Discovery +} OPAL_DISK; + +// +// Device with block IO protocol +// +typedef struct _OPAL_DRIVER_DEVICE OPAL_DRIVER_DEVICE; + +struct _OPAL_DRIVER_DEVICE { + OPAL_DRIVER_DEVICE *Next; ///< Linked list pointer + EFI_HANDLE Handle; ///< Device handle + OPAL_DISK OpalDisk; ///< User context + CHAR16 *Name16; ///< Allocated/freed by UEFI Filter Driver at device creation/removal + CHAR8 *NameZ; ///< Allocated/freed by UEFI Filter Driver at device creation/removal + UINT32 MediaId; ///< Required parameter for EFI_STORAGE_SECURITY_COMMAND_PROTOCOL, from BLOCK_IO_MEDIA + + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Sscp; /// Device protocols consumed + EFI_DEVICE_PATH_PROTOCOL *OpalDevicePath; +}; + +// +// Opal Driver UEFI Driver Model +// +typedef struct { + EFI_HANDLE Handle; ///< Driver image handle + OPAL_DRIVER_DEVICE *DeviceList; ///< Linked list of controllers owned by this Driver +} OPAL_DRIVER; +#pragma pack() + +// +// Retrieves a OPAL_DRIVER_DEVICE based on the pointer to its StorageSecurity protocol. +// +#define DRIVER_DEVICE_FROM_OPALDISK(OpalDiskPointer) (OPAL_DRIVER_DEVICE*)(BASE_CR(OpalDiskPointer, OPAL_DRIVER_DEVICE, OpalDisk)) + +/** + Get devcie list info. + + @retval return the device list pointer. +**/ +OPAL_DRIVER_DEVICE* +OpalDriverGetDeviceList( + VOID + ); + +/** + Get devcie name through the component name protocol. + + @param[in] Dev The device which need to get name. + + @retval TRUE Find the name for this device. + @retval FALSE Not found the name for this device. +**/ +BOOLEAN +OpalDriverGetDriverDeviceName( + OPAL_DRIVER_DEVICE *Dev + ); + +/** + Get current device count. + + @retval return the current created device count. + +**/ +UINT8 +GetDeviceCount ( + VOID + ); + +#endif // _OPAL_DRIVER_P_H_ diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c new file mode 100644 index 0000000000..250cb438e9 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c @@ -0,0 +1,1424 @@ +/** @file + Implementation of the HII for the Opal UEFI Driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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[]; + +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 + ) +{ + EFI_STATUS Status; + OPAL_EXTRA_INFO_VAR OpalExtraInfo; + UINTN DataSize; + + gHiiConfiguration.NumDisks = GetDeviceCount(); + + DataSize = sizeof (OPAL_EXTRA_INFO_VAR); + Status = gRT->GetVariable ( + OPAL_EXTRA_INFO_VAR_NAME, + &gOpalExtraInfoVariableGuid, + NULL, + &DataSize, + &OpalExtraInfo + ); + DEBUG ((DEBUG_INFO, "GetVariable for OpalExtraInfo @ HiiSetCurrentConfiguration, Status: %r\n", Status)); + if (!EFI_ERROR (Status)) { + gHiiConfiguration.EnableBlockSid = OpalExtraInfo.EnableBlockSid; + } +} + +/** + Check that all required protocols for HII are available. + + @retval EFI_SUCCESS All required protocols are installed. + @retval EFI_NOT_FOUND One or more protocol are not installed. +**/ +EFI_STATUS +HiiCheckForRequiredProtocols ( + VOID + ) +{ + VOID* TempProtocol; + EFI_STATUS Status; + + Status = gBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID**)&TempProtocol ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&TempProtocol ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + Status = gBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**)&TempProtocol ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + Status = gBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, (VOID**)&TempProtocol ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + 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; + + // + // Check that all required protocols are available for HII. + // If not, fail the install + // + Status = HiiCheckForRequiredProtocols(); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // 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; + + if (ActionRequest != NULL) { + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + } + + // + // 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_BLOCKSID: + return HiiSetBlockSid(Value->b); + } + } else if (Action == EFI_BROWSER_ACTION_CHANGED) { + switch (HiiKeyId) { + case HII_KEY_ID_ENTER_PSID: + HiiPsidRevert(); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + return EFI_SUCCESS; + } + } + + 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; + gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_BLOCKSID; + + 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. + + @retval EFI_SUCCESS Do the required action success. + +**/ +EFI_STATUS +HiiPsidRevert( + VOID + ) +{ + CHAR8 Response[DEFAULT_RESPONSE_SIZE]; + TCG_PSID Psid; + OPAL_DISK *OpalDisk; + TCG_RESULT Ret; + OPAL_SESSION Session; + + Ret = TcgResultFailure; + + OpalHiiGetBrowserData(); + + UnicodeStrToAsciiStr(gHiiConfiguration.Psid, (CHAR8*)Psid.Psid); + + OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); + + ZeroMem(&Session, sizeof(Session)); + Session.Sscp = OpalDisk->Sscp; + Session.MediaId = OpalDisk->MediaId; + Session.OpalBaseComId = OpalDisk->OpalBaseComId; + + if (OpalDisk != NULL) { + Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath); + } + + 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; + } + PassLength = (UINT32) StrLen (UniStr); + if (PassLength >= sizeof(Password)) { + HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long"); + gBS->FreePool(UniStr); + return EFI_BUFFER_TOO_SMALL; + } + + UnicodeStrToAsciiStr(UniStr, Password); + gBS->FreePool(UniStr); + + DEBUG ((DEBUG_INFO, "Password: '%s'\n", Password)); + + 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) { + DEBUG ((DEBUG_INFO, "gHiiConfiguration.KeepUserData %u\n", gHiiConfiguration.KeepUserData)); + Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData); + } else { + Status = HiiSetPassword(OpalDisk, Password, PassLength); + } + + OpalHiiSetBrowserData (); + + return Status; +} + +/** + Update block sid info. + + @param Enable Enable/disable BlockSid. + + @retval EFI_SUCCESS Do the required action success. + @retval Others Other error occur. + +**/ +EFI_STATUS +HiiSetBlockSid ( + BOOLEAN Enable + ) +{ + EFI_STATUS Status; + OPAL_EXTRA_INFO_VAR OpalExtraInfo; + UINTN DataSize; + + Status = EFI_SUCCESS; + + DEBUG ((DEBUG_INFO, "HiiSetBlockSid(enable: %x)\n", Enable)); + + OpalExtraInfo.EnableBlockSid = Enable; + DataSize = sizeof (OPAL_EXTRA_INFO_VAR); + Status = gRT->SetVariable ( + OPAL_EXTRA_INFO_VAR_NAME, + &gOpalExtraInfoVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + DataSize, + &OpalExtraInfo + ); + DEBUG ((DEBUG_INFO, "SetVariable, Status: %r\n", Status)); + + 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 + 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 + ) +{ + DEBUG ((DEBUG_INFO, "RouteConfig( )\n")); + if (Configuration == NULL || Progress == NULL) { + return (EFI_INVALID_PARAMETER); + } + + 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 + 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 + 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; + + DEBUG ((DEBUG_INFO, "ExtractConfig( )\n")); + + // + // Check for valid parameters + // + if (Progress == NULL || Results == NULL) { + return (EFI_INVALID_PARAMETER); + } + + // + // Convert Buffer Data to 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 + ) +{ + DEBUG ((DEBUG_INFO, "OpalHiiSetBrowserData( )\n")); + HiiSetBrowserData( + &gHiiSetupVariableGuid, + (CHAR16*)L"OpalHiiConfig", + sizeof(gHiiConfiguration), + (UINT8*)&gHiiConfiguration, + NULL + ); +} + + +/** + + Populate the hii_g_Configuraton with the browser Data. + +**/ +VOID +OpalHiiGetBrowserData ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "OpalHiiGetBrowserData( )\n")); + 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; + + DEBUG ((DEBUG_INFO, "HiiSetFormString( )\n")); + + // + // 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 + // + AsciiStrToUnicodeStr( SrcAsciiStr, UniStr ); + + // + // 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; +} + diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h new file mode 100644 index 0000000000..c03f082780 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h @@ -0,0 +1,146 @@ +/** @file + Public Header file of HII library used by Opal UEFI Driver. + Defines required callbacks of Opal HII library. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef _OPAL_HII_H_ +#define _OPAL_HII_H_ + +#include +#include + +#define DEFAULT_RESPONSE_SIZE 200 + +/** + Get the driver image handle. + + @retval the driver image handle. + +**/ +EFI_HANDLE +HiiGetDriverImageHandleCB( + VOID + ); + +/** + 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 + ); + +/** + Check whether enable feature or not. + + @retval Return the disk number. + +**/ +UINT8 +HiiGetNumConfigRequiredOpalDisksCB( + VOID + ); + +/** + Returns the driver name. + + @retval Returns the driver name. + +**/ +CHAR16* +HiiGetDriverNameCB( + VOID + ); + +/** + Returns the opaque pointer to a physical disk context. + + @param DiskIndex Input the disk index. + + @retval The device pointer. + +**/ +OPAL_DISK* +HiiGetOpalDiskCB( + UINT8 DiskIndex + ); + +/** + Returns the disk name. + + @param DiskIndex Input the disk index. + + @retval Returns the disk name. + +**/ +CHAR8* +HiiDiskGetNameCB( + UINT8 DiskIndex + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +#endif // _HII_H_ diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c new file mode 100644 index 0000000000..6f2eaeb4c3 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c @@ -0,0 +1,221 @@ +/** @file + Callbacks required by the HII of the Opal UEFI Driver to help display + Opal device information and to send password to SMM handler. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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 "OpalDriverPrivate.h" + +/** + Get Opal var name. + The return Value must be freed by caller if not NULL + + @param OpalDisk The disk. + @param Prefix The prefix string. + + @retval The var name string. + +**/ +CHAR16* +OpalDriverGetOpalVarName( + OPAL_DISK *OpalDisk, + const CHAR16 *Prefix + ) +{ + OPAL_DRIVER_DEVICE* Dev; + UINTN PrefixLen; + UINTN NameLen; + UINTN VarNameLen; + CHAR16* VarName; + + Dev = DRIVER_DEVICE_FROM_OPALDISK(OpalDisk); + if (Dev == NULL) { + return NULL; + } + + PrefixLen = StrLen(Prefix); + + NameLen = 0; + if (Dev->Name16 != NULL) { + NameLen = StrLen(Dev->Name16); + } + + VarNameLen = PrefixLen + NameLen; + + VarName = (CHAR16*)AllocateZeroPool((VarNameLen + 1) * sizeof(CHAR16)); + if (VarName == NULL) { + return NULL; + } + + CopyMem(VarName, Prefix, PrefixLen * sizeof(CHAR16)); + if (Dev->Name16 != NULL) { + CopyMem(VarName + PrefixLen, Dev->Name16, NameLen * sizeof(CHAR16)); + } + VarName[VarNameLen] = 0; + + return VarName; +} + +/** + Get the driver image handle. + + @retval the driver image handle. + +**/ +EFI_HANDLE +HiiGetDriverImageHandleCB( + VOID + ) +{ + return gImageHandle; +} + +/** + Check whether enable feature or not. + + @retval Return the disk number. + +**/ +UINT8 +HiiGetNumConfigRequiredOpalDisksCB( + VOID + ) +{ + UINT8 NumDisks; + UINT8 NumLockedOpalDisks; + OPAL_DISK *OpalDisk; + UINT8 Index; + + NumLockedOpalDisks = 0; + + NumDisks = GetDeviceCount(); + + for (Index = 0; Index < NumDisks; Index++) { + OpalDisk = HiiGetOpalDiskCB(Index); + + if (OpalDisk != NULL) { + if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) { + DEBUG ((DEBUG_INFO, "Ignoring disk %u because feature is disabled or health has already been inspected\n", Index)); + } else if (OpalDeviceLocked (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) { + NumLockedOpalDisks++; + } + } + } + + return NumLockedOpalDisks; +} + + + +/** + Returns the opaque pointer to a physical disk context. + + @param DiskIndex Input the disk index. + + @retval The device pointer. + +**/ +VOID * +HiiGetDiskContextCB( + UINT8 DiskIndex + ) +{ + OPAL_DRIVER_DEVICE* Dev; + UINT8 CurrentDisk; + + Dev = OpalDriverGetDeviceList(); + CurrentDisk = 0; + + if (DiskIndex >= GetDeviceCount()) { + return NULL; + } + + while (Dev != NULL) { + if (CurrentDisk == DiskIndex) { + return Dev; + } else { + Dev = Dev->Next; + CurrentDisk++; + } + } + + return NULL; +} + +/** + Returns the opaque pointer to a physical disk context. + + @param DiskIndex Input the disk index. + + @retval The device pointer. + +**/ +OPAL_DISK* +HiiGetOpalDiskCB( + UINT8 DiskIndex + ) +{ + VOID *Ctx; + OPAL_DRIVER_DEVICE *Tmp; + + Ctx = HiiGetDiskContextCB (DiskIndex); + + if (Ctx == NULL) { + return NULL; + } + + Tmp = (OPAL_DRIVER_DEVICE*) Ctx; + + return &Tmp->OpalDisk; +} + +/** + Returns the disk name. + + @param DiskIndex Input the disk index. + + @retval Returns the disk name. + +**/ +CHAR8* +HiiDiskGetNameCB( + UINT8 DiskIndex + ) +{ + OPAL_DRIVER_DEVICE* Ctx; + + Ctx = (OPAL_DRIVER_DEVICE*) HiiGetDiskContextCB (DiskIndex); + + if (Ctx != NULL) { + if (Ctx->NameZ == NULL) { + OpalDriverGetDriverDeviceName (Ctx); + } + return Ctx->NameZ; + } + return NULL; +} + +/** + Returns the driver name. + + @retval Returns the driver name. + +**/ +CHAR16* +HiiGetDriverNameCB( + VOID + ) +{ + return (CHAR16*)EFI_DRIVER_NAME_UNICODE; +} diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni new file mode 100644 index 0000000000..754dbf776b --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni @@ -0,0 +1,91 @@ +// /** @file +// +// String definitions for Setup formset. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// 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. +// +// **/ + +/=# +///////////////////////////////// GENERIC DEFINITIONS ///////////////////////////////// +#langdef en-US "English" +#string STR_NULL #language en-US " " + +///////////////////////////////// FORM SET ///////////////////////////////// +#string STR_FORM_SET_HELP #language en-US "Manage Opal disks" + +///////////////////////////////// MULTIPLE FORMS ///////////////////////////////// +#string STR_OPAL #language en-US "Opal" +#string STR_MAIN_OPAL_VERSION #language en-US "Version 00.0.0.0000" + +///////////////////////////////// MAIN MENU FORM ///////////////////////////////// +#string STR_MAIN_PHY_DISKS_LBL #language en-US "Physical Disks:" +#string STR_MAIN_LOCKED_DISKS_LBL #language en-US "Locked Disks:" + +#string STR_MAIN_GOTO_DISK_INFO_0 #language en-US " " +#string STR_MAIN_GOTO_DISK_INFO_1 #language en-US " " +#string STR_MAIN_GOTO_DISK_INFO_2 #language en-US " " +#string STR_MAIN_GOTO_DISK_INFO_3 #language en-US " " +#string STR_MAIN_GOTO_DISK_INFO_4 #language en-US " " +#string STR_MAIN_GOTO_DISK_INFO_5 #language en-US " " + +#string STR_MAIN_GOTO_DISK_INFO_HELP #language en-US "Select to see Opal disk actions" +#string STR_MAIN_GOTO_DISK_HEALTH_HELP #language en-US "Select disk to unlock" + +#string STR_MAIN_NO_DISKS_PRESENT_LBL #language en-US "No disks connected to system" + +///////////////////////////////// DISK INFO MENU FORM ///////////////////////////////// +#string STR_DISK_INFO_SELECTED_DISK_NAME #language en-US " " + +#string STR_DISK_INFO_LOCK #language en-US "Lock" +#string STR_DISK_INFO_UNLOCK #language en-US "Unlock" +#string STR_DISK_INFO_SET_ADMIN_PSWD #language en-US "Update Drive Admin Password" +#string STR_DISK_INFO_SET_USER_PSWD #language en-US "Set Drive User Password" +#string STR_DISK_INFO_SECURE_ERASE #language en-US "Secure Erase User Data" +#string STR_DISK_INFO_PSID_REVERT #language en-US "PSID Revert to factory default" +#string STR_DISK_INFO_REVERT #language en-US "Admin Revert to factory default and Disable" +#string STR_DISK_INFO_DISABLE_USER #language en-US "Disable User" +#string STR_DISK_INFO_ENABLE_FEATURE #language en-US "Enable Feature" +#string STR_DISK_INFO_ENABLE_BLOCKSID #language en-US "Enable BlockSID" +#string STR_ENABLED #language en-US "Enabled" +#string STR_DISABLED #language en-US "Disabled" + +#string STR_DISK_INFO_GOTO_LOCK_HELP #language en-US "Lock the disk" +#string STR_DISK_INFO_GOTO_UNLOCK_HELP #language en-US "Unlock the disk" +#string STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP #language en-US "Set password for the administrator" +#string STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP #language en-US "Set password for User 1" +#string STR_DISK_INFO_GOTO_SECURE_ERASE_HELP #language en-US "Securely erase the disk" +#string STR_DISK_INFO_GOTO_PSID_REVERT_HELP #language en-US "Revert the disk to factory defaults" +#string STR_DISK_INFO_GOTO_DISABLE_USER_HELP #language en-US "Disable User" +#string STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP #language en-US "Enable Feature" +#string STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP #language en-US "Enable to send BlockSID command" + +///////////////////////////////// DISK ACTION MENU FORM ///////////////////////////////// +#string STR_DISK_ACTION_LBL #language en-US " " + +#string STR_PASSWORD_PROMPT #language en-US "Enter Password" +#string STR_PASSWORD_HELP #language en-US "Password must be between 6 and 20 characters" + +#string STR_REVERT_PROMPT #language en-US "Enter PSID" +#string STR_REVERT_HELP #language en-US "PSID is a 32 character case sensitive value" +#string STR_ACTION_STATUS #language en-US " " + +#string STR_PASSWORD_SUBMIT #language en-US "Submit Password Changes" +#string STR_PASSWORD_SUBMIT_HELP #language en-US "Submits Password Changes (new and update) after passwords have been entered" + +#string STR_GOTO_HOME #language en-US "Main Menu" +#string STR_GOTO_HOME_HELP #language en-US "Return to the main menu" + +#string STR_KEEP_USER_DATA_PROMPT #language en-US "Keep User Data" +#string STR_KEEP_USER_DATA_HELP #language en-US "Checkmark to keep user data, otherwise data will be lost" + +#string STR_OK #language en-US "OK" + diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h new file mode 100644 index 0000000000..50ad4eebcf --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h @@ -0,0 +1,120 @@ +/** @file + Defines Opal HII form ids, structures and values. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + + +#ifndef _OPAL_HII_FORM_VALUES_H_ +#define _OPAL_HII_FORM_VALUES_H_ + +// Maximum Opal password Length +#define MAX_PASSWORD_CHARACTER_LENGTH 0x14 + +// PSID Length +#define PSID_CHARACTER_LENGTH 0x20 + +// ID's for various forms that will be used by HII +#define FORMID_VALUE_MAIN_MENU 0x01 +#define FORMID_VALUE_DISK_INFO_FORM_MAIN 0x02 +#define FORMID_VALUE_DISK_ACTION_FORM 0x03 + +// Structure defining the OPAL_HII_CONFIGURATION +#pragma pack(1) +typedef struct { + UINT8 NumDisks; + UINT8 SelectedDiskIndex; + UINT8 SelectedAction; + UINT16 SelectedDiskAvailableActions; + UINT16 SupportedDisks; + UINT8 KeepUserData; + UINT16 AvailableFields; + UINT16 Password[MAX_PASSWORD_CHARACTER_LENGTH]; + UINT16 Psid[PSID_CHARACTER_LENGTH]; + UINT8 EnableBlockSid; +} OPAL_HII_CONFIGURATION; +#pragma pack() + +/* Action Flags */ +#define HII_ACTION_NONE 0x0000 +#define HII_ACTION_LOCK 0x0001 +#define HII_ACTION_UNLOCK 0x0002 +#define HII_ACTION_SET_ADMIN_PWD 0x0004 +#define HII_ACTION_SET_USER_PWD 0x0008 +#define HII_ACTION_SECURE_ERASE 0x0010 +#define HII_ACTION_PSID_REVERT 0x0020 +#define HII_ACTION_DISABLE_USER 0x0040 +#define HII_ACTION_REVERT 0x0080 +#define HII_ACTION_DISABLE_FEATURE 0x0100 +#define HII_ACTION_ENABLE_FEATURE 0x0200 +#define HII_ACTION_ENABLE_BLOCKSID 0x0400 + +/* Flags for diskActionAvailableFields */ +#define HII_FIELD_PASSWORD 0x0001 +#define HII_FIELD_PSID 0x0002 +#define HII_FIELD_KEEP_USER_DATA 0x0004 +#define HII_FIELD_KEEP_USER_DATA_FORCED 0x0008 + +/* Number of bits allocated for each part of a unique key for an HII_ITEM + * all bits together must be <= 16 (EFI_QUESTION_ID is UINT16) + * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + * | |-----------------------| |---------------------------| + * FLG INDEX ID + */ +#define HII_KEY_ID_BITS 8 +#define HII_KEY_INDEX_BITS 7 +#define HII_KEY_FLAG_BITS 1 + +#define HII_KEY_FLAG 0x8000 // bit 15 (zero based) + +/***********/ +/* Key IDs */ +/***********/ + +#define HII_KEY_ID_GOTO_MAIN_MENU 0 +#define HII_KEY_ID_GOTO_DISK_INFO 1 +#define HII_KEY_ID_GOTO_LOCK 2 +#define HII_KEY_ID_GOTO_UNLOCK 3 +#define HII_KEY_ID_GOTO_SET_ADMIN_PWD 4 +#define HII_KEY_ID_GOTO_SET_USER_PWD 5 +#define HII_KEY_ID_GOTO_SECURE_ERASE 6 +#define HII_KEY_ID_GOTO_PSID_REVERT 7 +#define HII_KEY_ID_GOTO_REVERT 8 +#define HII_KEY_ID_GOTO_DISABLE_USER 9 +#define HII_KEY_ID_GOTO_ENABLE_FEATURE 0xA //10 +#define HII_KEY_ID_GOTO_CONFIRM_TO_MAIN_MENU 0xB //11 +#define HII_KEY_ID_ENTER_PASSWORD 0xC //12 +#define HII_KEY_ID_ENTER_PSID 0xD //13 +#define HII_KEY_ID_VAR_SUPPORTED_DISKS 0xE //14 +#define HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS 0xF //15 + +#define HII_KEY_ID_BLOCKSID 0x17 //23 +#define HII_KEY_ID_MAX 0x17 //23 // !!Update each time a new ID is added!! + +#define HII_KEY_WITH_INDEX(id, index) \ + ( \ + HII_KEY_FLAG | \ + (id) | \ + ((index) << HII_KEY_ID_BITS) \ + ) + +#define HII_KEY(id) HII_KEY_WITH_INDEX(id, 0) + +#define PACKAGE_LIST_GUID { 0xf0308176, 0x9058, 0x4153, { 0x93, 0x3d, 0xda, 0x2f, 0xdc, 0xc8, 0x3e, 0x44 } } + +/* {410483CF-F4F9-4ece-848A-1958FD31CEB7} */ +#define SETUP_FORMSET_GUID { 0x410483cf, 0xf4f9, 0x4ece, { 0x84, 0x8a, 0x19, 0x58, 0xfd, 0x31, 0xce, 0xb7 } } + +// {BBF1ACD2-28D8-44ea-A291-58A237FEDF1A} +#define SETUP_VARIABLE_GUID { 0xbbf1acd2, 0x28d8, 0x44ea, { 0xa2, 0x91, 0x58, 0xa2, 0x37, 0xfe, 0xdf, 0x1a } } + +#endif //_HII_FORM_VALUES_H_ + diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h new file mode 100644 index 0000000000..366cd3813e --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h @@ -0,0 +1,266 @@ +/** @file + Private functions and sturctures used by the Opal UEFI Driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef _OPAL_HII_PRIVATE_H_ +#define _OPAL_HII_PRIVATE_H_ + + + +#include +#include + +#include "OpalHii.h" +#include "OpalHiiFormValues.h" + + +#define OPAL_PASSWORD_CONFIG_GUID \ + { \ + 0x0d510a4f, 0xa81b, 0x473f, { 0x87, 0x07, 0xb7, 0xfd, 0xfb, 0xc0, 0x45, 0xba } \ + } + +#pragma pack(1) + +typedef struct { + UINT16 Id: HII_KEY_ID_BITS; + UINT16 Index: HII_KEY_INDEX_BITS; + UINT16 Flag: HII_KEY_FLAG_BITS; +} KEY_BITS; + +typedef union { + UINT16 Raw; + KEY_BITS KeyBits; +} HII_KEY; + +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +/** +* Opal PSID Authority utilized for PSID revert +* +* The type indicates the structure of the PSID authority +*/ +typedef struct { + UINT8 Psid[32]; +} TCG_PSID; + +/** + 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 + 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 + ); + +/** + 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 + 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 + 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 + ); + +/** + 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 + ); + +/** + + Pass the current system state to the bios via the hii_G_Configuration. + +**/ +VOID +OpalHiiSetBrowserData ( + VOID + ); + +/** + + Populate the hii_g_Configuraton with the browser Data. + +**/ +VOID +OpalHiiGetBrowserData ( + VOID + ); + +/** + Draws the disk info form. + + @retval EFI_SUCCESS Draw the disk info success. + +**/ +EFI_STATUS +HiiPopulateDiskInfoForm( + VOID + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + Update block sid info. + + @param Enable Enable/disable BlockSid. + + @retval EFI_SUCCESS Do the required action success. + @retval Others Other error occur. + +**/ +EFI_STATUS +HiiSetBlockSid ( + BOOLEAN Enable + ); + +/** + Reverts the Opal disk to factory default. + + @retval EFI_SUCCESS Do the required action success. + +**/ +EFI_STATUS +HiiPsidRevert( + VOID + ); + +/** + Get disk name string id. + + @param DiskIndex The input disk index info. + + @retval The disk name string id. + +**/ +EFI_STRING_ID +GetDiskNameStringId( + UINT8 DiskIndex + ); + +/** + 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 + ); + +#pragma pack() + +#endif // _HII_P_H_ diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf new file mode 100644 index 0000000000..7da581b887 --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf @@ -0,0 +1,84 @@ +## @file +# This is a OpalPasswordDxe driver. +# +# This module is used to Management the Opal feature +# for Opal supported devices. +# +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# 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. +# +## +[Defines] + INF_VERSION = 0x00010007 + BASE_NAME = OpalPasswordDxe + FILE_GUID = E3E4048D-6C0C-43E4-AE1C-FFB579D8EF41 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = EfiDriverEntryPoint + UNLOAD_IMAGE = OpalEfiDriverUnload + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + OpalDriver.h + OpalHii.c + OpalHiiCallbacks.c + OpalDriver.c + OpalDriverPrivate.h + OpalHii.h + OpalHiiPrivate.h + OpalHiiFormValues.h + OpalPasswordForm.vfr + OpalHiiFormStrings.uni + ComponentName.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiHiiServicesLib + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + HiiLib + PrintLib + DevicePathLib + OpalPasswordSupportLib + UefiLib + TcgStorageOpalLib + +[Protocols] + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiStorageSecurityCommandProtocolGuid ## CONSUMES + gEfiComponentNameProtocolGuid ## PRODUCES + gEfiComponentName2ProtocolGuid ## PRODUCES + gEfiBlockIoProtocolGuid ## CONSUMES + gEfiSmmCommunicationProtocolGuid ## PRODUCES + gEfiPciIoProtocolGuid ## CONSUMES + gEfiDevicePathToTextProtocolGuid ## CONSUMES + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gOpalExtraInfoVariableGuid ## PRODUCES ## GUID + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /Od /GL- + +[Depex] + gEfiSmmCommunicationProtocolGuid diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr new file mode 100644 index 0000000000..9c35ec76ab --- /dev/null +++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr @@ -0,0 +1,327 @@ +/** @file + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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 "OpalHiiFormValues.h" + + +#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \ + { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } } + +formset + guid = SETUP_FORMSET_GUID, + title = STRING_TOKEN(STR_OPAL), + help = STRING_TOKEN(STR_FORM_SET_HELP), + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + // Define a Buffer Storage (EFI_IFR_VARSTORE) that will be filled + // out initially through extractConfig call + varstore OPAL_HII_CONFIGURATION, // This is the Data structure type + name = OpalHiiConfig, // Define referenced name in vfr + guid = SETUP_VARIABLE_GUID; // GUID of this Buffer storage + +form formid = FORMID_VALUE_MAIN_MENU, + title = STRING_TOKEN(STR_OPAL); + + //CONFIG_VARIABLE(HII_KEY(HII_KEY_ID_VAR_SUPPORTED_DISKS), SupportedDisks, 0x0, 0xFFFF); + suppressif TRUE; + numeric + name = SupportedDisks, + varid = OpalHiiConfig.SupportedDisks, + prompt = STRING_TOKEN(STR_NULL), + help = STRING_TOKEN(STR_NULL), + flags = INTERACTIVE, + key = 0x800E, //32782, + minimum = 0x0, + maximum = 0xFFFF, + endnumeric; + endif; + + subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION); + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_MAIN_PHY_DISKS_LBL); + + subtitle text = STRING_TOKEN(STR_NULL); + + //DISK( 0 ); + suppressif ( questionref(SupportedDisks) & ( 0x1 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8001; //32769 + endif; + + //DISK( 1 ); + suppressif ( questionref(SupportedDisks) & ( 0x2 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8101; //33025 + endif; + + //DISK( 2 ); + suppressif ( questionref(SupportedDisks) & ( 0x4 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8201; //33281 + endif; + + //DISK( 3 ); + suppressif ( questionref(SupportedDisks) & ( 0x8 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8301; // 33537 + endif; + + //DISK( 4 ); + suppressif ( questionref(SupportedDisks) & ( 0x10 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8401; // 33793 + endif; + + //DISK( 5 ); + suppressif ( questionref(SupportedDisks) & ( 0x20 ) ) == 0; + goto FORMID_VALUE_DISK_INFO_FORM_MAIN, + prompt = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5 ), + help = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP), + flags = INTERACTIVE, \ + key = 0x8501; // 34049 + endif; + + //No disks on system + suppressif ideqval OpalHiiConfig.NumDisks > 0; + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_MAIN_NO_DISKS_PRESENT_LBL); + endif; + +endform; // MAIN MENU FORM + +// +///////////////// DISK INFO FORM ///////////////// +// +form formid = FORMID_VALUE_DISK_INFO_FORM_MAIN, + title = STRING_TOKEN(STR_OPAL); + + suppressif TRUE; + numeric + name = SelectedDiskAvailableActions, + varid = OpalHiiConfig.SelectedDiskAvailableActions, + prompt = STRING_TOKEN(STR_NULL), + help = STRING_TOKEN(STR_NULL), + flags = INTERACTIVE, + key = 0x800F, // 32783 + minimum = 0x0, + maximum = 0xFFFF, + endnumeric; + endif; + + subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION); + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME); + + subtitle text = STRING_TOKEN(STR_NULL); + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_LOCK ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_LOCK), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_LOCK_HELP), + flags = INTERACTIVE, + key = 0x8002; // 32770 + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_UNLOCK ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_UNLOCK), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_UNLOCK_HELP), + flags = INTERACTIVE, + key = 0x8003; //32771; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_ADMIN_PWD ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_SET_ADMIN_PSWD), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP), + flags = INTERACTIVE, + key = 0x8004; //32772; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_USER_PWD ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_SET_USER_PSWD), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP), + flags = INTERACTIVE, + key = 0x8005; //32773; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SECURE_ERASE ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_SECURE_ERASE), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_SECURE_ERASE_HELP), + flags = INTERACTIVE, + key = 0x8006; //32774; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_REVERT ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_REVERT), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP), + flags = INTERACTIVE, + key = 0x8008; //32776; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_PSID_REVERT ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP), + flags = INTERACTIVE, + key = 0x8007; //32775; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_DISABLE_USER ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_DISABLE_USER), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_DISABLE_USER_HELP), + flags = INTERACTIVE, + key = 0x8009; //32777; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_ENABLE_FEATURE ) == 0; + goto FORMID_VALUE_DISK_ACTION_FORM, + prompt = STRING_TOKEN(STR_DISK_INFO_ENABLE_FEATURE), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP), + flags = INTERACTIVE, + key = 0x800A; //32778; + endif; + + suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_ENABLE_BLOCKSID ) == 0; + oneof varid = OpalHiiConfig.EnableBlockSid, + questionid = 0x8017, // 32791, + prompt = STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID), + help = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED; + option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED; + endoneof; + endif; + +endform; // DISK INFO FORM + +// +///////////////// DISK ACTION FORM ///////////////// +// +form formid = FORMID_VALUE_DISK_ACTION_FORM, + title = STRING_TOKEN(STR_OPAL); + + suppressif TRUE; + numeric + name = AvailableFields, + varid = OpalHiiConfig.AvailableFields, + prompt = STRING_TOKEN(STR_NULL), + help = STRING_TOKEN(STR_NULL), + flags = INTERACTIVE, + key = 0x8012, //32786, + minimum = 0x0, + maximum = 0xFFFF, + endnumeric; + endif; + + subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION); + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME); + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_DISK_ACTION_LBL); + + subtitle text = STRING_TOKEN(STR_NULL); + + suppressif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA) == 0; + grayoutif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA_FORCED) != 0; + checkbox + name = MyCheckbox, + varid = OpalHiiConfig.KeepUserData, + prompt = STRING_TOKEN(STR_KEEP_USER_DATA_PROMPT), + help = STRING_TOKEN(STR_KEEP_USER_DATA_HELP), + key = 0x8011, //32785, + endcheckbox; + + //EMPTY_LINE; + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_NULL); + endif; + endif; + + suppressif (questionref(AvailableFields) & HII_FIELD_PASSWORD) == 0; + password + varid = OpalHiiConfig.Password, + prompt = STRING_TOKEN(STR_PASSWORD_PROMPT), + help = STRING_TOKEN(STR_PASSWORD_HELP), + flags = INTERACTIVE, + key = 0x800C, //32780, + minsize = 6, + maxsize = 20, + endpassword; + endif; + + suppressif (questionref(AvailableFields) & HII_FIELD_PSID) == 0; + string + varid = OpalHiiConfig.Psid, + prompt = STRING_TOKEN(STR_REVERT_PROMPT), + help = STRING_TOKEN(STR_REVERT_HELP), + flags = INTERACTIVE, + key = 0x800D, //32781, + minsize = PSID_CHARACTER_LENGTH, + maxsize = PSID_CHARACTER_LENGTH, + endstring; + endif; + + subtitle text = STRING_TOKEN(STR_NULL); + + text + help = STRING_TOKEN(STR_NULL), + text = STRING_TOKEN(STR_ACTION_STATUS); + + subtitle text = STRING_TOKEN(STR_NULL); + + goto FORMID_VALUE_MAIN_MENU, + prompt = STRING_TOKEN(STR_GOTO_HOME), + help = STRING_TOKEN(STR_GOTO_HOME_HELP), + flags = INTERACTIVE, + key = 0x8000; //32768; + +endform; // DISK ACTION FORM + +endformset;