--- /dev/null
+/** @file\r
+ Implement TPM1.2 NV storage related command.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved. <BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+#include <IndustryStandard/Tpm12.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/Tpm12DeviceLib.h>\r
+#include <Library/Tpm12CommandLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+//\r
+// Max TPM command/reponse length\r
+//\r
+#define TPMCMDBUFLENGTH 1024\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ TPM_RQU_COMMAND_HDR Hdr;\r
+ TPM12_NV_DATA_PUBLIC PubInfo;\r
+ TPM_ENCAUTH EncAuth;\r
+} TPM_CMD_NV_DEFINE_SPACE;\r
+\r
+typedef struct {\r
+ TPM_RSP_COMMAND_HDR Hdr;\r
+} TPM_RSP_NV_DEFINE_SPACE;\r
+\r
+typedef struct {\r
+ TPM_RQU_COMMAND_HDR Hdr;\r
+ TPM_NV_INDEX NvIndex;\r
+ UINT32 Offset;\r
+ UINT32 DataSize;\r
+} TPM_CMD_NV_READ_VALUE;\r
+\r
+typedef struct {\r
+ TPM_RSP_COMMAND_HDR Hdr;\r
+ UINT32 DataSize;\r
+ UINT8 Data[TPMCMDBUFLENGTH];\r
+} TPM_RSP_NV_READ_VALUE;\r
+\r
+typedef struct {\r
+ TPM_RQU_COMMAND_HDR Hdr;\r
+ TPM_NV_INDEX NvIndex;\r
+ UINT32 Offset;\r
+ UINT32 DataSize;\r
+ UINT8 Data[TPMCMDBUFLENGTH];\r
+} TPM_CMD_NV_WRITE_VALUE;\r
+\r
+typedef struct {\r
+ TPM_RSP_COMMAND_HDR Hdr;\r
+} TPM_RSP_NV_WRITE_VALUE;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+ Send NV DefineSpace command to TPM1.2.\r
+ \r
+ @param PubInfo The public parameters of the NV area.\r
+ @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12NvDefineSpace (\r
+ IN TPM12_NV_DATA_PUBLIC *PubInfo,\r
+ IN TPM_ENCAUTH *EncAuth\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 TpmRecvSize;\r
+ UINT32 TpmSendSize;\r
+ TPM_CMD_NV_DEFINE_SPACE SendBuffer;\r
+ TPM_RSP_NV_DEFINE_SPACE RecvBuffer;\r
+ UINT32 ReturnCode;\r
+\r
+ //\r
+ // send Tpm command TPM_ORD_NV_DefineSpace\r
+ //\r
+ TpmRecvSize = sizeof (TPM_RSP_NV_DEFINE_SPACE);\r
+ TpmSendSize = sizeof (TPM_CMD_NV_DEFINE_SPACE);\r
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
+ SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_DEFINE_SPACE));\r
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace);\r
+ SendBuffer.PubInfo.tag = SwapBytes16 (PubInfo->tag);\r
+ SendBuffer.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex);\r
+ SendBuffer.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect);\r
+ SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0];\r
+ SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1];\r
+ SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2];\r
+ SendBuffer.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease;\r
+ CopyMem (&SendBuffer.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease));\r
+ SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect);\r
+ SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0];\r
+ SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1];\r
+ SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2];\r
+ SendBuffer.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease;\r
+ CopyMem (&SendBuffer.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease));\r
+ SendBuffer.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag);\r
+ SendBuffer.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes);\r
+ SendBuffer.PubInfo.bReadSTClear = PubInfo->bReadSTClear;\r
+ SendBuffer.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear;\r
+ SendBuffer.PubInfo.bWriteDefine = PubInfo->bWriteDefine;\r
+ SendBuffer.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize);\r
+ CopyMem (&SendBuffer.EncAuth, EncAuth, sizeof(*EncAuth));\r
+\r
+ Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
+ DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", ReturnCode));\r
+ switch (ReturnCode) {\r
+ case TPM_SUCCESS:\r
+ break;\r
+ default:\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Send NV ReadValue command to TPM1.2.\r
+\r
+ @param NvIndex The index of the area to set.\r
+ @param Offset The offset into the area.\r
+ @param DataSize The size of the data area.\r
+ @param Data The data to set the area to.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12NvReadValue (\r
+ IN TPM_NV_INDEX NvIndex,\r
+ IN UINT32 Offset,\r
+ IN OUT UINT32 *DataSize,\r
+ OUT UINT8 *Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 TpmRecvSize;\r
+ UINT32 TpmSendSize;\r
+ TPM_CMD_NV_READ_VALUE SendBuffer;\r
+ TPM_RSP_NV_READ_VALUE RecvBuffer;\r
+ UINT32 ReturnCode;\r
+\r
+ //\r
+ // send Tpm command TPM_ORD_NV_ReadValue\r
+ //\r
+ TpmRecvSize = sizeof (TPM_RSP_NV_READ_VALUE);\r
+ TpmSendSize = sizeof (TPM_CMD_NV_READ_VALUE);\r
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
+ SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_READ_VALUE));\r
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue);\r
+ SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
+ SendBuffer.Offset = SwapBytes32 (Offset);\r
+ SendBuffer.DataSize = SwapBytes32 (*DataSize);\r
+\r
+ Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
+ DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", ReturnCode));\r
+ switch (ReturnCode) {\r
+ case TPM_SUCCESS:\r
+ break;\r
+ default:\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ //\r
+ // Return the response\r
+ //\r
+ *DataSize = SwapBytes32(RecvBuffer.DataSize);\r
+ CopyMem (Data, &RecvBuffer.Data, *DataSize);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Send NV WriteValue command to TPM1.2.\r
+ \r
+ @param NvIndex The index of the area to set.\r
+ @param Offset The offset into the NV Area.\r
+ @param DataSize The size of the data parameter.\r
+ @param Data The data to set the area to.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Tpm12NvWriteValue (\r
+ IN TPM_NV_INDEX NvIndex,\r
+ IN UINT32 Offset,\r
+ IN UINT32 DataSize,\r
+ IN UINT8 *Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 TpmRecvSize;\r
+ UINT32 TpmSendSize;\r
+ TPM_CMD_NV_WRITE_VALUE SendBuffer;\r
+ TPM_RSP_NV_WRITE_VALUE RecvBuffer;\r
+ UINT32 ReturnCode;\r
+\r
+ if (DataSize > sizeof(SendBuffer.Data)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // send Tpm command TPM_ORD_NV_WriteValue\r
+ //\r
+ TpmRecvSize = sizeof (TPM_RSP_NV_WRITE_VALUE);\r
+ TpmSendSize = sizeof (TPM_CMD_NV_WRITE_VALUE) - sizeof(SendBuffer.Data) + DataSize;\r
+ SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
+ SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_WRITE_VALUE) - sizeof(SendBuffer.Data) + DataSize);\r
+ SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue);\r
+ SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
+ SendBuffer.Offset = SwapBytes32 (Offset);\r
+ SendBuffer.DataSize = SwapBytes32 (DataSize);\r
+ CopyMem (SendBuffer.Data, Data, DataSize);\r
+\r
+ Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
+ DEBUG ((DEBUG_INFO, "Tpm12NvWritedValue - ReturnCode = %x\n", ReturnCode));\r
+ switch (ReturnCode) {\r
+ case TPM_SUCCESS:\r
+ break;\r
+ default:\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r