diff options
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.c | 228 |
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; + } +} |