]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
Add TPM12 NV related function.
[mirror_edk2.git] / SecurityPkg / Library / Tpm12CommandLib / Tpm12NvStorage.c
diff --git a/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c b/SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
new file mode 100644 (file)
index 0000000..d644d33
--- /dev/null
@@ -0,0 +1,255 @@
+/** @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