]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm12CommandLib/Tpm12NvStorage.c
Add TPM12 NV related function.
[mirror_edk2.git] / SecurityPkg / Library / Tpm12CommandLib / Tpm12NvStorage.c
CommitLineData
92ca0c67
JY
1/** @file\r
2 Implement TPM1.2 NV storage related command.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved. <BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <Uefi.h>\r
16#include <IndustryStandard/Tpm12.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/Tpm12DeviceLib.h>\r
20#include <Library/Tpm12CommandLib.h>\r
21#include <Library/DebugLib.h>\r
22\r
23//\r
24// Max TPM command/reponse length\r
25//\r
26#define TPMCMDBUFLENGTH 1024\r
27\r
28#pragma pack(1)\r
29\r
30typedef struct {\r
31 TPM_RQU_COMMAND_HDR Hdr;\r
32 TPM12_NV_DATA_PUBLIC PubInfo;\r
33 TPM_ENCAUTH EncAuth;\r
34} TPM_CMD_NV_DEFINE_SPACE;\r
35\r
36typedef struct {\r
37 TPM_RSP_COMMAND_HDR Hdr;\r
38} TPM_RSP_NV_DEFINE_SPACE;\r
39\r
40typedef struct {\r
41 TPM_RQU_COMMAND_HDR Hdr;\r
42 TPM_NV_INDEX NvIndex;\r
43 UINT32 Offset;\r
44 UINT32 DataSize;\r
45} TPM_CMD_NV_READ_VALUE;\r
46\r
47typedef struct {\r
48 TPM_RSP_COMMAND_HDR Hdr;\r
49 UINT32 DataSize;\r
50 UINT8 Data[TPMCMDBUFLENGTH];\r
51} TPM_RSP_NV_READ_VALUE;\r
52\r
53typedef struct {\r
54 TPM_RQU_COMMAND_HDR Hdr;\r
55 TPM_NV_INDEX NvIndex;\r
56 UINT32 Offset;\r
57 UINT32 DataSize;\r
58 UINT8 Data[TPMCMDBUFLENGTH];\r
59} TPM_CMD_NV_WRITE_VALUE;\r
60\r
61typedef struct {\r
62 TPM_RSP_COMMAND_HDR Hdr;\r
63} TPM_RSP_NV_WRITE_VALUE;\r
64\r
65#pragma pack()\r
66\r
67/**\r
68 Send NV DefineSpace command to TPM1.2.\r
69 \r
70 @param PubInfo The public parameters of the NV area.\r
71 @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization.\r
72\r
73 @retval EFI_SUCCESS Operation completed successfully.\r
74 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
75**/\r
76EFI_STATUS\r
77EFIAPI\r
78Tpm12NvDefineSpace (\r
79 IN TPM12_NV_DATA_PUBLIC *PubInfo,\r
80 IN TPM_ENCAUTH *EncAuth\r
81 )\r
82{\r
83 EFI_STATUS Status;\r
84 UINT32 TpmRecvSize;\r
85 UINT32 TpmSendSize;\r
86 TPM_CMD_NV_DEFINE_SPACE SendBuffer;\r
87 TPM_RSP_NV_DEFINE_SPACE RecvBuffer;\r
88 UINT32 ReturnCode;\r
89\r
90 //\r
91 // send Tpm command TPM_ORD_NV_DefineSpace\r
92 //\r
93 TpmRecvSize = sizeof (TPM_RSP_NV_DEFINE_SPACE);\r
94 TpmSendSize = sizeof (TPM_CMD_NV_DEFINE_SPACE);\r
95 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
96 SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_DEFINE_SPACE));\r
97 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace);\r
98 SendBuffer.PubInfo.tag = SwapBytes16 (PubInfo->tag);\r
99 SendBuffer.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex);\r
100 SendBuffer.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect);\r
101 SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0];\r
102 SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1];\r
103 SendBuffer.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2];\r
104 SendBuffer.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease;\r
105 CopyMem (&SendBuffer.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease));\r
106 SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect);\r
107 SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0];\r
108 SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1];\r
109 SendBuffer.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2];\r
110 SendBuffer.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease;\r
111 CopyMem (&SendBuffer.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease));\r
112 SendBuffer.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag);\r
113 SendBuffer.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes);\r
114 SendBuffer.PubInfo.bReadSTClear = PubInfo->bReadSTClear;\r
115 SendBuffer.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear;\r
116 SendBuffer.PubInfo.bWriteDefine = PubInfo->bWriteDefine;\r
117 SendBuffer.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize);\r
118 CopyMem (&SendBuffer.EncAuth, EncAuth, sizeof(*EncAuth));\r
119\r
120 Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
121 if (EFI_ERROR (Status)) {\r
122 return Status;\r
123 }\r
124 ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
125 DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", ReturnCode));\r
126 switch (ReturnCode) {\r
127 case TPM_SUCCESS:\r
128 break;\r
129 default:\r
130 return EFI_DEVICE_ERROR;\r
131 }\r
132\r
133 return EFI_SUCCESS;\r
134}\r
135\r
136/**\r
137 Send NV ReadValue command to TPM1.2.\r
138\r
139 @param NvIndex The index of the area to set.\r
140 @param Offset The offset into the area.\r
141 @param DataSize The size of the data area.\r
142 @param Data The data to set the area to.\r
143\r
144 @retval EFI_SUCCESS Operation completed successfully.\r
145 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
146**/\r
147EFI_STATUS\r
148EFIAPI\r
149Tpm12NvReadValue (\r
150 IN TPM_NV_INDEX NvIndex,\r
151 IN UINT32 Offset,\r
152 IN OUT UINT32 *DataSize,\r
153 OUT UINT8 *Data\r
154 )\r
155{\r
156 EFI_STATUS Status;\r
157 UINT32 TpmRecvSize;\r
158 UINT32 TpmSendSize;\r
159 TPM_CMD_NV_READ_VALUE SendBuffer;\r
160 TPM_RSP_NV_READ_VALUE RecvBuffer;\r
161 UINT32 ReturnCode;\r
162\r
163 //\r
164 // send Tpm command TPM_ORD_NV_ReadValue\r
165 //\r
166 TpmRecvSize = sizeof (TPM_RSP_NV_READ_VALUE);\r
167 TpmSendSize = sizeof (TPM_CMD_NV_READ_VALUE);\r
168 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
169 SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_READ_VALUE));\r
170 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue);\r
171 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
172 SendBuffer.Offset = SwapBytes32 (Offset);\r
173 SendBuffer.DataSize = SwapBytes32 (*DataSize);\r
174\r
175 Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
176 if (EFI_ERROR (Status)) {\r
177 return Status;\r
178 }\r
179 ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
180 DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", ReturnCode));\r
181 switch (ReturnCode) {\r
182 case TPM_SUCCESS:\r
183 break;\r
184 default:\r
185 return EFI_DEVICE_ERROR;\r
186 }\r
187\r
188 //\r
189 // Return the response\r
190 //\r
191 *DataSize = SwapBytes32(RecvBuffer.DataSize);\r
192 CopyMem (Data, &RecvBuffer.Data, *DataSize);\r
193\r
194 return EFI_SUCCESS;\r
195}\r
196\r
197/**\r
198 Send NV WriteValue command to TPM1.2.\r
199 \r
200 @param NvIndex The index of the area to set.\r
201 @param Offset The offset into the NV Area.\r
202 @param DataSize The size of the data parameter.\r
203 @param Data The data to set the area to.\r
204\r
205 @retval EFI_SUCCESS Operation completed successfully.\r
206 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
207**/\r
208EFI_STATUS\r
209EFIAPI\r
210Tpm12NvWriteValue (\r
211 IN TPM_NV_INDEX NvIndex,\r
212 IN UINT32 Offset,\r
213 IN UINT32 DataSize,\r
214 IN UINT8 *Data\r
215 )\r
216{\r
217 EFI_STATUS Status;\r
218 UINT32 TpmRecvSize;\r
219 UINT32 TpmSendSize;\r
220 TPM_CMD_NV_WRITE_VALUE SendBuffer;\r
221 TPM_RSP_NV_WRITE_VALUE RecvBuffer;\r
222 UINT32 ReturnCode;\r
223\r
224 if (DataSize > sizeof(SendBuffer.Data)) {\r
225 return EFI_UNSUPPORTED;\r
226 }\r
227\r
228 //\r
229 // send Tpm command TPM_ORD_NV_WriteValue\r
230 //\r
231 TpmRecvSize = sizeof (TPM_RSP_NV_WRITE_VALUE);\r
232 TpmSendSize = sizeof (TPM_CMD_NV_WRITE_VALUE) - sizeof(SendBuffer.Data) + DataSize;\r
233 SendBuffer.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
234 SendBuffer.Hdr.paramSize = SwapBytes32 (sizeof(TPM_CMD_NV_WRITE_VALUE) - sizeof(SendBuffer.Data) + DataSize);\r
235 SendBuffer.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue);\r
236 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
237 SendBuffer.Offset = SwapBytes32 (Offset);\r
238 SendBuffer.DataSize = SwapBytes32 (DataSize);\r
239 CopyMem (SendBuffer.Data, Data, DataSize);\r
240\r
241 Status = Tpm12SubmitCommand (TpmSendSize, (UINT8 *)&SendBuffer, &TpmRecvSize, (UINT8 *)&RecvBuffer);\r
242 if (EFI_ERROR (Status)) {\r
243 return Status;\r
244 }\r
245 ReturnCode = SwapBytes32(RecvBuffer.Hdr.returnCode);\r
246 DEBUG ((DEBUG_INFO, "Tpm12NvWritedValue - ReturnCode = %x\n", ReturnCode));\r
247 switch (ReturnCode) {\r
248 case TPM_SUCCESS:\r
249 break;\r
250 default:\r
251 return EFI_DEVICE_ERROR;\r
252 }\r
253\r
254 return EFI_SUCCESS;\r
255}\r