2 Implement TPM2 NVStorage related command.
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <IndustryStandard/UefiTcgPlatform.h>
10 #include <Library/Tpm2CommandLib.h>
11 #include <Library/Tpm2DeviceLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/BaseLib.h>
14 #include <Library/DebugLib.h>
18 #define RC_NV_ReadPublic_nvIndex (TPM_RC_H + TPM_RC_1)
20 #define RC_NV_DefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
21 #define RC_NV_DefineSpace_auth (TPM_RC_P + TPM_RC_1)
22 #define RC_NV_DefineSpace_publicInfo (TPM_RC_P + TPM_RC_2)
24 #define RC_NV_UndefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
25 #define RC_NV_UndefineSpace_nvIndex (TPM_RC_H + TPM_RC_2)
27 #define RC_NV_Read_authHandle (TPM_RC_H + TPM_RC_1)
28 #define RC_NV_Read_nvIndex (TPM_RC_H + TPM_RC_2)
29 #define RC_NV_Read_size (TPM_RC_P + TPM_RC_1)
30 #define RC_NV_Read_offset (TPM_RC_P + TPM_RC_2)
32 #define RC_NV_Write_authHandle (TPM_RC_H + TPM_RC_1)
33 #define RC_NV_Write_nvIndex (TPM_RC_H + TPM_RC_2)
34 #define RC_NV_Write_data (TPM_RC_P + TPM_RC_1)
35 #define RC_NV_Write_offset (TPM_RC_P + TPM_RC_2)
38 TPM2_COMMAND_HEADER Header
;
39 TPMI_RH_NV_INDEX NvIndex
;
40 } TPM2_NV_READPUBLIC_COMMAND
;
43 TPM2_RESPONSE_HEADER Header
;
44 TPM2B_NV_PUBLIC NvPublic
;
46 } TPM2_NV_READPUBLIC_RESPONSE
;
49 TPM2_COMMAND_HEADER Header
;
50 TPMI_RH_PROVISION AuthHandle
;
51 UINT32 AuthSessionSize
;
52 TPMS_AUTH_COMMAND AuthSession
;
54 TPM2B_NV_PUBLIC NvPublic
;
55 } TPM2_NV_DEFINESPACE_COMMAND
;
58 TPM2_RESPONSE_HEADER Header
;
59 UINT32 AuthSessionSize
;
60 TPMS_AUTH_RESPONSE AuthSession
;
61 } TPM2_NV_DEFINESPACE_RESPONSE
;
64 TPM2_COMMAND_HEADER Header
;
65 TPMI_RH_PROVISION AuthHandle
;
66 TPMI_RH_NV_INDEX NvIndex
;
67 UINT32 AuthSessionSize
;
68 TPMS_AUTH_COMMAND AuthSession
;
69 } TPM2_NV_UNDEFINESPACE_COMMAND
;
72 TPM2_RESPONSE_HEADER Header
;
73 UINT32 AuthSessionSize
;
74 TPMS_AUTH_RESPONSE AuthSession
;
75 } TPM2_NV_UNDEFINESPACE_RESPONSE
;
78 TPM2_COMMAND_HEADER Header
;
79 TPMI_RH_NV_AUTH AuthHandle
;
80 TPMI_RH_NV_INDEX NvIndex
;
81 UINT32 AuthSessionSize
;
82 TPMS_AUTH_COMMAND AuthSession
;
85 } TPM2_NV_READ_COMMAND
;
88 TPM2_RESPONSE_HEADER Header
;
89 UINT32 AuthSessionSize
;
90 TPM2B_MAX_BUFFER Data
;
91 TPMS_AUTH_RESPONSE AuthSession
;
92 } TPM2_NV_READ_RESPONSE
;
95 TPM2_COMMAND_HEADER Header
;
96 TPMI_RH_NV_AUTH AuthHandle
;
97 TPMI_RH_NV_INDEX NvIndex
;
98 UINT32 AuthSessionSize
;
99 TPMS_AUTH_COMMAND AuthSession
;
100 TPM2B_MAX_BUFFER Data
;
102 } TPM2_NV_WRITE_COMMAND
;
105 TPM2_RESPONSE_HEADER Header
;
106 UINT32 AuthSessionSize
;
107 TPMS_AUTH_RESPONSE AuthSession
;
108 } TPM2_NV_WRITE_RESPONSE
;
111 TPM2_COMMAND_HEADER Header
;
112 TPMI_RH_NV_AUTH AuthHandle
;
113 TPMI_RH_NV_INDEX NvIndex
;
114 UINT32 AuthSessionSize
;
115 TPMS_AUTH_COMMAND AuthSession
;
116 } TPM2_NV_READLOCK_COMMAND
;
119 TPM2_RESPONSE_HEADER Header
;
120 UINT32 AuthSessionSize
;
121 TPMS_AUTH_RESPONSE AuthSession
;
122 } TPM2_NV_READLOCK_RESPONSE
;
125 TPM2_COMMAND_HEADER Header
;
126 TPMI_RH_NV_AUTH AuthHandle
;
127 TPMI_RH_NV_INDEX NvIndex
;
128 UINT32 AuthSessionSize
;
129 TPMS_AUTH_COMMAND AuthSession
;
130 } TPM2_NV_WRITELOCK_COMMAND
;
133 TPM2_RESPONSE_HEADER Header
;
134 UINT32 AuthSessionSize
;
135 TPMS_AUTH_RESPONSE AuthSession
;
136 } TPM2_NV_WRITELOCK_RESPONSE
;
139 TPM2_COMMAND_HEADER Header
;
140 TPMI_RH_PROVISION AuthHandle
;
141 UINT32 AuthSessionSize
;
142 TPMS_AUTH_COMMAND AuthSession
;
143 } TPM2_NV_GLOBALWRITELOCK_COMMAND
;
146 TPM2_RESPONSE_HEADER Header
;
147 UINT32 AuthSessionSize
;
148 TPMS_AUTH_RESPONSE AuthSession
;
149 } TPM2_NV_GLOBALWRITELOCK_RESPONSE
;
154 This command is used to read the public area and Name of an NV Index.
156 @param[in] NvIndex The NV Index.
157 @param[out] NvPublic The public area of the index.
158 @param[out] NvName The Name of the nvIndex.
160 @retval EFI_SUCCESS Operation completed successfully.
161 @retval EFI_DEVICE_ERROR The command was unsuccessful.
162 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
167 IN TPMI_RH_NV_INDEX NvIndex
,
168 OUT TPM2B_NV_PUBLIC
*NvPublic
,
169 OUT TPM2B_NAME
*NvName
173 TPM2_NV_READPUBLIC_COMMAND SendBuffer
;
174 TPM2_NV_READPUBLIC_RESPONSE RecvBuffer
;
175 UINT32 SendBufferSize
;
176 UINT32 RecvBufferSize
;
185 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_NO_SESSIONS
);
186 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_ReadPublic
);
188 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
190 SendBufferSize
= (UINT32
)sizeof (SendBuffer
);
191 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
196 RecvBufferSize
= sizeof (RecvBuffer
);
197 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
198 if (EFI_ERROR (Status
)) {
202 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
203 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
204 return EFI_DEVICE_ERROR
;
207 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
208 if (ResponseCode
!= TPM_RC_SUCCESS
) {
209 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
212 switch (ResponseCode
) {
216 case TPM_RC_HANDLE
+ RC_NV_ReadPublic_nvIndex
: // TPM_RC_NV_DEFINED:
217 return EFI_NOT_FOUND
;
218 case TPM_RC_VALUE
+ RC_NV_ReadPublic_nvIndex
:
219 return EFI_INVALID_PARAMETER
;
221 return EFI_DEVICE_ERROR
;
224 if (RecvBufferSize
<= sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + sizeof (UINT16
)) {
225 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
226 return EFI_NOT_FOUND
;
232 NvPublicSize
= SwapBytes16 (RecvBuffer
.NvPublic
.size
);
233 if (NvPublicSize
> sizeof (TPMS_NV_PUBLIC
)) {
234 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - NvPublic.size error %x\n", NvPublicSize
));
235 return EFI_DEVICE_ERROR
;
238 NvNameSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + NvPublicSize
)));
239 if (NvNameSize
> sizeof (TPMU_NAME
)) {
240 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - NvNameSize error %x\n", NvNameSize
));
241 return EFI_DEVICE_ERROR
;
244 if (RecvBufferSize
!= sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + NvPublicSize
+ sizeof (UINT16
) + NvNameSize
) {
245 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - NvPublicSize %x\n", RecvBufferSize
));
246 return EFI_NOT_FOUND
;
250 // Return the response
252 CopyMem (NvPublic
, &RecvBuffer
.NvPublic
, sizeof (UINT16
) + NvPublicSize
);
253 NvPublic
->size
= NvPublicSize
;
254 NvPublic
->nvPublic
.nvIndex
= SwapBytes32 (NvPublic
->nvPublic
.nvIndex
);
255 NvPublic
->nvPublic
.nameAlg
= SwapBytes16 (NvPublic
->nvPublic
.nameAlg
);
256 WriteUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
, SwapBytes32 (ReadUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
)));
257 NvPublic
->nvPublic
.authPolicy
.size
= SwapBytes16 (NvPublic
->nvPublic
.authPolicy
.size
);
258 Buffer
= (UINT8
*)&RecvBuffer
.NvPublic
.nvPublic
.authPolicy
;
259 Buffer
+= sizeof (UINT16
) + NvPublic
->nvPublic
.authPolicy
.size
;
260 NvPublic
->nvPublic
.dataSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
262 CopyMem (NvName
->name
, (UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + NvPublicSize
+ sizeof (UINT16
), NvNameSize
);
263 NvName
->size
= NvNameSize
;
269 This command defines the attributes of an NV Index and causes the TPM to
270 reserve space to hold the data associated with the index.
271 If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.
273 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
274 @param[in] AuthSession Auth Session context
275 @param[in] Auth The authorization data.
276 @param[in] NvPublic The public area of the index.
278 @retval EFI_SUCCESS Operation completed successfully.
279 @retval EFI_DEVICE_ERROR The command was unsuccessful.
280 @retval EFI_ALREADY_STARTED The command was returned successfully, but NvIndex is already defined.
285 IN TPMI_RH_PROVISION AuthHandle
,
286 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
,
288 IN TPM2B_NV_PUBLIC
*NvPublic
292 TPM2_NV_DEFINESPACE_COMMAND SendBuffer
;
293 TPM2_NV_DEFINESPACE_RESPONSE RecvBuffer
;
294 UINT32 SendBufferSize
;
295 UINT32 RecvBufferSize
;
298 UINT32 SessionInfoSize
;
304 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
305 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_DefineSpace
);
306 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
309 // Add in Auth session
311 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
314 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
315 Buffer
+= SessionInfoSize
;
316 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
321 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Auth
->size
));
322 Buffer
+= sizeof (UINT16
);
323 CopyMem (Buffer
, Auth
->buffer
, Auth
->size
);
324 Buffer
+= Auth
->size
;
329 NvPublicSize
= NvPublic
->size
;
331 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublicSize
));
332 Buffer
+= sizeof (UINT16
);
333 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (NvPublic
->nvPublic
.nvIndex
));
334 Buffer
+= sizeof (UINT32
);
335 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.nameAlg
));
336 Buffer
+= sizeof (UINT16
);
337 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (ReadUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
)));
338 Buffer
+= sizeof (UINT32
);
339 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.authPolicy
.size
));
340 Buffer
+= sizeof (UINT16
);
341 CopyMem (Buffer
, NvPublic
->nvPublic
.authPolicy
.buffer
, NvPublic
->nvPublic
.authPolicy
.size
);
342 Buffer
+= NvPublic
->nvPublic
.authPolicy
.size
;
343 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.dataSize
));
344 Buffer
+= sizeof (UINT16
);
346 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
347 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
352 RecvBufferSize
= sizeof (RecvBuffer
);
353 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
354 if (EFI_ERROR (Status
)) {
358 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
359 DEBUG ((DEBUG_ERROR
, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize
));
360 Status
= EFI_DEVICE_ERROR
;
364 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
365 if (ResponseCode
!= TPM_RC_SUCCESS
) {
366 DEBUG ((DEBUG_ERROR
, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
369 switch (ResponseCode
) {
373 case TPM_RC_SIZE
+ RC_NV_DefineSpace_publicInfo
:
374 case TPM_RC_SIZE
+ RC_NV_DefineSpace_auth
:
375 Status
= EFI_BAD_BUFFER_SIZE
;
377 case TPM_RC_ATTRIBUTES
:
378 case TPM_RC_ATTRIBUTES
+ RC_NV_DefineSpace_publicInfo
:
379 Status
= EFI_UNSUPPORTED
;
381 case TPM_RC_ATTRIBUTES
+ RC_NV_DefineSpace_authHandle
:
382 Status
= EFI_INVALID_PARAMETER
;
384 case TPM_RC_NV_DEFINED
:
385 Status
= EFI_ALREADY_STARTED
;
387 case TPM_RC_VALUE
+ RC_NV_DefineSpace_publicInfo
:
388 case TPM_RC_VALUE
+ RC_NV_DefineSpace_authHandle
:
389 Status
= EFI_INVALID_PARAMETER
;
391 case TPM_RC_NV_SPACE
:
392 Status
= EFI_OUT_OF_RESOURCES
;
395 Status
= EFI_DEVICE_ERROR
;
401 // Clear AuthSession Content
403 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
404 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
409 This command removes an index from the TPM.
411 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
412 @param[in] NvIndex The NV Index.
413 @param[in] AuthSession Auth Session context
415 @retval EFI_SUCCESS Operation completed successfully.
416 @retval EFI_DEVICE_ERROR The command was unsuccessful.
417 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
421 Tpm2NvUndefineSpace (
422 IN TPMI_RH_PROVISION AuthHandle
,
423 IN TPMI_RH_NV_INDEX NvIndex
,
424 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
428 TPM2_NV_UNDEFINESPACE_COMMAND SendBuffer
;
429 TPM2_NV_UNDEFINESPACE_RESPONSE RecvBuffer
;
430 UINT32 SendBufferSize
;
431 UINT32 RecvBufferSize
;
433 UINT32 SessionInfoSize
;
439 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
440 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_UndefineSpace
);
442 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
443 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
446 // Add in Auth session
448 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
451 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
452 Buffer
+= SessionInfoSize
;
453 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
455 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
456 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
461 RecvBufferSize
= sizeof (RecvBuffer
);
462 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
463 if (EFI_ERROR (Status
)) {
467 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
468 DEBUG ((DEBUG_ERROR
, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize
));
469 Status
= EFI_DEVICE_ERROR
;
473 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
474 if (ResponseCode
!= TPM_RC_SUCCESS
) {
475 DEBUG ((DEBUG_ERROR
, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
478 switch (ResponseCode
) {
482 case TPM_RC_ATTRIBUTES
:
483 case TPM_RC_ATTRIBUTES
+ RC_NV_UndefineSpace_nvIndex
:
484 Status
= EFI_UNSUPPORTED
;
486 case TPM_RC_NV_AUTHORIZATION
:
487 Status
= EFI_SECURITY_VIOLATION
;
489 case TPM_RC_HANDLE
+ RC_NV_UndefineSpace_nvIndex
: // TPM_RC_NV_DEFINED:
490 Status
= EFI_NOT_FOUND
;
492 case TPM_RC_HANDLE
+ RC_NV_UndefineSpace_authHandle
: // TPM_RC_NV_DEFINED:
493 Status
= EFI_INVALID_PARAMETER
;
495 case TPM_RC_VALUE
+ RC_NV_UndefineSpace_authHandle
:
496 case TPM_RC_VALUE
+ RC_NV_UndefineSpace_nvIndex
:
497 Status
= EFI_INVALID_PARAMETER
;
500 Status
= EFI_DEVICE_ERROR
;
506 // Clear AuthSession Content
508 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
509 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
514 This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().
516 @param[in] AuthHandle the handle indicating the source of the authorization value.
517 @param[in] NvIndex The index to be read.
518 @param[in] AuthSession Auth Session context
519 @param[in] Size Number of bytes to read.
520 @param[in] Offset Byte offset into the area.
521 @param[in,out] OutData The data read.
523 @retval EFI_SUCCESS Operation completed successfully.
524 @retval EFI_DEVICE_ERROR The command was unsuccessful.
525 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
530 IN TPMI_RH_NV_AUTH AuthHandle
,
531 IN TPMI_RH_NV_INDEX NvIndex
,
532 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
,
535 IN OUT TPM2B_MAX_BUFFER
*OutData
539 TPM2_NV_READ_COMMAND SendBuffer
;
540 TPM2_NV_READ_RESPONSE RecvBuffer
;
541 UINT32 SendBufferSize
;
542 UINT32 RecvBufferSize
;
544 UINT32 SessionInfoSize
;
550 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
551 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_Read
);
553 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
554 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
557 // Add in Auth session
559 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
562 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
563 Buffer
+= SessionInfoSize
;
564 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
566 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Size
));
567 Buffer
+= sizeof (UINT16
);
568 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Offset
));
569 Buffer
+= sizeof (UINT16
);
571 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
572 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
577 RecvBufferSize
= sizeof (RecvBuffer
);
578 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
579 if (EFI_ERROR (Status
)) {
583 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
584 DEBUG ((DEBUG_ERROR
, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
585 Status
= EFI_DEVICE_ERROR
;
589 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
590 if (ResponseCode
!= TPM_RC_SUCCESS
) {
591 DEBUG ((DEBUG_ERROR
, "Tpm2NvRead - responseCode - %x\n", ResponseCode
));
594 switch (ResponseCode
) {
598 case TPM_RC_NV_AUTHORIZATION
:
599 Status
= EFI_SECURITY_VIOLATION
;
601 case TPM_RC_NV_LOCKED
:
602 Status
= EFI_ACCESS_DENIED
;
604 case TPM_RC_NV_RANGE
:
605 Status
= EFI_BAD_BUFFER_SIZE
;
607 case TPM_RC_NV_UNINITIALIZED
:
608 Status
= EFI_NOT_READY
;
610 case TPM_RC_HANDLE
+ RC_NV_Read_nvIndex
: // TPM_RC_NV_DEFINED:
611 Status
= EFI_NOT_FOUND
;
613 case TPM_RC_HANDLE
+ RC_NV_Read_authHandle
: // TPM_RC_NV_DEFINED:
614 Status
= EFI_INVALID_PARAMETER
;
616 case TPM_RC_VALUE
+ RC_NV_Read_nvIndex
:
617 case TPM_RC_VALUE
+ RC_NV_Read_authHandle
:
618 Status
= EFI_INVALID_PARAMETER
;
620 case TPM_RC_BAD_AUTH
+ RC_NV_Read_authHandle
+ TPM_RC_S
:
621 Status
= EFI_INVALID_PARAMETER
;
623 case TPM_RC_AUTH_UNAVAILABLE
:
624 Status
= EFI_INVALID_PARAMETER
;
626 case TPM_RC_AUTH_FAIL
+ RC_NV_Read_authHandle
+ TPM_RC_S
:
627 Status
= EFI_INVALID_PARAMETER
;
629 case TPM_RC_ATTRIBUTES
+ RC_NV_Read_authHandle
+ TPM_RC_S
:
630 Status
= EFI_UNSUPPORTED
;
633 Status
= EFI_DEVICE_ERROR
;
637 if (Status
!= EFI_SUCCESS
) {
642 // Return the response
644 OutData
->size
= SwapBytes16 (RecvBuffer
.Data
.size
);
645 if (OutData
->size
> MAX_DIGEST_BUFFER
) {
646 DEBUG ((DEBUG_ERROR
, "Tpm2NvRead - OutData->size error %x\n", OutData
->size
));
647 Status
= EFI_DEVICE_ERROR
;
651 CopyMem (OutData
->buffer
, &RecvBuffer
.Data
.buffer
, OutData
->size
);
655 // Clear AuthSession Content
657 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
658 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
663 This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
665 @param[in] AuthHandle the handle indicating the source of the authorization value.
666 @param[in] NvIndex The NV Index of the area to write.
667 @param[in] AuthSession Auth Session context
668 @param[in] InData The data to write.
669 @param[in] Offset The offset into the NV Area.
671 @retval EFI_SUCCESS Operation completed successfully.
672 @retval EFI_DEVICE_ERROR The command was unsuccessful.
673 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
678 IN TPMI_RH_NV_AUTH AuthHandle
,
679 IN TPMI_RH_NV_INDEX NvIndex
,
680 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
,
681 IN TPM2B_MAX_BUFFER
*InData
,
686 TPM2_NV_WRITE_COMMAND SendBuffer
;
687 TPM2_NV_WRITE_RESPONSE RecvBuffer
;
688 UINT32 SendBufferSize
;
689 UINT32 RecvBufferSize
;
691 UINT32 SessionInfoSize
;
697 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
698 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_Write
);
700 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
701 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
704 // Add in Auth session
706 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
709 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
710 Buffer
+= SessionInfoSize
;
711 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
713 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (InData
->size
));
714 Buffer
+= sizeof (UINT16
);
715 CopyMem (Buffer
, InData
->buffer
, InData
->size
);
716 Buffer
+= InData
->size
;
717 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Offset
));
718 Buffer
+= sizeof (UINT16
);
720 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
721 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
726 RecvBufferSize
= sizeof (RecvBuffer
);
727 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
728 if (EFI_ERROR (Status
)) {
732 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
733 DEBUG ((DEBUG_ERROR
, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize
));
734 Status
= EFI_DEVICE_ERROR
;
738 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
739 if (ResponseCode
!= TPM_RC_SUCCESS
) {
740 DEBUG ((DEBUG_ERROR
, "Tpm2NvWrite - responseCode - %x\n", ResponseCode
));
743 switch (ResponseCode
) {
747 case TPM_RC_ATTRIBUTES
:
748 Status
= EFI_UNSUPPORTED
;
750 case TPM_RC_NV_AUTHORIZATION
:
751 Status
= EFI_SECURITY_VIOLATION
;
753 case TPM_RC_NV_LOCKED
:
754 Status
= EFI_ACCESS_DENIED
;
756 case TPM_RC_NV_RANGE
:
757 Status
= EFI_BAD_BUFFER_SIZE
;
759 case TPM_RC_HANDLE
+ RC_NV_Write_nvIndex
: // TPM_RC_NV_DEFINED:
760 Status
= EFI_NOT_FOUND
;
762 case TPM_RC_HANDLE
+ RC_NV_Write_authHandle
: // TPM_RC_NV_DEFINED:
763 Status
= EFI_INVALID_PARAMETER
;
765 case TPM_RC_VALUE
+ RC_NV_Write_nvIndex
:
766 case TPM_RC_VALUE
+ RC_NV_Write_authHandle
:
767 Status
= EFI_INVALID_PARAMETER
;
769 case TPM_RC_BAD_AUTH
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
770 Status
= EFI_INVALID_PARAMETER
;
772 case TPM_RC_AUTH_UNAVAILABLE
:
773 Status
= EFI_INVALID_PARAMETER
;
775 case TPM_RC_AUTH_FAIL
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
776 Status
= EFI_INVALID_PARAMETER
;
778 case TPM_RC_ATTRIBUTES
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
779 Status
= EFI_UNSUPPORTED
;
782 Status
= EFI_DEVICE_ERROR
;
788 // Clear AuthSession Content
790 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
791 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
796 This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).
798 @param[in] AuthHandle the handle indicating the source of the authorization value.
799 @param[in] NvIndex The NV Index of the area to lock.
800 @param[in] AuthSession Auth Session context
802 @retval EFI_SUCCESS Operation completed successfully.
803 @retval EFI_DEVICE_ERROR The command was unsuccessful.
804 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
809 IN TPMI_RH_NV_AUTH AuthHandle
,
810 IN TPMI_RH_NV_INDEX NvIndex
,
811 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
815 TPM2_NV_READLOCK_COMMAND SendBuffer
;
816 TPM2_NV_READLOCK_RESPONSE RecvBuffer
;
817 UINT32 SendBufferSize
;
818 UINT32 RecvBufferSize
;
820 UINT32 SessionInfoSize
;
826 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
827 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_ReadLock
);
829 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
830 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
833 // Add in Auth session
835 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
838 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
839 Buffer
+= SessionInfoSize
;
840 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
842 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
843 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
848 RecvBufferSize
= sizeof (RecvBuffer
);
849 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
850 if (EFI_ERROR (Status
)) {
854 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
855 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
856 Status
= EFI_DEVICE_ERROR
;
860 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
861 if (ResponseCode
!= TPM_RC_SUCCESS
) {
862 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
865 switch (ResponseCode
) {
870 Status
= EFI_DEVICE_ERROR
;
876 // Clear AuthSession Content
878 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
879 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
884 This command may be used to inhibit further writes of the Index.
886 @param[in] AuthHandle the handle indicating the source of the authorization value.
887 @param[in] NvIndex The NV Index of the area to lock.
888 @param[in] AuthSession Auth Session context
890 @retval EFI_SUCCESS Operation completed successfully.
891 @retval EFI_DEVICE_ERROR The command was unsuccessful.
892 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
897 IN TPMI_RH_NV_AUTH AuthHandle
,
898 IN TPMI_RH_NV_INDEX NvIndex
,
899 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
903 TPM2_NV_WRITELOCK_COMMAND SendBuffer
;
904 TPM2_NV_WRITELOCK_RESPONSE RecvBuffer
;
905 UINT32 SendBufferSize
;
906 UINT32 RecvBufferSize
;
908 UINT32 SessionInfoSize
;
914 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
915 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_WriteLock
);
917 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
918 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
921 // Add in Auth session
923 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
926 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
927 Buffer
+= SessionInfoSize
;
928 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
930 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
931 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
936 RecvBufferSize
= sizeof (RecvBuffer
);
937 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
938 if (EFI_ERROR (Status
)) {
942 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
943 DEBUG ((DEBUG_ERROR
, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
944 Status
= EFI_DEVICE_ERROR
;
948 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
949 if (ResponseCode
!= TPM_RC_SUCCESS
) {
950 DEBUG ((DEBUG_ERROR
, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
953 switch (ResponseCode
) {
958 Status
= EFI_DEVICE_ERROR
;
964 // Clear AuthSession Content
966 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
967 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));
972 The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.
974 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
975 @param[in] AuthSession Auth Session context
977 @retval EFI_SUCCESS Operation completed successfully.
978 @retval EFI_DEVICE_ERROR The command was unsuccessful.
979 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
983 Tpm2NvGlobalWriteLock (
984 IN TPMI_RH_PROVISION AuthHandle
,
985 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
989 TPM2_NV_GLOBALWRITELOCK_COMMAND SendBuffer
;
990 TPM2_NV_GLOBALWRITELOCK_RESPONSE RecvBuffer
;
991 UINT32 SendBufferSize
;
992 UINT32 RecvBufferSize
;
994 UINT32 SessionInfoSize
;
1000 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
1001 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_NV_GlobalWriteLock
);
1003 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
1006 // Add in Auth session
1008 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
1011 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
1012 Buffer
+= SessionInfoSize
;
1013 SendBuffer
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
1015 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
1016 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
1021 RecvBufferSize
= sizeof (RecvBuffer
);
1022 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
1023 if (EFI_ERROR (Status
)) {
1027 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
1028 DEBUG ((DEBUG_ERROR
, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
1029 Status
= EFI_DEVICE_ERROR
;
1033 ResponseCode
= SwapBytes32 (RecvBuffer
.Header
.responseCode
);
1034 if (ResponseCode
!= TPM_RC_SUCCESS
) {
1035 DEBUG ((DEBUG_ERROR
, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
1038 switch (ResponseCode
) {
1039 case TPM_RC_SUCCESS
:
1043 Status
= EFI_DEVICE_ERROR
;
1049 // Clear AuthSession Content
1051 ZeroMem (&SendBuffer
, sizeof (SendBuffer
));
1052 ZeroMem (&RecvBuffer
, sizeof (RecvBuffer
));