| /** @file | |
| Implement TPM1.2 NV storage related command. | |
| Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved. <BR> | |
| (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> | |
| 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. | |
| **/ | |
| #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, "Tpm12NvWritedValue - ReturnCode = %x\n", SwapBytes32 (Response.returnCode))); | |
| switch (SwapBytes32 (Response.returnCode)) { | |
| case TPM_SUCCESS: | |
| return EFI_SUCCESS; | |
| default: | |
| return EFI_DEVICE_ERROR; | |
| } | |
| } |