diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl')
5 files changed, 508 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c new file mode 100644 index 00000000..602790b8 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c @@ -0,0 +1,375 @@ +/** @file + TCG MOR (Memory Overwrite Request) Control Driver. + + This driver initialize MemoryOverwriteRequestControl variable. It + will clear MOR_CLEAR_MEMORY_BIT bit if it is set. It will also do TPer Reset for + those encrypted drives through EFI_STORAGE_SECURITY_COMMAND_PROTOCOL at EndOfDxe. + +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "TcgMor.h" + +UINT8 mMorControl; + +/** + Ready to Boot Event notification handler. + + @param[in] Event Event whose notification function is being invoked + @param[in] Context Pointer to the notification function's context + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN DataSize; + + if (MOR_CLEAR_MEMORY_VALUE (mMorControl) == 0x0) { + // + // MorControl is expected, directly return to avoid unnecessary variable operation + // + return ; + } + // + // Clear MOR_CLEAR_MEMORY_BIT + // + DEBUG ((EFI_D_INFO, "TcgMor: Clear MorClearMemory bit\n")); + mMorControl &= 0xFE; + + DataSize = sizeof (mMorControl); + Status = gRT->SetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &mMorControl + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "TcgMor: Clear MOR_CLEAR_MEMORY_BIT failure, Status = %r\n")); + } +} + +/** + Send TPer Reset command to reset eDrive to lock all protected bands. + Typically, there are 2 mechanism for resetting eDrive. They are: + 1. TPer Reset through IEEE 1667 protocol. + 2. TPer Reset through native TCG protocol. + This routine will detect what protocol the attached eDrive conform to, TCG or + IEEE 1667 protocol. Then send out TPer Reset command separately. + + @param[in] Ssp The pointer to EFI_STORAGE_SECURITY_COMMAND_PROTOCOL instance. + @param[in] MediaId ID of the medium to receive data from or send data to. + +**/ +VOID +InitiateTPerReset ( + IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Ssp, + IN UINT32 MediaId + ) +{ + + EFI_STATUS Status; + UINT8 *Buffer; + UINTN XferSize; + UINTN Len; + UINTN Index; + BOOLEAN TcgFlag; + BOOLEAN IeeeFlag; + SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA *Data; + + Buffer = NULL; + TcgFlag = FALSE; + IeeeFlag = FALSE; + + // + // ATA8-ACS 7.57.6.1 indicates the Transfer Length field requirements a multiple of 512. + // If the length of the TRUSTED RECEIVE parameter data is greater than the Transfer Length, + // then the device shall return the TRUSTED RECEIVE parameter data truncated to the requested Transfer Length. + // + Len = ROUNDUP512(sizeof(SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA)); + Buffer = AllocateZeroPool(Len); + + if (Buffer == NULL) { + return; + } + + // + // When the Security Protocol field is set to 00h, and SP Specific is set to 0000h in a TRUSTED RECEIVE + // command, the device basic information data shall be returned. + // + Status = Ssp->ReceiveData ( + Ssp, + MediaId, + 100000000, // Timeout 10-sec + 0, // SecurityProtocol + 0, // SecurityProtocolSpecificData + Len, // PayloadBufferSize, + Buffer, // PayloadBuffer + &XferSize + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + // + // In returned data, the ListLength field indicates the total length, in bytes, + // of the supported security protocol list. + // + Data = (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA*)Buffer; + Len = ROUNDUP512(sizeof (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA) + + (Data->SupportedSecurityListLength[0] << 8) + + (Data->SupportedSecurityListLength[1]) + ); + + // + // Free original buffer and allocate new buffer. + // + FreePool(Buffer); + Buffer = AllocateZeroPool(Len); + if (Buffer == NULL) { + return; + } + + // + // Read full supported security protocol list from device. + // + Status = Ssp->ReceiveData ( + Ssp, + MediaId, + 100000000, // Timeout 10-sec + 0, // SecurityProtocol + 0, // SecurityProtocolSpecificData + Len, // PayloadBufferSize, + Buffer, // PayloadBuffer + &XferSize + ); + + if (EFI_ERROR (Status)) { + goto Exit; + } + + Data = (SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA*)Buffer; + Len = (Data->SupportedSecurityListLength[0] << 8) + Data->SupportedSecurityListLength[1]; + + // + // Iterate full supported security protocol list to check if TCG or IEEE 1667 protocol + // is supported. + // + for (Index = 0; Index < Len; Index++) { + if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_TCG) { + // + // Found a TCG device. + // + TcgFlag = TRUE; + DEBUG ((EFI_D_INFO, "This device is a TCG protocol device\n")); + break; + } + + if (Data->SupportedSecurityProtocol[Index] == SECURITY_PROTOCOL_IEEE1667) { + // + // Found a IEEE 1667 device. + // + IeeeFlag = TRUE; + DEBUG ((EFI_D_INFO, "This device is a IEEE 1667 protocol device\n")); + break; + } + } + + if (!TcgFlag && !IeeeFlag) { + DEBUG ((EFI_D_INFO, "Neither a TCG nor IEEE 1667 protocol device is found\n")); + goto Exit; + } + + if (TcgFlag) { + // + // As long as TCG protocol is supported, send out a TPer Reset + // TCG command to the device via the TrustedSend command with a non-zero Transfer Length. + // + Status = Ssp->SendData ( + Ssp, + MediaId, + 100000000, // Timeout 10-sec + SECURITY_PROTOCOL_TCG, // SecurityProtocol + 0x0400, // SecurityProtocolSpecificData + 512, // PayloadBufferSize, + Buffer // PayloadBuffer + ); + + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "Send TPer Reset Command Successfully !\n")); + } else { + DEBUG ((EFI_D_INFO, "Send TPer Reset Command Fail !\n")); + } + } + + if (IeeeFlag) { + // + // TBD : Perform a TPer Reset via IEEE 1667 Protocol + // + DEBUG ((EFI_D_INFO, "IEEE 1667 Protocol didn't support yet!\n")); + } + +Exit: + + if (Buffer != NULL) { + FreePool(Buffer); + } +} + +/** + Notification function of END_OF_DXE. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +TPerResetAtEndOfDxe ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *Ssp; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + // + // Locate all SSP protocol instances. + // + HandleCount = 0; + HandleBuffer = NULL; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiStorageSecurityCommandProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + + if (EFI_ERROR (Status) || (HandleCount == 0) || (HandleBuffer == NULL)) { + return; + } + + for (Index = 0; Index < HandleCount; Index ++) { + // + // Get the SSP interface. + // + Status = gBS->HandleProtocol( + HandleBuffer[Index], + &gEfiStorageSecurityCommandProtocolGuid, + (VOID **) &Ssp + ); + + if (EFI_ERROR (Status)) { + continue; + } + + Status = gBS->HandleProtocol( + HandleBuffer[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlockIo + ); + + if (EFI_ERROR (Status)) { + continue; + } + + InitiateTPerReset (Ssp, BlockIo->Media->MediaId); + } + + FreePool (HandleBuffer); +} + +/** + Entry Point for TCG MOR Control driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable A Pointer to the EFI System Table. + + @retval EFI_SUCCESS + @return Others Some error occurs. +**/ +EFI_STATUS +EFIAPI +MorDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINTN DataSize; + EFI_EVENT Event; + + /// + /// The firmware is required to create the MemoryOverwriteRequestControl UEFI variable. + /// + + DataSize = sizeof (mMorControl); + Status = gRT->GetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + NULL, + &DataSize, + &mMorControl + ); + if (EFI_ERROR (Status)) { + // + // Set default value to 0 + // + mMorControl = 0; + Status = gRT->SetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + DataSize, + &mMorControl + ); + DEBUG ((EFI_D_INFO, "TcgMor: Create MOR variable! Status = %r\n", Status)); + } else { + // + // Create a Ready To Boot Event and Clear the MorControl bit in the call back function. + // + DEBUG ((DEBUG_INFO, "TcgMor: Create ReadyToBoot Event for MorControl Bit cleaning!\n")); + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &Event + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event. + // + DEBUG ((EFI_D_INFO, "TcgMor: Create EndofDxe Event for Mor TPer Reset!\n")); + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + TPerResetAtEndOfDxe, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &Event + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return Status; +} + + diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h new file mode 100644 index 00000000..63ff7784 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h @@ -0,0 +1,42 @@ +/** @file + The header file for TcgMor. + +Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __TCG_MOR_H__ +#define __TCG_MOR_H__ + +#include <PiDxe.h> + +#include <Guid/MemoryOverwriteControl.h> + +#include <Library/UefiDriverEntryPoint.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiLib.h> +#include <Library/MemoryAllocationLib.h> + +#include <Protocol/StorageSecurityCommand.h> +#include <Protocol/BlockIo.h> + +// +// Supported Security Protocols List Description. +// Refer to ATA8-ACS Spec 7.57.6.2 Table 69 or SPC4 7.7.1.3 Table 511. +// +typedef struct { + UINT8 Reserved1[6]; + UINT8 SupportedSecurityListLength[2]; + UINT8 SupportedSecurityProtocol[1]; +} SUPPORTED_SECURITY_PROTOCOLS_PARAMETER_DATA; + +#define SECURITY_PROTOCOL_TCG 0x02 +#define SECURITY_PROTOCOL_IEEE1667 0xEE + +#define ROUNDUP512(x) (((x) % 512 == 0) ? (x) : ((x) / 512 + 1) * 512) + +#endif + diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf new file mode 100644 index 00000000..6aa727af --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf @@ -0,0 +1,61 @@ +## @file +# initializes MemoryOverwriteRequestControl variable +# +# This module will clear MOR_CLEAR_MEMORY_BIT bit if it is set. It will also do +# TPer Reset for those encrypted drives through EFI_STORAGE_SECURITY_COMMAND_PROTOCOL +# at EndOfDxe. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = TcgMor + MODULE_UNI_FILE = TcgMor.uni + FILE_GUID = AD416CE3-A483-45b1-94C2-4B4E4D575562 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = MorDriverEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + TcgMor.c + TcgMor.h + +[Packages] + MdePkg/MdePkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + DebugLib + UefiLib + MemoryAllocationLib + +[Guids] + ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl" + ## PRODUCES ## Variable:L"MemoryOverwriteRequestControl" + gEfiMemoryOverwriteControlDataGuid + gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event + +[Protocols] + gEfiStorageSecurityCommandProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + +[Depex] + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid AND + ( gEfiTcgProtocolGuid OR gEfiTcg2ProtocolGuid ) + +[UserExtensions.TianoCore."ExtraFiles"] + TcgMorExtra.uni diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.uni b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.uni new file mode 100644 index 00000000..6a1df103 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.uni @@ -0,0 +1,16 @@ +// /** @file
+// initializes MemoryOverwriteRequestControl variable
+//
+// This module will clear MOR_CLEAR_MEMORY_BIT bit if it is set.
+//
+// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Initializes the MemoryOverwriteRequestControl variable"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module will clear MOR_CLEAR_MEMORY_BIT bit if it is set."
+
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMorExtra.uni b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMorExtra.uni new file mode 100644 index 00000000..49170c76 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMorExtra.uni @@ -0,0 +1,14 @@ +// /** @file
+// TcgMor Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TCG (Trusted Computing Group) MOR"
+
+
|