X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=SecurityPkg%2FTcg%2FOpal%2FOpalPassword%2FOpalDriver.c;h=e14fa32354ea09c7665e661c95ba0dcbe48e7c63;hp=1b55bbe4ecb840f12c32cd2002cfe42b753e087b;hb=6cbed0e36fe734f3fc11d30d652122d7714627c4;hpb=fbe1328a51136538ec985ce7b9ef7cf97ba999e9 diff --git a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c index 1b55bbe4ec..e14fa32354 100644 --- a/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c +++ b/SecurityPkg/Tcg/Opal/OpalPassword/OpalDriver.c @@ -2,14 +2,8 @@ Entrypoint of Opal UEFI Driver and contains all the logic to register for new Opal device instances. -Copyright (c) 2016 - 2018, 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. +Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -21,39 +15,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "OpalDriver.h" #include "OpalHii.h" -EFI_GUID mOpalDeviceAtaGuid = OPAL_DEVICE_ATA_GUID; -EFI_GUID mOpalDeviceNvmeGuid = OPAL_DEVICE_NVME_GUID; +EFI_GUID mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID; BOOLEAN mOpalEndOfDxe = FALSE; OPAL_REQUEST_VARIABLE *mOpalRequestVariable = NULL; UINTN mOpalRequestVariableSize = 0; -CHAR16 mPopUpString[256]; - -typedef struct { - UINT32 Address; - S3_BOOT_SCRIPT_LIB_WIDTH Width; -} OPAL_HC_PCI_REGISTER_SAVE; - -// -// To unlock the Intel SATA controller at S3 Resume, restored the following registers. -// -const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] = { - {0x9, S3BootScriptWidthUint8}, - {0x10, S3BootScriptWidthUint32}, - {0x14, S3BootScriptWidthUint32}, - {0x18, S3BootScriptWidthUint32}, - {0x1C, S3BootScriptWidthUint32}, - {0x20, S3BootScriptWidthUint32}, - {0x24, S3BootScriptWidthUint32}, - {0x3c, S3BootScriptWidthUint8}, - {0x3d, S3BootScriptWidthUint8}, - {0x40, S3BootScriptWidthUint16}, - {0x42, S3BootScriptWidthUint16}, - {0x92, S3BootScriptWidthUint16}, - {0x94, S3BootScriptWidthUint32}, - {0x9C, S3BootScriptWidthUint32}, - {0x4, S3BootScriptWidthUint16}, -}; +CHAR16 mPopUpString[100]; OPAL_DRIVER mOpalDriver; @@ -105,13 +72,12 @@ OpalSupportGetAvailableActions( } // - // Psid revert is available for any device with media encryption support - // Revert is allowed for any device with media encryption support, however it requires + // Psid revert is available for any device with media encryption support or pyrite 2.0 type support. // - if (SupportedAttributes->MediaEncryption) { + if (SupportedAttributes->PyriteSscV2 || SupportedAttributes->MediaEncryption) { // - // Only allow psid revert if media encryption is enabled. + // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support.. // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still // intact and accessible // @@ -234,14 +200,12 @@ OpalSupportUpdatePassword ( @param[out] DevInfoLength Device information length needed. @param[out] DevInfo Device information extracted. - @return Device type. - **/ -UINT8 +VOID ExtractDeviceInfoFromDevicePath ( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT16 *DevInfoLength, - OUT OPAL_DEVICE_COMMON *DevInfo OPTIONAL + OUT UINT32 *DevInfoLength, + OUT OPAL_DEVICE_LOCKBOX_DATA *DevInfo OPTIONAL ) { EFI_DEVICE_PATH_PROTOCOL *TmpDevPath; @@ -250,10 +214,6 @@ ExtractDeviceInfoFromDevicePath ( UINT8 DeviceType; UINT8 BusNum; OPAL_PCI_DEVICE *PciDevice; - OPAL_DEVICE_ATA *DevInfoAta; - OPAL_DEVICE_NVME *DevInfoNvme; - SATA_DEVICE_PATH *SataDevPath; - NVME_NAMESPACE_DEVICE_PATH *NvmeDevPath; ASSERT (DevicePath != NULL); ASSERT (DevInfoLength != NULL); @@ -267,30 +227,15 @@ ExtractDeviceInfoFromDevicePath ( // Get device type. // while (!IsDevicePathEnd (TmpDevPath)) { - if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_SATA_DP) { - // - // SATA - // + if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) && + (TmpDevPath->SubType == MSG_SATA_DP || TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)) { if (DevInfo != NULL) { - SataDevPath = (SATA_DEVICE_PATH *) TmpDevPath; - DevInfoAta = (OPAL_DEVICE_ATA *) DevInfo; - DevInfoAta->Port = SataDevPath->HBAPortNumber; - DevInfoAta->PortMultiplierPort = SataDevPath->PortMultiplierPortNumber; + DevInfo->DevicePathLength = (UINT32) GetDevicePathSize (DevicePath); + CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength); } - DeviceType = OPAL_DEVICE_TYPE_ATA; - *DevInfoLength = sizeof (OPAL_DEVICE_ATA); - break; - } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) { - // - // NVMe - // - if (DevInfo != NULL) { - NvmeDevPath = (NVME_NAMESPACE_DEVICE_PATH *) TmpDevPath; - DevInfoNvme = (OPAL_DEVICE_NVME *) DevInfo; - DevInfoNvme->NvmeNamespaceId = NvmeDevPath->NamespaceId; - } - DeviceType = OPAL_DEVICE_TYPE_NVME; - *DevInfoLength = sizeof (OPAL_DEVICE_NVME); + + DeviceType = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME; + *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32) GetDevicePathSize (DevicePath); break; } TmpDevPath = NextDevicePathNode (TmpDevPath); @@ -305,8 +250,8 @@ ExtractDeviceInfoFromDevicePath ( while (!IsDevicePathEnd (TmpDevPath2)) { if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) { PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath; - if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)|| - (TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_SATA_DP)) { + if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) && + (TmpDevPath2->SubType == MSG_SATA_DP || TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)) { if (DevInfo != NULL) { PciDevice = &DevInfo->Device; PciDevice->Segment = 0; @@ -315,14 +260,6 @@ ExtractDeviceInfoFromDevicePath ( PciDevice->Function = PciDevPath->Function; } } else { - if (DevInfo != NULL) { - PciDevice = (OPAL_PCI_DEVICE *) ((UINTN) DevInfo + *DevInfoLength); - PciDevice->Segment = 0; - PciDevice->Bus = BusNum; - PciDevice->Device = PciDevPath->Device; - PciDevice->Function = PciDevPath->Function; - } - *DevInfoLength += sizeof (OPAL_PCI_DEVICE); if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) { BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); } @@ -334,245 +271,203 @@ ExtractDeviceInfoFromDevicePath ( } ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN); - return DeviceType; -} - -/** - Save boot script for ATA OPAL device. - - @param[in] DevInfo Pointer to ATA Opal device information. - - **/ -VOID -OpalDeviceAtaSaveBootScript ( - IN OPAL_DEVICE_ATA *DevInfo - ) -{ - UINTN Bus; - UINTN Device; - UINTN Function; - UINTN Index; - EFI_STATUS Status; - UINTN Offset; - UINT64 Address; - S3_BOOT_SCRIPT_LIB_WIDTH Width; - UINT32 Data; - OPAL_HC_PCI_REGISTER_SAVE *HcRegisterSaveListPtr; - UINTN Count; - - Data = 0; - - Bus = DevInfo->Device.Bus; - Device = DevInfo->Device.Device; - Function = DevInfo->Device.Function; - - HcRegisterSaveListPtr = (OPAL_HC_PCI_REGISTER_SAVE *) mSataHcRegisterSaveTemplate; - Count = sizeof (mSataHcRegisterSaveTemplate) / sizeof (OPAL_HC_PCI_REGISTER_SAVE); - - for (Index = 0; Index < Count; Index++) { - Offset = HcRegisterSaveListPtr[Index].Address; - Width = HcRegisterSaveListPtr[Index].Width; - - switch (Width) { - case S3BootScriptWidthUint8: - Data = (UINT32)PciRead8 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset)); - break; - case S3BootScriptWidthUint16: - Data = (UINT32)PciRead16 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset)); - break; - case S3BootScriptWidthUint32: - Data = PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset)); - break; - default: - ASSERT (FALSE); - break; - } - - Address = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function, Offset); - Status = S3BootScriptSavePciCfgWrite (Width, Address, 1, &Data); - ASSERT_EFI_ERROR (Status); - } + return; } /** - Build ATA OPAL device info and save them to LockBox. - - @param[in] BarAddr Bar address allocated. + Build OPAL device info and save them to LockBox. **/ VOID -BuildOpalDeviceInfoAta ( - IN UINT32 BarAddr +BuildOpalDeviceInfo ( + VOID ) { - EFI_STATUS Status; - UINT8 DeviceType; - OPAL_DEVICE_ATA *DevInfoAta; - OPAL_DEVICE_ATA *TempDevInfoAta; - UINTN DevInfoLengthAta; - UINT16 DevInfoLength; - OPAL_DRIVER_DEVICE *TmpDev; + EFI_STATUS Status; + OPAL_DEVICE_LOCKBOX_DATA *DevInfo; + OPAL_DEVICE_LOCKBOX_DATA *TempDevInfo; + UINTN TotalDevInfoLength; + UINT32 DevInfoLength; + OPAL_DRIVER_DEVICE *TmpDev; + UINT8 DummyData; + BOOLEAN S3InitDevicesExist; + UINTN S3InitDevicesLength; + EFI_DEVICE_PATH_PROTOCOL *S3InitDevices; + EFI_DEVICE_PATH_PROTOCOL *S3InitDevicesBak; // - // Build ATA OPAL device info and save them to LockBox. + // Build OPAL device info and save them to LockBox. // - DevInfoLengthAta = 0; + TotalDevInfoLength = 0; TmpDev = mOpalDriver.DeviceList; while (TmpDev != NULL) { - DeviceType = ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - NULL - ); - if (DeviceType == OPAL_DEVICE_TYPE_ATA) { - DevInfoLengthAta += DevInfoLength; - } - + ExtractDeviceInfoFromDevicePath ( + TmpDev->OpalDisk.OpalDevicePath, + &DevInfoLength, + NULL + ); + TotalDevInfoLength += DevInfoLength; TmpDev = TmpDev->Next; } - if (DevInfoLengthAta == 0) { + if (TotalDevInfoLength == 0) { return; } - DevInfoAta = AllocateZeroPool (DevInfoLengthAta); - ASSERT (DevInfoAta != NULL); + S3InitDevicesLength = sizeof (DummyData); + Status = RestoreLockBox ( + &gS3StorageDeviceInitListGuid, + &DummyData, + &S3InitDevicesLength + ); + ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL)); + if (Status == EFI_NOT_FOUND) { + S3InitDevices = NULL; + S3InitDevicesExist = FALSE; + } else if (Status == EFI_BUFFER_TOO_SMALL) { + S3InitDevices = AllocatePool (S3InitDevicesLength); + ASSERT (S3InitDevices != NULL); + if (S3InitDevices == NULL) { + return; + } - TempDevInfoAta = DevInfoAta; - TmpDev = mOpalDriver.DeviceList; + Status = RestoreLockBox ( + &gS3StorageDeviceInitListGuid, + S3InitDevices, + &S3InitDevicesLength + ); + ASSERT_EFI_ERROR (Status); + S3InitDevicesExist = TRUE; + } else { + return; + } + + DevInfo = AllocateZeroPool (TotalDevInfoLength); + ASSERT (DevInfo != NULL); + if (DevInfo == NULL) { + return; + } + + TempDevInfo = DevInfo; + TmpDev = mOpalDriver.DeviceList; while (TmpDev != NULL) { - DeviceType = ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - NULL - ); - if (DeviceType == OPAL_DEVICE_TYPE_ATA) { - ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - (OPAL_DEVICE_COMMON *) TempDevInfoAta - ); - TempDevInfoAta->Length = DevInfoLength; - TempDevInfoAta->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId; - TempDevInfoAta->BarAddr = BarAddr; - CopyMem ( - TempDevInfoAta->Password, - TmpDev->OpalDisk.Password, - TmpDev->OpalDisk.PasswordLength - ); - TempDevInfoAta->PasswordLength = TmpDev->OpalDisk.PasswordLength; - OpalDeviceAtaSaveBootScript (TempDevInfoAta); - TempDevInfoAta = (OPAL_DEVICE_ATA *) ((UINTN) TempDevInfoAta + DevInfoLength); + ExtractDeviceInfoFromDevicePath ( + TmpDev->OpalDisk.OpalDevicePath, + &DevInfoLength, + TempDevInfo + ); + TempDevInfo->Length = DevInfoLength; + TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId; + CopyMem ( + TempDevInfo->Password, + TmpDev->OpalDisk.Password, + TmpDev->OpalDisk.PasswordLength + ); + TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength; + + S3InitDevicesBak = S3InitDevices; + S3InitDevices = AppendDevicePathInstance ( + S3InitDevicesBak, + TmpDev->OpalDisk.OpalDevicePath + ); + if (S3InitDevicesBak != NULL) { + FreePool (S3InitDevicesBak); + } + ASSERT (S3InitDevices != NULL); + if (S3InitDevices == NULL) { + return; } + TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *) ((UINTN) TempDevInfo + DevInfoLength); TmpDev = TmpDev->Next; } Status = SaveLockBox ( - &mOpalDeviceAtaGuid, - DevInfoAta, - DevInfoLengthAta + &mOpalDeviceLockBoxGuid, + DevInfo, + TotalDevInfoLength ); ASSERT_EFI_ERROR (Status); Status = SetLockBoxAttributes ( - &mOpalDeviceAtaGuid, + &mOpalDeviceLockBoxGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY ); ASSERT_EFI_ERROR (Status); - ZeroMem (DevInfoAta, DevInfoLengthAta); - FreePool (DevInfoAta); + S3InitDevicesLength = GetDevicePathSize (S3InitDevices); + if (S3InitDevicesExist) { + Status = UpdateLockBox ( + &gS3StorageDeviceInitListGuid, + 0, + S3InitDevices, + S3InitDevicesLength + ); + ASSERT_EFI_ERROR (Status); + } else { + Status = SaveLockBox ( + &gS3StorageDeviceInitListGuid, + S3InitDevices, + S3InitDevicesLength + ); + ASSERT_EFI_ERROR (Status); + + Status = SetLockBoxAttributes ( + &gS3StorageDeviceInitListGuid, + LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY + ); + ASSERT_EFI_ERROR (Status); + } + + ZeroMem (DevInfo, TotalDevInfoLength); + FreePool (DevInfo); + FreePool (S3InitDevices); } /** - Build NVMe OPAL device info and save them to LockBox. - @param[in] BarAddr Bar address allocated. + Send BlockSid command if needed. - **/ +**/ VOID -BuildOpalDeviceInfoNvme ( - IN UINT32 BarAddr +SendBlockSidCommand ( + VOID ) { - EFI_STATUS Status; - UINT8 DeviceType; - OPAL_DEVICE_NVME *DevInfoNvme; - OPAL_DEVICE_NVME *TempDevInfoNvme; - UINTN DevInfoLengthNvme; - UINT16 DevInfoLength; - OPAL_DRIVER_DEVICE *TmpDev; - - // - // Build NVMe OPAL device info and save them to LockBox. - // - DevInfoLengthNvme = 0; - TmpDev = mOpalDriver.DeviceList; - while (TmpDev != NULL) { - DeviceType = ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - NULL - ); - if (DeviceType == OPAL_DEVICE_TYPE_NVME) { - DevInfoLengthNvme += DevInfoLength; - } + OPAL_DRIVER_DEVICE *Itr; + TCG_RESULT Result; + OPAL_SESSION Session; + UINT32 PpStorageFlag; - TmpDev = TmpDev->Next; - } + PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags (); + if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) { + // + // Send BlockSID command to each Opal disk + // + Itr = mOpalDriver.DeviceList; + while (Itr != NULL) { + if (Itr->OpalDisk.SupportedAttributes.BlockSid) { + ZeroMem(&Session, sizeof(Session)); + Session.Sscp = Itr->OpalDisk.Sscp; + Session.MediaId = Itr->OpalDisk.MediaId; + Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId; - if (DevInfoLengthNvme == 0) { - return; - } + DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n")); + Result = OpalBlockSid (&Session, TRUE); // HardwareReset must always be TRUE + if (Result != TcgResultSuccess) { + DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n")); + break; + } - DevInfoNvme = AllocateZeroPool (DevInfoLengthNvme); - ASSERT (DevInfoNvme != NULL); + // + // Record BlockSID command has been sent. + // + Itr->OpalDisk.SentBlockSID = TRUE; + } - TempDevInfoNvme = DevInfoNvme; - TmpDev = mOpalDriver.DeviceList; - while (TmpDev != NULL) { - DeviceType = ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - NULL - ); - if (DeviceType == OPAL_DEVICE_TYPE_NVME) { - ExtractDeviceInfoFromDevicePath ( - TmpDev->OpalDisk.OpalDevicePath, - &DevInfoLength, - (OPAL_DEVICE_COMMON *) TempDevInfoNvme - ); - TempDevInfoNvme->Length = DevInfoLength; - TempDevInfoNvme->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId; - TempDevInfoNvme->BarAddr = BarAddr; - CopyMem ( - TempDevInfoNvme->Password, - TmpDev->OpalDisk.Password, - TmpDev->OpalDisk.PasswordLength - ); - TempDevInfoNvme->PasswordLength = TmpDev->OpalDisk.PasswordLength; - TempDevInfoNvme = (OPAL_DEVICE_NVME *) ((UINTN) TempDevInfoNvme + DevInfoLength); + Itr = Itr->Next; } - - TmpDev = TmpDev->Next; } - - Status = SaveLockBox ( - &mOpalDeviceNvmeGuid, - DevInfoNvme, - DevInfoLengthNvme - ); - ASSERT_EFI_ERROR (Status); - - Status = SetLockBoxAttributes ( - &mOpalDeviceNvmeGuid, - LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY - ); - ASSERT_EFI_ERROR (Status); - - ZeroMem (DevInfoNvme, DevInfoLengthNvme); - FreePool (DevInfoNvme); } /** @@ -591,9 +486,6 @@ OpalEndOfDxeEventNotify ( VOID *Context ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; - UINT64 Length; OPAL_DRIVER_DEVICE *TmpDev; DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); @@ -618,24 +510,7 @@ OpalEndOfDxeEventNotify ( return; } - // - // Assume 64K size and alignment are enough. - // - Length = 0x10000; - Address = 0xFFFFFFFF; - Status = gDS->AllocateMemorySpace ( - EfiGcdAllocateMaxAddressSearchBottomUp, - EfiGcdMemoryTypeMemoryMappedIo, - 16, // 2^16: 64K Alignment - Length, - &Address, - gImageHandle, - NULL - ); - ASSERT_EFI_ERROR (Status); - - BuildOpalDeviceInfoAta ((UINT32) Address); - BuildOpalDeviceInfoNvme ((UINT32) Address); + BuildOpalDeviceInfo (); // // Zero passsword. @@ -646,6 +521,11 @@ OpalEndOfDxeEventNotify ( TmpDev = TmpDev->Next; } + // + // Send BlockSid command if needed. + // + SendBlockSidCommand (); + DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); gBS->CloseEvent (Event); @@ -657,15 +537,20 @@ OpalEndOfDxeEventNotify ( @param[in] Dev The device which need Psid to process Psid Revert OPAL request. @param[in] PopUpString Pop up string. + @param[in] PopUpString2 Pop up string in line 2. + @param[in] PopUpString3 Pop up string in line 3. + @param[out] PressEsc Whether user escape function through Press ESC. - @retval Password string if success. NULL if failed. + @retval Psid string if success. NULL if failed. **/ CHAR8 * OpalDriverPopUpPsidInput ( IN OPAL_DRIVER_DEVICE *Dev, IN CHAR16 *PopUpString, + IN CHAR16 *PopUpString2, + IN CHAR16 *PopUpString3, OUT BOOLEAN *PressEsc ) { @@ -685,14 +570,39 @@ OpalDriverPopUpPsidInput ( InputLength = 0; while (TRUE) { Mask[InputLength] = L'_'; - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &InputKey, - PopUpString, - L"---------------------", - Mask, - NULL - ); + if (PopUpString2 == NULL) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + L"---------------------", + Mask, + NULL + ); + } else { + if (PopUpString3 == NULL) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + PopUpString2, + L"---------------------", + Mask, + NULL + ); + } else { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString, + PopUpString2, + PopUpString3, + L"---------------------", + Mask, + NULL + ); + } + } // // Check key. @@ -781,6 +691,7 @@ OpalDriverPopUpPsidInput ( process OPAL request. @param[in] PopUpString1 Pop up string 1. @param[in] PopUpString2 Pop up string 2. + @param[in] PopUpString3 Pop up string 3. @param[out] PressEsc Whether user escape function through Press ESC. @retval Password string if success. NULL if failed. @@ -791,6 +702,7 @@ OpalDriverPopUpPasswordInput ( IN OPAL_DRIVER_DEVICE *Dev, IN CHAR16 *PopUpString1, IN CHAR16 *PopUpString2, + IN CHAR16 *PopUpString3, OUT BOOLEAN *PressEsc ) { @@ -820,15 +732,28 @@ OpalDriverPopUpPasswordInput ( NULL ); } else { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &InputKey, - PopUpString1, - PopUpString2, - L"---------------------", - Mask, - NULL - ); + if (PopUpString3 == NULL) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString1, + PopUpString2, + L"---------------------", + Mask, + NULL + ); + } else { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &InputKey, + PopUpString1, + PopUpString2, + PopUpString3, + L"---------------------", + Mask, + NULL + ); + } } // @@ -908,11 +833,13 @@ OpalDriverPopUpPasswordInput ( } /** - Check if disk is locked, show popup window and ask for password if it is. + Get pop up string. - @param[in] Dev The device which need to be unlocked. + @param[in] Dev The OPAL device. @param[in] RequestString Request string. + @return Pop up string. + **/ CHAR16 * OpalGetPopUpString ( @@ -920,15 +847,10 @@ OpalGetPopUpString ( IN CHAR16 *RequestString ) { - UINTN StrLength; - - StrLength = StrLen (RequestString) + 1 + MAX (StrLen (Dev->Name16), StrLen (L"Disk")); - ASSERT (StrLength < sizeof (mPopUpString) / sizeof (CHAR16)); - if (Dev->Name16 == NULL) { - UnicodeSPrint (mPopUpString, StrLength + 1, L"%s Disk", RequestString); + UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s Disk", RequestString); } else { - UnicodeSPrint (mPopUpString, StrLength + 1, L"%s %s", RequestString, Dev->Name16); + UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s %s", RequestString, Dev->Name16); } return mPopUpString; @@ -977,8 +899,24 @@ OpalDriverRequestPassword ( IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature); + // + // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt. + // Due to board design, device may not power off during system warm boot, which result in + // security status remain unlocked status, hence we add device security status check here. + // + // If device is in the locked status, device keeps locked and system continues booting. + // If device is in the unlocked status, system is forced shutdown to support security requirement. + // + if (PcdGetBool (PcdSkipOpalPasswordPrompt)) { + if (IsLocked) { + return; + } else { + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + } + while (Count < MAX_PASSWORD_TRY_COUNT) { - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc); if (PressEsc) { if (IsLocked) { // @@ -1065,6 +1003,15 @@ OpalDriverRequestPassword ( break; } + // + // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown + // before accept new password. + // + if (Ret == TcgResultFailureInvalidType) { + Count = MAX_PASSWORD_TRY_COUNT; + break; + } + Count++; do { @@ -1134,7 +1081,7 @@ ProcessOpalRequestEnableFeature ( Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; while (Count < MAX_PASSWORD_TRY_COUNT) { - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1163,7 +1110,7 @@ ProcessOpalRequestEnableFeature ( } PasswordLen = (UINT32) AsciiStrLen(Password); - PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc); + PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc); if (PasswordConfirm == NULL) { ZeroMem (Password, PasswordLen); FreePool (Password); @@ -1278,7 +1225,7 @@ ProcessOpalRequestDisableUser ( Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; while (Count < MAX_PASSWORD_TRY_COUNT) { - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1372,6 +1319,9 @@ ProcessOpalRequestPsidRevert ( EFI_INPUT_KEY Key; TCG_RESULT Ret; CHAR16 *PopUpString; + CHAR16 *PopUpString2; + CHAR16 *PopUpString3; + UINTN BufferSize; if (Dev == NULL) { return; @@ -1381,6 +1331,22 @@ ProcessOpalRequestPsidRevert ( PopUpString = OpalGetPopUpString (Dev, RequestString); + if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) { + BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds"); + PopUpString2 = AllocateZeroPool (BufferSize); + ASSERT (PopUpString2 != NULL); + UnicodeSPrint ( + PopUpString2, + BufferSize, + L"WARNING: Revert action will take about %d seconds", + Dev->OpalDisk.EstimateTimeCost + ); + PopUpString3 = L"DO NOT power off system during the revert action!"; + } else { + PopUpString2 = NULL; + PopUpString3 = NULL; + } + Count = 0; ZeroMem(&Session, sizeof(Session)); @@ -1389,7 +1355,7 @@ ProcessOpalRequestPsidRevert ( Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; while (Count < MAX_PSID_TRY_COUNT) { - Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, &PressEsc); + Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1403,7 +1369,7 @@ ProcessOpalRequestPsidRevert ( if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gST->ConOut->ClearScreen(gST->ConOut); - return; + goto Done; } else { // // Let user input Psid again. @@ -1459,6 +1425,11 @@ ProcessOpalRequestPsidRevert ( } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gST->ConOut->ClearScreen(gST->ConOut); } + +Done: + if (PopUpString2 != NULL) { + FreePool (PopUpString2); + } } /** @@ -1485,6 +1456,9 @@ ProcessOpalRequestRevert ( TCG_RESULT Ret; BOOLEAN PasswordFailed; CHAR16 *PopUpString; + CHAR16 *PopUpString2; + CHAR16 *PopUpString3; + UINTN BufferSize; if (Dev == NULL) { return; @@ -1494,6 +1468,23 @@ ProcessOpalRequestRevert ( PopUpString = OpalGetPopUpString (Dev, RequestString); + if ((!KeepUserData) && + (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME)) { + BufferSize = StrSize (L"Warning: Revert action will take about ####### seconds"); + PopUpString2 = AllocateZeroPool (BufferSize); + ASSERT (PopUpString2 != NULL); + UnicodeSPrint ( + PopUpString2, + BufferSize, + L"WARNING: Revert action will take about %d seconds", + Dev->OpalDisk.EstimateTimeCost + ); + PopUpString3 = L"DO NOT power off system during the revert action!"; + } else { + PopUpString2 = NULL; + PopUpString3 = NULL; + } + Count = 0; ZeroMem(&Session, sizeof(Session)); @@ -1502,7 +1493,7 @@ ProcessOpalRequestRevert ( Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; while (Count < MAX_PASSWORD_TRY_COUNT) { - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1516,7 +1507,7 @@ ProcessOpalRequestRevert ( if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gST->ConOut->ClearScreen(gST->ConOut); - return; + goto Done; } else { // // Let user input password again. @@ -1599,6 +1590,11 @@ ProcessOpalRequestRevert ( } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gST->ConOut->ClearScreen(gST->ConOut); } + +Done: + if (PopUpString2 != NULL) { + FreePool (PopUpString2); + } } /** @@ -1623,6 +1619,9 @@ ProcessOpalRequestSecureErase ( TCG_RESULT Ret; BOOLEAN PasswordFailed; CHAR16 *PopUpString; + CHAR16 *PopUpString2; + CHAR16 *PopUpString3; + UINTN BufferSize; if (Dev == NULL) { return; @@ -1632,6 +1631,21 @@ ProcessOpalRequestSecureErase ( PopUpString = OpalGetPopUpString (Dev, RequestString); + if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) { + BufferSize = StrSize (L"Warning: Secure erase action will take about ####### seconds"); + PopUpString2 = AllocateZeroPool (BufferSize); + ASSERT (PopUpString2 != NULL); + UnicodeSPrint ( + PopUpString2, + BufferSize, + L"WARNING: Secure erase action will take about %d seconds", + Dev->OpalDisk.EstimateTimeCost + ); + PopUpString3 = L"DO NOT power off system during the action!"; + } else { + PopUpString2 = NULL; + PopUpString3 = NULL; + } Count = 0; ZeroMem(&Session, sizeof(Session)); @@ -1640,7 +1654,7 @@ ProcessOpalRequestSecureErase ( Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId; while (Count < MAX_PASSWORD_TRY_COUNT) { - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1654,7 +1668,7 @@ ProcessOpalRequestSecureErase ( if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { gST->ConOut->ClearScreen(gST->ConOut); - return; + goto Done; } else { // // Let user input password again. @@ -1711,6 +1725,11 @@ ProcessOpalRequestSecureErase ( } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); gST->ConOut->ClearScreen(gST->ConOut); } + +Done: + if (PopUpString2 != NULL) { + FreePool (PopUpString2); + } } /** @@ -1750,7 +1769,7 @@ ProcessOpalRequestSetUserPwd ( Count = 0; while (Count < MAX_PASSWORD_TRY_COUNT) { - OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc); + OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -1808,7 +1827,7 @@ ProcessOpalRequestSetUserPwd ( } } - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc); if (Password == NULL) { ZeroMem (OldPassword, OldPasswordLen); FreePool (OldPassword); @@ -1817,7 +1836,7 @@ ProcessOpalRequestSetUserPwd ( } PasswordLen = (UINT32) AsciiStrLen(Password); - PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc); + PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc); if (PasswordConfirm == NULL) { ZeroMem (OldPassword, OldPasswordLen); FreePool (OldPassword); @@ -1949,7 +1968,7 @@ ProcessOpalRequestSetAdminPwd ( Count = 0; while (Count < MAX_PASSWORD_TRY_COUNT) { - OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", &PressEsc); + OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc); if (PressEsc) { do { CreatePopUp ( @@ -2002,7 +2021,7 @@ ProcessOpalRequestSetAdminPwd ( continue; } - Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", &PressEsc); + Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc); if (Password == NULL) { ZeroMem (OldPassword, OldPasswordLen); FreePool (OldPassword); @@ -2011,7 +2030,7 @@ ProcessOpalRequestSetAdminPwd ( } PasswordLen = (UINT32) AsciiStrLen(Password); - PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", &PressEsc); + PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc); if (PasswordConfirm == NULL) { ZeroMem (OldPassword, OldPasswordLen); FreePool (OldPassword); @@ -2202,6 +2221,12 @@ ProcessOpalRequest ( ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:"); } + // + // Update Device ownership. + // Later BlockSID command may block the update. + // + OpalDiskUpdateOwnerShip (&Dev->OpalDisk); + break; } @@ -2306,52 +2331,6 @@ OpalDriverGetDeviceList( return mOpalDriver.DeviceList; } -/** - ReadyToBoot callback to send BlockSid command. - - @param Event Pointer to this event - @param Context Event handler private Data - -**/ -VOID -EFIAPI -ReadyToBootCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - OPAL_DRIVER_DEVICE *Itr; - TCG_RESULT Result; - OPAL_SESSION Session; - UINT32 PpStorageFlag; - - gBS->CloseEvent (Event); - - PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags (); - if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) { - // - // Send BlockSID command to each Opal disk - // - Itr = mOpalDriver.DeviceList; - while (Itr != NULL) { - if (Itr->OpalDisk.SupportedAttributes.BlockSid) { - 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; - } - } -} - /** Stop this Controller. @@ -2614,7 +2593,6 @@ EfiDriverEntryPoint( ) { EFI_STATUS Status; - EFI_EVENT ReadyToBootEvent; EFI_EVENT EndOfDxeEvent; Status = EfiLibInstallDriverBindingComponentName2 ( @@ -2647,16 +2625,6 @@ EfiDriverEntryPoint( ); ASSERT_EFI_ERROR (Status); - // - // register a ReadyToBoot event callback for sending BlockSid command - // - Status = EfiCreateEventReadyToBootEx ( - TPL_CALLBACK, - ReadyToBootCallback, - (VOID *) &ImageHandle, - &ReadyToBootEvent - ); - // // Install Hii packages. //