summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
new file mode 100644
index 00000000..5a4ebefd
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
@@ -0,0 +1,228 @@
+/** @file
+ Implement TPM1.2 NV storage related command.
+
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/Tpm12CommandLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/Tpm12DeviceLib.h>
+
+//
+// Max TPM NV value length
+//
+#define TPMNVVALUELENGTH 1024
+
+#pragma pack(1)
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM12_NV_DATA_PUBLIC PubInfo;
+ TPM_ENCAUTH EncAuth;
+} TPM_CMD_NV_DEFINE_SPACE;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM_NV_INDEX NvIndex;
+ UINT32 Offset;
+ UINT32 DataSize;
+} TPM_CMD_NV_READ_VALUE;
+
+typedef struct {
+ TPM_RSP_COMMAND_HDR Hdr;
+ UINT32 DataSize;
+ UINT8 Data[TPMNVVALUELENGTH];
+} TPM_RSP_NV_READ_VALUE;
+
+typedef struct {
+ TPM_RQU_COMMAND_HDR Hdr;
+ TPM_NV_INDEX NvIndex;
+ UINT32 Offset;
+ UINT32 DataSize;
+ UINT8 Data[TPMNVVALUELENGTH];
+} TPM_CMD_NV_WRITE_VALUE;
+
+#pragma pack()
+
+/**
+ Send NV DefineSpace command to TPM1.2.
+
+ @param PubInfo The public parameters of the NV area.
+ @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12NvDefineSpace (
+ IN TPM12_NV_DATA_PUBLIC *PubInfo,
+ IN TPM_ENCAUTH *EncAuth
+ )
+{
+ EFI_STATUS Status;
+ TPM_CMD_NV_DEFINE_SPACE Command;
+ TPM_RSP_COMMAND_HDR Response;
+ UINT32 Length;
+
+ //
+ // send Tpm command TPM_ORD_NV_DefineSpace
+ //
+ Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
+ Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace);
+ Command.PubInfo.tag = SwapBytes16 (PubInfo->tag);
+ Command.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex);
+ Command.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect);
+ Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0];
+ Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1];
+ Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2];
+ Command.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease;
+ CopyMem (&Command.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease));
+ Command.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect);
+ Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0];
+ Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1];
+ Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2];
+ Command.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease;
+ CopyMem (&Command.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease));
+ Command.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag);
+ Command.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes);
+ Command.PubInfo.bReadSTClear = PubInfo->bReadSTClear;
+ Command.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear;
+ Command.PubInfo.bWriteDefine = PubInfo->bWriteDefine;
+ Command.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize);
+ CopyMem (&Command.EncAuth, EncAuth, sizeof(*EncAuth));
+ Length = sizeof (Response);
+ Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
+ switch (SwapBytes32 (Response.returnCode)) {
+ case TPM_SUCCESS:
+ return EFI_SUCCESS;
+ default:
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Send NV ReadValue command to TPM1.2.
+
+ @param NvIndex The index of the area to set.
+ @param Offset The offset into the area.
+ @param DataSize The size of the data area.
+ @param Data The data to set the area to.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12NvReadValue (
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN OUT UINT32 *DataSize,
+ OUT UINT8 *Data
+ )
+{
+ EFI_STATUS Status;
+ TPM_CMD_NV_READ_VALUE Command;
+ TPM_RSP_NV_READ_VALUE Response;
+ UINT32 Length;
+
+ //
+ // send Tpm command TPM_ORD_NV_ReadValue
+ //
+ Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ Command.Hdr.paramSize = SwapBytes32 (sizeof (Command));
+ Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue);
+ Command.NvIndex = SwapBytes32 (NvIndex);
+ Command.Offset = SwapBytes32 (Offset);
+ Command.DataSize = SwapBytes32 (*DataSize);
+ Length = sizeof (Response);
+ Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", SwapBytes32 (Response.Hdr.returnCode)));
+ switch (SwapBytes32 (Response.Hdr.returnCode)) {
+ case TPM_SUCCESS:
+ break;
+ default:
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the response
+ //
+ if (SwapBytes32 (Response.DataSize) > *DataSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *DataSize = SwapBytes32 (Response.DataSize);
+ ZeroMem (Data, *DataSize);
+ CopyMem (Data, &Response.Data, *DataSize);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Send NV WriteValue command to TPM1.2.
+
+ @param NvIndex The index of the area to set.
+ @param Offset The offset into the NV Area.
+ @param DataSize The size of the data parameter.
+ @param Data The data to set the area to.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12NvWriteValue (
+ IN TPM_NV_INDEX NvIndex,
+ IN UINT32 Offset,
+ IN UINT32 DataSize,
+ IN UINT8 *Data
+ )
+{
+ EFI_STATUS Status;
+ TPM_CMD_NV_WRITE_VALUE Command;
+ UINT32 CommandLength;
+ TPM_RSP_COMMAND_HDR Response;
+ UINT32 ResponseLength;
+
+ if (DataSize > sizeof (Command.Data)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // send Tpm command TPM_ORD_NV_WriteValue
+ //
+ Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);
+ CommandLength = sizeof (Command) - sizeof(Command.Data) + DataSize;
+ Command.Hdr.paramSize = SwapBytes32 (CommandLength);
+ Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue);
+ Command.NvIndex = SwapBytes32 (NvIndex);
+ Command.Offset = SwapBytes32 (Offset);
+ Command.DataSize = SwapBytes32 (DataSize);
+ CopyMem (Command.Data, Data, DataSize);
+ ResponseLength = sizeof (Response);
+ Status = Tpm12SubmitCommand (CommandLength, (UINT8 *)&Command, &ResponseLength, (UINT8 *)&Response);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ DEBUG ((DEBUG_INFO, "Tpm12NvWriteValue - ReturnCode = %x\n", SwapBytes32 (Response.returnCode)));
+ switch (SwapBytes32 (Response.returnCode)) {
+ case TPM_SUCCESS:
+ return EFI_SUCCESS;
+ default:
+ return EFI_DEVICE_ERROR;
+ }
+}