]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
Add TPM2 implementation.
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2NVStorage.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 NVStorage related command.\r
3\r
4Copyright (c) 2013, 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 <IndustryStandard/UefiTcgPlatform.h>\r
16#include <Library/Tpm2CommandLib.h>\r
17#include <Library/Tpm2DeviceLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22#pragma pack(1)\r
23\r
24#define RC_NV_ReadPublic_nvIndex (TPM_RC_H + TPM_RC_1)\r
25\r
26#define RC_NV_DefineSpace_authHandle (TPM_RC_H + TPM_RC_1)\r
27#define RC_NV_DefineSpace_auth (TPM_RC_P + TPM_RC_1)\r
28#define RC_NV_DefineSpace_publicInfo (TPM_RC_P + TPM_RC_2)\r
29\r
30#define RC_NV_UndefineSpace_authHandle (TPM_RC_H + TPM_RC_1)\r
31#define RC_NV_UndefineSpace_nvIndex (TPM_RC_H + TPM_RC_2)\r
32\r
33#define RC_NV_Read_authHandle (TPM_RC_H + TPM_RC_1)\r
34#define RC_NV_Read_nvIndex (TPM_RC_H + TPM_RC_2)\r
35#define RC_NV_Read_size (TPM_RC_P + TPM_RC_1)\r
36#define RC_NV_Read_offset (TPM_RC_P + TPM_RC_2)\r
37\r
38#define RC_NV_Write_authHandle (TPM_RC_H + TPM_RC_1)\r
39#define RC_NV_Write_nvIndex (TPM_RC_H + TPM_RC_2)\r
40#define RC_NV_Write_data (TPM_RC_P + TPM_RC_1)\r
41#define RC_NV_Write_offset (TPM_RC_P + TPM_RC_2)\r
42\r
43typedef struct {\r
44 TPM2_COMMAND_HEADER Header;\r
45 TPMI_RH_NV_INDEX NvIndex;\r
46} TPM2_NV_READPUBLIC_COMMAND;\r
47\r
48typedef struct {\r
49 TPM2_RESPONSE_HEADER Header;\r
50 TPM2B_NV_PUBLIC NvPublic;\r
51 TPM2B_NAME NvName;\r
52} TPM2_NV_READPUBLIC_RESPONSE;\r
53\r
54typedef struct {\r
55 TPM2_COMMAND_HEADER Header;\r
56 TPMI_RH_PROVISION AuthHandle;\r
57 UINT32 AuthSessionSize;\r
58 TPMS_AUTH_COMMAND AuthSession;\r
59 TPM2B_AUTH Auth;\r
60 TPM2B_NV_PUBLIC NvPublic;\r
61} TPM2_NV_DEFINESPACE_COMMAND;\r
62\r
63typedef struct {\r
64 TPM2_RESPONSE_HEADER Header;\r
65 UINT32 AuthSessionSize;\r
66 TPMS_AUTH_RESPONSE AuthSession;\r
67} TPM2_NV_DEFINESPACE_RESPONSE;\r
68\r
69typedef struct {\r
70 TPM2_COMMAND_HEADER Header;\r
71 TPMI_RH_PROVISION AuthHandle;\r
72 TPMI_RH_NV_INDEX NvIndex;\r
73 UINT32 AuthSessionSize;\r
74 TPMS_AUTH_COMMAND AuthSession;\r
75} TPM2_NV_UNDEFINESPACE_COMMAND;\r
76\r
77typedef struct {\r
78 TPM2_RESPONSE_HEADER Header;\r
79 UINT32 AuthSessionSize;\r
80 TPMS_AUTH_RESPONSE AuthSession;\r
81} TPM2_NV_UNDEFINESPACE_RESPONSE;\r
82\r
83typedef struct {\r
84 TPM2_COMMAND_HEADER Header;\r
85 TPMI_RH_NV_AUTH AuthHandle;\r
86 TPMI_RH_NV_INDEX NvIndex;\r
87 UINT32 AuthSessionSize;\r
88 TPMS_AUTH_COMMAND AuthSession;\r
89 UINT16 Size;\r
90 UINT16 Offset;\r
91} TPM2_NV_READ_COMMAND;\r
92\r
93typedef struct {\r
94 TPM2_RESPONSE_HEADER Header;\r
95 UINT32 AuthSessionSize;\r
96 TPM2B_MAX_BUFFER Data;\r
97 TPMS_AUTH_RESPONSE AuthSession;\r
98} TPM2_NV_READ_RESPONSE;\r
99\r
100typedef struct {\r
101 TPM2_COMMAND_HEADER Header;\r
102 TPMI_RH_NV_AUTH AuthHandle;\r
103 TPMI_RH_NV_INDEX NvIndex;\r
104 UINT32 AuthSessionSize;\r
105 TPMS_AUTH_COMMAND AuthSession;\r
106 TPM2B_MAX_BUFFER Data;\r
107 UINT16 Offset;\r
108} TPM2_NV_WRITE_COMMAND;\r
109\r
110typedef struct {\r
111 TPM2_RESPONSE_HEADER Header;\r
112 UINT32 AuthSessionSize;\r
113 TPMS_AUTH_RESPONSE AuthSession;\r
114} TPM2_NV_WRITE_RESPONSE;\r
115\r
116typedef struct {\r
117 TPM2_COMMAND_HEADER Header;\r
118 TPMI_RH_NV_AUTH AuthHandle;\r
119 TPMI_RH_NV_INDEX NvIndex;\r
120 UINT32 AuthSessionSize;\r
121 TPMS_AUTH_COMMAND AuthSession;\r
122} TPM2_NV_READLOCK_COMMAND;\r
123\r
124typedef struct {\r
125 TPM2_RESPONSE_HEADER Header;\r
126 UINT32 AuthSessionSize;\r
127 TPMS_AUTH_RESPONSE AuthSession;\r
128} TPM2_NV_READLOCK_RESPONSE;\r
129\r
130typedef struct {\r
131 TPM2_COMMAND_HEADER Header;\r
132 TPMI_RH_NV_AUTH AuthHandle;\r
133 TPMI_RH_NV_INDEX NvIndex;\r
134 UINT32 AuthSessionSize;\r
135 TPMS_AUTH_COMMAND AuthSession;\r
136} TPM2_NV_WRITELOCK_COMMAND;\r
137\r
138typedef struct {\r
139 TPM2_RESPONSE_HEADER Header;\r
140 UINT32 AuthSessionSize;\r
141 TPMS_AUTH_RESPONSE AuthSession;\r
142} TPM2_NV_WRITELOCK_RESPONSE;\r
143\r
144typedef struct {\r
145 TPM2_COMMAND_HEADER Header;\r
146 TPMI_RH_PROVISION AuthHandle;\r
147 UINT32 AuthSessionSize;\r
148 TPMS_AUTH_COMMAND AuthSession;\r
149} TPM2_NV_GLOBALWRITELOCK_COMMAND;\r
150\r
151typedef struct {\r
152 TPM2_RESPONSE_HEADER Header;\r
153 UINT32 AuthSessionSize;\r
154 TPMS_AUTH_RESPONSE AuthSession;\r
155} TPM2_NV_GLOBALWRITELOCK_RESPONSE;\r
156\r
157#pragma pack()\r
158\r
159/**\r
160 This command is used to read the public area and Name of an NV Index.\r
161\r
162 @param[in] NvIndex The NV Index.\r
163 @param[out] NvPublic The public area of the index.\r
164 @param[out] NvName The Name of the nvIndex.\r
165 \r
166 @retval EFI_SUCCESS Operation completed successfully.\r
167 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
168 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
169**/\r
170EFI_STATUS\r
171EFIAPI\r
172Tpm2NvReadPublic (\r
173 IN TPMI_RH_NV_INDEX NvIndex,\r
174 OUT TPM2B_NV_PUBLIC *NvPublic,\r
175 OUT TPM2B_NAME *NvName\r
176 )\r
177{\r
178 EFI_STATUS Status;\r
179 TPM2_NV_READPUBLIC_COMMAND SendBuffer;\r
180 TPM2_NV_READPUBLIC_RESPONSE RecvBuffer;\r
181 UINT32 SendBufferSize;\r
182 UINT32 RecvBufferSize;\r
183 UINT16 NvPublicSize;\r
184 UINT16 NvNameSize;\r
185 UINT8 *Buffer;\r
186 TPM_RC ResponseCode;\r
187\r
188 //\r
189 // Construct command\r
190 //\r
191 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
192 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadPublic);\r
193\r
194 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
195 \r
196 SendBufferSize = (UINT32) sizeof (SendBuffer);\r
197 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
198\r
199 //\r
200 // send Tpm command\r
201 //\r
202 RecvBufferSize = sizeof (RecvBuffer);\r
203 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
204 if (EFI_ERROR (Status)) {\r
205 return Status;\r
206 }\r
207\r
208 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
209 DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));\r
210 return EFI_DEVICE_ERROR;\r
211 }\r
212 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
213 if (ResponseCode != TPM_RC_SUCCESS) {\r
214 DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
215 }\r
216 switch (ResponseCode) {\r
217 case TPM_RC_SUCCESS:\r
218 // return data\r
219 break;\r
220 case TPM_RC_HANDLE + RC_NV_ReadPublic_nvIndex: // TPM_RC_NV_DEFINED:\r
221 return EFI_NOT_FOUND;\r
222 case TPM_RC_VALUE + RC_NV_ReadPublic_nvIndex:\r
223 return EFI_INVALID_PARAMETER;\r
224 default:\r
225 return EFI_DEVICE_ERROR;\r
226 }\r
227\r
228 if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT16) + sizeof(UINT16)) {\r
229 DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize));\r
230 return EFI_NOT_FOUND;\r
231 }\r
232\r
233 //\r
234 // Basic check\r
235 //\r
236 NvPublicSize = SwapBytes16 (RecvBuffer.NvPublic.size);\r
237 NvNameSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)((UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize)));\r
238\r
239 if (RecvBufferSize != sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize + sizeof(UINT16) + NvNameSize) {\r
240 DEBUG ((EFI_D_ERROR, "Tpm2NvReadPublic - RecvBufferSize Error - NvPublicSize %x, NvNameSize %x\n", RecvBufferSize, NvNameSize));\r
241 return EFI_NOT_FOUND;\r
242 }\r
243\r
244 //\r
245 // Return the response\r
246 //\r
247 CopyMem (NvPublic, &RecvBuffer.NvPublic, sizeof(UINT16) + NvPublicSize);\r
248 NvPublic->size = NvPublicSize;\r
249 NvPublic->nvPublic.nvIndex = SwapBytes32 (NvPublic->nvPublic.nvIndex);\r
250 NvPublic->nvPublic.nameAlg = SwapBytes16 (NvPublic->nvPublic.nameAlg);\r
251 WriteUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));\r
252 NvPublic->nvPublic.authPolicy.size = SwapBytes16 (NvPublic->nvPublic.authPolicy.size);\r
253 Buffer = (UINT8 *)&NvPublic->nvPublic.authPolicy;\r
254 Buffer += sizeof(UINT16) + NvPublic->nvPublic.authPolicy.size;\r
255 NvPublic->nvPublic.dataSize = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
256\r
257 CopyMem (NvName, (UINT8 *)&RecvBuffer + sizeof(TPM2_RESPONSE_HEADER) + sizeof(UINT16) + NvPublicSize, NvNameSize);\r
258 NvName->size = NvNameSize;\r
259 \r
260 return EFI_SUCCESS;\r
261}\r
262\r
263/**\r
264 This command defines the attributes of an NV Index and causes the TPM to\r
265 reserve space to hold the data associated with the index.\r
266 If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.\r
267\r
268 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
269 @param[in] AuthSession Auth Session context\r
270 @param[in] Auth The authorization data.\r
271 @param[in] NvPublic The public area of the index.\r
272 \r
273 @retval EFI_SUCCESS Operation completed successfully.\r
274 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
275 @retval EFI_ALREADY_STARTED The command was returned successfully, but NvIndex is already defined.\r
276**/\r
277EFI_STATUS\r
278EFIAPI\r
279Tpm2NvDefineSpace (\r
280 IN TPMI_RH_PROVISION AuthHandle,\r
281 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
282 IN TPM2B_AUTH *Auth,\r
283 IN TPM2B_NV_PUBLIC *NvPublic\r
284 )\r
285{\r
286 EFI_STATUS Status;\r
287 TPM2_NV_DEFINESPACE_COMMAND SendBuffer;\r
288 TPM2_NV_DEFINESPACE_RESPONSE RecvBuffer;\r
289 UINT32 SendBufferSize;\r
290 UINT32 RecvBufferSize;\r
291 UINT16 NvPublicSize;\r
292 UINT8 *Buffer;\r
293 UINT32 SessionInfoSize;\r
294 TPM_RC ResponseCode;\r
295\r
296 //\r
297 // Construct command\r
298 //\r
299 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
300 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_DefineSpace);\r
301 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
302\r
303 //\r
304 // Add in Auth session\r
305 //\r
306 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
307\r
308 // sessionInfoSize\r
309 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
310 Buffer += SessionInfoSize;\r
311 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
312\r
313 //\r
314 // IndexAuth\r
315 //\r
316 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Auth->size));\r
317 Buffer += sizeof(UINT16);\r
318 CopyMem(Buffer, Auth->buffer, Auth->size);\r
319 Buffer += Auth->size;\r
320\r
321 //\r
322 // NvPublic\r
323 //\r
324 NvPublicSize = NvPublic->size;\r
325\r
326 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublicSize));\r
327 Buffer += sizeof(UINT16);\r
328 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (NvPublic->nvPublic.nvIndex));\r
329 Buffer += sizeof(UINT32);\r
330 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.nameAlg));\r
331 Buffer += sizeof(UINT16);\r
332 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&NvPublic->nvPublic.attributes)));\r
333 Buffer += sizeof(UINT32);\r
334 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.authPolicy.size));\r
335 Buffer += sizeof(UINT16);\r
336 CopyMem (Buffer, NvPublic->nvPublic.authPolicy.buffer, NvPublic->nvPublic.authPolicy.size);\r
337 Buffer += NvPublic->nvPublic.authPolicy.size;\r
338 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NvPublic->nvPublic.dataSize));\r
339 Buffer += sizeof(UINT16);\r
340\r
341 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
342 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
343\r
344 //\r
345 // send Tpm command\r
346 //\r
347 RecvBufferSize = sizeof (RecvBuffer);\r
348 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
349 if (EFI_ERROR (Status)) {\r
350 return Status;\r
351 }\r
352\r
353 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
354 DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));\r
355 return EFI_DEVICE_ERROR;\r
356 }\r
357\r
358 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
359 if (ResponseCode != TPM_RC_SUCCESS) {\r
360 DEBUG ((EFI_D_ERROR, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
361 }\r
362 switch (ResponseCode) {\r
363 case TPM_RC_SUCCESS:\r
364 // return data\r
365 break;\r
366 case TPM_RC_SIZE + RC_NV_DefineSpace_publicInfo:\r
367 case TPM_RC_SIZE + RC_NV_DefineSpace_auth:\r
368 return EFI_BAD_BUFFER_SIZE;\r
369 case TPM_RC_ATTRIBUTES:\r
370 case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_publicInfo:\r
371 return EFI_UNSUPPORTED;\r
372 case TPM_RC_ATTRIBUTES + RC_NV_DefineSpace_authHandle:\r
373 return EFI_INVALID_PARAMETER;\r
374 case TPM_RC_NV_DEFINED:\r
375 return EFI_ALREADY_STARTED;\r
376 case TPM_RC_VALUE + RC_NV_DefineSpace_publicInfo:\r
377 case TPM_RC_VALUE + RC_NV_DefineSpace_authHandle:\r
378 return EFI_INVALID_PARAMETER;\r
379 case TPM_RC_NV_SPACE:\r
380 return EFI_OUT_OF_RESOURCES;\r
381 default:\r
382 return EFI_DEVICE_ERROR;\r
383 }\r
384 \r
385 return EFI_SUCCESS;\r
386}\r
387\r
388/**\r
389 This command removes an index from the TPM.\r
390\r
391 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
392 @param[in] NvIndex The NV Index.\r
393 @param[in] AuthSession Auth Session context\r
394 \r
395 @retval EFI_SUCCESS Operation completed successfully.\r
396 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
397 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
398**/\r
399EFI_STATUS\r
400EFIAPI\r
401Tpm2NvUndefineSpace (\r
402 IN TPMI_RH_PROVISION AuthHandle,\r
403 IN TPMI_RH_NV_INDEX NvIndex,\r
404 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL\r
405 )\r
406{\r
407 EFI_STATUS Status;\r
408 TPM2_NV_UNDEFINESPACE_COMMAND SendBuffer;\r
409 TPM2_NV_UNDEFINESPACE_RESPONSE RecvBuffer;\r
410 UINT32 SendBufferSize;\r
411 UINT32 RecvBufferSize;\r
412 UINT8 *Buffer;\r
413 UINT32 SessionInfoSize;\r
414 TPM_RC ResponseCode;\r
415\r
416 //\r
417 // Construct command\r
418 //\r
419 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
420 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_UndefineSpace);\r
421\r
422 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
423 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
424\r
425 //\r
426 // Add in Auth session\r
427 //\r
428 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
429\r
430 // sessionInfoSize\r
431 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
432 Buffer += SessionInfoSize;\r
433 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
434\r
435 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
436 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
437\r
438 //\r
439 // send Tpm command\r
440 //\r
441 RecvBufferSize = sizeof (RecvBuffer);\r
442 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
443 if (EFI_ERROR (Status)) {\r
444 return Status;\r
445 }\r
446\r
447 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
448 DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize));\r
449 return EFI_DEVICE_ERROR;\r
450 }\r
451\r
452 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
453 if (ResponseCode != TPM_RC_SUCCESS) {\r
454 DEBUG ((EFI_D_ERROR, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
455 }\r
456 switch (ResponseCode) {\r
457 case TPM_RC_SUCCESS:\r
458 // return data\r
459 break;\r
460 case TPM_RC_ATTRIBUTES:\r
461 case TPM_RC_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex:\r
462 return EFI_UNSUPPORTED;\r
463 case TPM_RC_NV_AUTHORIZATION:\r
464 return EFI_SECURITY_VIOLATION;\r
465 case TPM_RC_HANDLE + RC_NV_UndefineSpace_nvIndex: // TPM_RC_NV_DEFINED:\r
466 return EFI_NOT_FOUND;\r
467 case TPM_RC_HANDLE + RC_NV_UndefineSpace_authHandle: // TPM_RC_NV_DEFINED:\r
468 return EFI_INVALID_PARAMETER;\r
469 case TPM_RC_VALUE + RC_NV_UndefineSpace_authHandle:\r
470 case TPM_RC_VALUE + RC_NV_UndefineSpace_nvIndex:\r
471 return EFI_INVALID_PARAMETER;\r
472 default:\r
473 return EFI_DEVICE_ERROR;\r
474 }\r
475\r
476 return EFI_SUCCESS;\r
477}\r
478\r
479/**\r
480 This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().\r
481\r
482 @param[in] AuthHandle the handle indicating the source of the authorization value.\r
483 @param[in] NvIndex The index to be read.\r
484 @param[in] AuthSession Auth Session context\r
485 @param[in] Size Number of bytes to read.\r
486 @param[in] Offset Byte offset into the area.\r
487 @param[in,out] OutData The data read.\r
488 \r
489 @retval EFI_SUCCESS Operation completed successfully.\r
490 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
491 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
492**/\r
493EFI_STATUS\r
494EFIAPI\r
495Tpm2NvRead (\r
496 IN TPMI_RH_NV_AUTH AuthHandle,\r
497 IN TPMI_RH_NV_INDEX NvIndex,\r
498 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
499 IN UINT16 Size,\r
500 IN UINT16 Offset,\r
501 IN OUT TPM2B_MAX_BUFFER *OutData\r
502 )\r
503{\r
504 EFI_STATUS Status;\r
505 TPM2_NV_READ_COMMAND SendBuffer;\r
506 TPM2_NV_READ_RESPONSE RecvBuffer;\r
507 UINT32 SendBufferSize;\r
508 UINT32 RecvBufferSize;\r
509 UINT8 *Buffer;\r
510 UINT32 SessionInfoSize;\r
511 TPM_RC ResponseCode;\r
512\r
513 //\r
514 // Construct command\r
515 //\r
516 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
517 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Read);\r
518\r
519 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
520 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
521\r
522 //\r
523 // Add in Auth session\r
524 //\r
525 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
526\r
527 // sessionInfoSize\r
528 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
529 Buffer += SessionInfoSize;\r
530 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
531\r
532 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Size));\r
533 Buffer += sizeof(UINT16);\r
534 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));\r
535 Buffer += sizeof(UINT16);\r
536\r
537 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
538 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
539\r
540 //\r
541 // send Tpm command\r
542 //\r
543 RecvBufferSize = sizeof (RecvBuffer);\r
544 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
545 if (EFI_ERROR (Status)) {\r
546 return Status;\r
547 }\r
548\r
549 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
550 DEBUG ((EFI_D_ERROR, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
551 return EFI_DEVICE_ERROR;\r
552 }\r
553 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
554 if (ResponseCode != TPM_RC_SUCCESS) {\r
555 DEBUG ((EFI_D_ERROR, "Tpm2NvRead - responseCode - %x\n", ResponseCode));\r
556 }\r
557 switch (ResponseCode) {\r
558 case TPM_RC_SUCCESS:\r
559 // return data\r
560 break;\r
561 case TPM_RC_NV_AUTHORIZATION:\r
562 return EFI_SECURITY_VIOLATION;\r
563 case TPM_RC_NV_LOCKED:\r
564 return EFI_ACCESS_DENIED;\r
565 case TPM_RC_NV_RANGE:\r
566 return EFI_BAD_BUFFER_SIZE;\r
567 case TPM_RC_NV_UNINITIALIZED:\r
568 return EFI_NOT_READY;\r
569 case TPM_RC_HANDLE + RC_NV_Read_nvIndex: // TPM_RC_NV_DEFINED:\r
570 return EFI_NOT_FOUND;\r
571 case TPM_RC_HANDLE + RC_NV_Read_authHandle: // TPM_RC_NV_DEFINED:\r
572 return EFI_INVALID_PARAMETER;\r
573 case TPM_RC_VALUE + RC_NV_Read_nvIndex:\r
574 case TPM_RC_VALUE + RC_NV_Read_authHandle:\r
575 return EFI_INVALID_PARAMETER;\r
576 case TPM_RC_BAD_AUTH + RC_NV_Read_authHandle + TPM_RC_S:\r
577 return EFI_INVALID_PARAMETER;\r
578 case TPM_RC_AUTH_UNAVAILABLE:\r
579 return EFI_INVALID_PARAMETER;\r
580 case TPM_RC_AUTH_FAIL + RC_NV_Read_authHandle + TPM_RC_S:\r
581 return EFI_INVALID_PARAMETER;\r
582 default:\r
583 return EFI_DEVICE_ERROR;\r
584 case TPM_RC_ATTRIBUTES + RC_NV_Read_authHandle + TPM_RC_S:\r
585 return EFI_UNSUPPORTED;\r
586 }\r
587\r
588 //\r
589 // Return the response\r
590 //\r
591 OutData->size = SwapBytes16 (RecvBuffer.Data.size);\r
592 CopyMem (OutData->buffer, &RecvBuffer.Data.buffer, OutData->size);\r
593 \r
594 return EFI_SUCCESS;\r
595}\r
596\r
597/**\r
598 This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().\r
599\r
600 @param[in] AuthHandle the handle indicating the source of the authorization value.\r
601 @param[in] NvIndex The NV Index of the area to write.\r
602 @param[in] AuthSession Auth Session context\r
603 @param[in] InData The data to write.\r
604 @param[in] Offset The offset into the NV Area.\r
605 \r
606 @retval EFI_SUCCESS Operation completed successfully.\r
607 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
608 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
609**/\r
610EFI_STATUS\r
611EFIAPI\r
612Tpm2NvWrite (\r
613 IN TPMI_RH_NV_AUTH AuthHandle,\r
614 IN TPMI_RH_NV_INDEX NvIndex,\r
615 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL\r
616 IN TPM2B_MAX_BUFFER *InData,\r
617 IN UINT16 Offset\r
618 )\r
619{\r
620 EFI_STATUS Status;\r
621 TPM2_NV_WRITE_COMMAND SendBuffer;\r
622 TPM2_NV_WRITE_RESPONSE RecvBuffer;\r
623 UINT32 SendBufferSize;\r
624 UINT32 RecvBufferSize;\r
625 UINT8 *Buffer;\r
626 UINT32 SessionInfoSize;\r
627 TPM_RC ResponseCode;\r
628\r
629 //\r
630 // Construct command\r
631 //\r
632 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
633 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_Write);\r
634\r
635 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
636 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
637\r
638 //\r
639 // Add in Auth session\r
640 //\r
641 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
642\r
643 // sessionInfoSize\r
644 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
645 Buffer += SessionInfoSize;\r
646 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
647\r
648 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));\r
649 Buffer += sizeof(UINT16);\r
650 CopyMem (Buffer, InData->buffer, InData->size);\r
651 Buffer += InData->size;\r
652 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Offset));\r
653 Buffer += sizeof(UINT16);\r
654\r
655 SendBufferSize = (UINT32) (Buffer - (UINT8 *)&SendBuffer);\r
656 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
657\r
658 //\r
659 // send Tpm command\r
660 //\r
661 RecvBufferSize = sizeof (RecvBuffer);\r
662 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
663 if (EFI_ERROR (Status)) {\r
664 return Status;\r
665 }\r
666\r
667 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
668 DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize));\r
669 return EFI_DEVICE_ERROR;\r
670 }\r
671 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
672 if (ResponseCode != TPM_RC_SUCCESS) {\r
673 DEBUG ((EFI_D_ERROR, "Tpm2NvWrite - responseCode - %x\n", ResponseCode));\r
674 }\r
675 switch (ResponseCode) {\r
676 case TPM_RC_SUCCESS:\r
677 return EFI_SUCCESS;\r
678 case TPM_RC_ATTRIBUTES:\r
679 return EFI_UNSUPPORTED;\r
680 case TPM_RC_NV_AUTHORIZATION:\r
681 return EFI_SECURITY_VIOLATION;\r
682 case TPM_RC_NV_LOCKED:\r
683 return EFI_ACCESS_DENIED;\r
684 case TPM_RC_NV_RANGE:\r
685 return EFI_BAD_BUFFER_SIZE;\r
686 case TPM_RC_HANDLE + RC_NV_Write_nvIndex: // TPM_RC_NV_DEFINED:\r
687 return EFI_NOT_FOUND;\r
688 case TPM_RC_HANDLE + RC_NV_Write_authHandle: // TPM_RC_NV_DEFINED:\r
689 return EFI_INVALID_PARAMETER;\r
690 case TPM_RC_VALUE + RC_NV_Write_nvIndex:\r
691 case TPM_RC_VALUE + RC_NV_Write_authHandle:\r
692 return EFI_INVALID_PARAMETER;\r
693 case TPM_RC_BAD_AUTH + RC_NV_Write_authHandle + TPM_RC_S:\r
694 return EFI_INVALID_PARAMETER;\r
695 case TPM_RC_AUTH_UNAVAILABLE:\r
696 return EFI_INVALID_PARAMETER;\r
697 case TPM_RC_AUTH_FAIL + RC_NV_Write_authHandle + TPM_RC_S:\r
698 return EFI_INVALID_PARAMETER;\r
699 default:\r
700 return EFI_DEVICE_ERROR;\r
701 case TPM_RC_ATTRIBUTES + RC_NV_Write_authHandle + TPM_RC_S:\r
702 return EFI_UNSUPPORTED;\r
703 }\r
704}\r
705\r
706/**\r
707 This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).\r
708\r
709 @param[in] AuthHandle the handle indicating the source of the authorization value.\r
710 @param[in] NvIndex The NV Index of the area to lock.\r
711 @param[in] AuthSession Auth Session context\r
712\r
713 @retval EFI_SUCCESS Operation completed successfully.\r
714 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
715 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
716**/\r
717EFI_STATUS\r
718EFIAPI\r
719Tpm2NvReadLock (\r
720 IN TPMI_RH_NV_AUTH AuthHandle,\r
721 IN TPMI_RH_NV_INDEX NvIndex,\r
722 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL\r
723 )\r
724{\r
725 EFI_STATUS Status;\r
726 TPM2_NV_READLOCK_COMMAND SendBuffer;\r
727 TPM2_NV_READLOCK_RESPONSE RecvBuffer;\r
728 UINT32 SendBufferSize;\r
729 UINT32 RecvBufferSize;\r
730 UINT8 *Buffer;\r
731 UINT32 SessionInfoSize;\r
732 TPM_RC ResponseCode;\r
733\r
734 //\r
735 // Construct command\r
736 //\r
737 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
738 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_ReadLock);\r
739\r
740 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
741 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
742\r
743 //\r
744 // Add in Auth session\r
745 //\r
746 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
747\r
748 // sessionInfoSize\r
749 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
750 Buffer += SessionInfoSize;\r
751 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
752\r
753 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
754 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
755\r
756 //\r
757 // send Tpm command\r
758 //\r
759 RecvBufferSize = sizeof (RecvBuffer);\r
760 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
761 if (EFI_ERROR (Status)) {\r
762 return Status;\r
763 }\r
764\r
765 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
766 DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize));\r
767 return EFI_DEVICE_ERROR;\r
768 }\r
769\r
770 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
771 if (ResponseCode != TPM_RC_SUCCESS) {\r
772 DEBUG ((EFI_D_ERROR, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
773 }\r
774 switch (ResponseCode) {\r
775 case TPM_RC_SUCCESS:\r
776 // return data\r
777 break;\r
778 default:\r
779 return EFI_DEVICE_ERROR;\r
780 }\r
781\r
782 return EFI_SUCCESS;\r
783}\r
784\r
785/**\r
786 This command may be used to inhibit further writes of the Index.\r
787\r
788 @param[in] AuthHandle the handle indicating the source of the authorization value.\r
789 @param[in] NvIndex The NV Index of the area to lock.\r
790 @param[in] AuthSession Auth Session context\r
791\r
792 @retval EFI_SUCCESS Operation completed successfully.\r
793 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
794 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
795**/\r
796EFI_STATUS\r
797EFIAPI\r
798Tpm2NvWriteLock (\r
799 IN TPMI_RH_NV_AUTH AuthHandle,\r
800 IN TPMI_RH_NV_INDEX NvIndex,\r
801 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL\r
802 )\r
803{\r
804 EFI_STATUS Status;\r
805 TPM2_NV_WRITELOCK_COMMAND SendBuffer;\r
806 TPM2_NV_WRITELOCK_RESPONSE RecvBuffer;\r
807 UINT32 SendBufferSize;\r
808 UINT32 RecvBufferSize;\r
809 UINT8 *Buffer;\r
810 UINT32 SessionInfoSize;\r
811 TPM_RC ResponseCode;\r
812\r
813 //\r
814 // Construct command\r
815 //\r
816 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
817 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_WriteLock);\r
818\r
819 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
820 SendBuffer.NvIndex = SwapBytes32 (NvIndex);\r
821\r
822 //\r
823 // Add in Auth session\r
824 //\r
825 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
826\r
827 // sessionInfoSize\r
828 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
829 Buffer += SessionInfoSize;\r
830 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
831\r
832 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
833 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
834\r
835 //\r
836 // send Tpm command\r
837 //\r
838 RecvBufferSize = sizeof (RecvBuffer);\r
839 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
840 if (EFI_ERROR (Status)) {\r
841 return Status;\r
842 }\r
843\r
844 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
845 DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));\r
846 return EFI_DEVICE_ERROR;\r
847 }\r
848\r
849 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
850 if (ResponseCode != TPM_RC_SUCCESS) {\r
851 DEBUG ((EFI_D_ERROR, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
852 }\r
853 switch (ResponseCode) {\r
854 case TPM_RC_SUCCESS:\r
855 // return data\r
856 break;\r
857 default:\r
858 return EFI_DEVICE_ERROR;\r
859 }\r
860\r
861 return EFI_SUCCESS;\r
862}\r
863\r
864/**\r
865 The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.\r
866\r
867 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.\r
868 @param[in] AuthSession Auth Session context\r
869\r
870 @retval EFI_SUCCESS Operation completed successfully.\r
871 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
872 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.\r
873**/\r
874EFI_STATUS\r
875EFIAPI\r
876Tpm2NvGlobalWriteLock (\r
877 IN TPMI_RH_PROVISION AuthHandle,\r
878 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL\r
879 )\r
880{\r
881 EFI_STATUS Status;\r
882 TPM2_NV_GLOBALWRITELOCK_COMMAND SendBuffer;\r
883 TPM2_NV_GLOBALWRITELOCK_RESPONSE RecvBuffer;\r
884 UINT32 SendBufferSize;\r
885 UINT32 RecvBufferSize;\r
886 UINT8 *Buffer;\r
887 UINT32 SessionInfoSize;\r
888 TPM_RC ResponseCode;\r
889\r
890 //\r
891 // Construct command\r
892 //\r
893 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
894 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_NV_GlobalWriteLock);\r
895\r
896 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);\r
897\r
898 //\r
899 // Add in Auth session\r
900 //\r
901 Buffer = (UINT8 *)&SendBuffer.AuthSession;\r
902\r
903 // sessionInfoSize\r
904 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
905 Buffer += SessionInfoSize;\r
906 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
907\r
908 SendBufferSize = (UINT32)(Buffer - (UINT8 *)&SendBuffer);\r
909 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
910\r
911 //\r
912 // send Tpm command\r
913 //\r
914 RecvBufferSize = sizeof (RecvBuffer);\r
915 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
916 if (EFI_ERROR (Status)) {\r
917 return Status;\r
918 }\r
919\r
920 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
921 DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize));\r
922 return EFI_DEVICE_ERROR;\r
923 }\r
924\r
925 ResponseCode = SwapBytes32(RecvBuffer.Header.responseCode);\r
926 if (ResponseCode != TPM_RC_SUCCESS) {\r
927 DEBUG ((EFI_D_ERROR, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
928 }\r
929 switch (ResponseCode) {\r
930 case TPM_RC_SUCCESS:\r
931 // return data\r
932 break;\r
933 default:\r
934 return EFI_DEVICE_ERROR;\r
935 }\r
936\r
937 return EFI_SUCCESS;\r
938}\r