summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c375
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.h42
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf61
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.uni16
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMorExtra.uni14
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"
+
+