2 Implement TPM2 NVStorage related command.
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <IndustryStandard/UefiTcgPlatform.h>
16 #include <Library/Tpm2CommandLib.h>
17 #include <Library/Tpm2DeviceLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
24 #define RC_NV_ReadPublic_nvIndex (TPM_RC_H + TPM_RC_1)
26 #define RC_NV_DefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
27 #define RC_NV_DefineSpace_auth (TPM_RC_P + TPM_RC_1)
28 #define RC_NV_DefineSpace_publicInfo (TPM_RC_P + TPM_RC_2)
30 #define RC_NV_UndefineSpace_authHandle (TPM_RC_H + TPM_RC_1)
31 #define RC_NV_UndefineSpace_nvIndex (TPM_RC_H + TPM_RC_2)
33 #define RC_NV_Read_authHandle (TPM_RC_H + TPM_RC_1)
34 #define RC_NV_Read_nvIndex (TPM_RC_H + TPM_RC_2)
35 #define RC_NV_Read_size (TPM_RC_P + TPM_RC_1)
36 #define RC_NV_Read_offset (TPM_RC_P + TPM_RC_2)
38 #define RC_NV_Write_authHandle (TPM_RC_H + TPM_RC_1)
39 #define RC_NV_Write_nvIndex (TPM_RC_H + TPM_RC_2)
40 #define RC_NV_Write_data (TPM_RC_P + TPM_RC_1)
41 #define RC_NV_Write_offset (TPM_RC_P + TPM_RC_2)
44 TPM2_COMMAND_HEADER Header
;
45 TPMI_RH_NV_INDEX NvIndex
;
46 } TPM2_NV_READPUBLIC_COMMAND
;
49 TPM2_RESPONSE_HEADER Header
;
50 TPM2B_NV_PUBLIC NvPublic
;
52 } TPM2_NV_READPUBLIC_RESPONSE
;
55 TPM2_COMMAND_HEADER Header
;
56 TPMI_RH_PROVISION AuthHandle
;
57 UINT32 AuthSessionSize
;
58 TPMS_AUTH_COMMAND AuthSession
;
60 TPM2B_NV_PUBLIC NvPublic
;
61 } TPM2_NV_DEFINESPACE_COMMAND
;
64 TPM2_RESPONSE_HEADER Header
;
65 UINT32 AuthSessionSize
;
66 TPMS_AUTH_RESPONSE AuthSession
;
67 } TPM2_NV_DEFINESPACE_RESPONSE
;
70 TPM2_COMMAND_HEADER Header
;
71 TPMI_RH_PROVISION AuthHandle
;
72 TPMI_RH_NV_INDEX NvIndex
;
73 UINT32 AuthSessionSize
;
74 TPMS_AUTH_COMMAND AuthSession
;
75 } TPM2_NV_UNDEFINESPACE_COMMAND
;
78 TPM2_RESPONSE_HEADER Header
;
79 UINT32 AuthSessionSize
;
80 TPMS_AUTH_RESPONSE AuthSession
;
81 } TPM2_NV_UNDEFINESPACE_RESPONSE
;
84 TPM2_COMMAND_HEADER Header
;
85 TPMI_RH_NV_AUTH AuthHandle
;
86 TPMI_RH_NV_INDEX NvIndex
;
87 UINT32 AuthSessionSize
;
88 TPMS_AUTH_COMMAND AuthSession
;
91 } TPM2_NV_READ_COMMAND
;
94 TPM2_RESPONSE_HEADER Header
;
95 UINT32 AuthSessionSize
;
96 TPM2B_MAX_BUFFER Data
;
97 TPMS_AUTH_RESPONSE AuthSession
;
98 } TPM2_NV_READ_RESPONSE
;
101 TPM2_COMMAND_HEADER Header
;
102 TPMI_RH_NV_AUTH AuthHandle
;
103 TPMI_RH_NV_INDEX NvIndex
;
104 UINT32 AuthSessionSize
;
105 TPMS_AUTH_COMMAND AuthSession
;
106 TPM2B_MAX_BUFFER Data
;
108 } TPM2_NV_WRITE_COMMAND
;
111 TPM2_RESPONSE_HEADER Header
;
112 UINT32 AuthSessionSize
;
113 TPMS_AUTH_RESPONSE AuthSession
;
114 } TPM2_NV_WRITE_RESPONSE
;
117 TPM2_COMMAND_HEADER Header
;
118 TPMI_RH_NV_AUTH AuthHandle
;
119 TPMI_RH_NV_INDEX NvIndex
;
120 UINT32 AuthSessionSize
;
121 TPMS_AUTH_COMMAND AuthSession
;
122 } TPM2_NV_READLOCK_COMMAND
;
125 TPM2_RESPONSE_HEADER Header
;
126 UINT32 AuthSessionSize
;
127 TPMS_AUTH_RESPONSE AuthSession
;
128 } TPM2_NV_READLOCK_RESPONSE
;
131 TPM2_COMMAND_HEADER Header
;
132 TPMI_RH_NV_AUTH AuthHandle
;
133 TPMI_RH_NV_INDEX NvIndex
;
134 UINT32 AuthSessionSize
;
135 TPMS_AUTH_COMMAND AuthSession
;
136 } TPM2_NV_WRITELOCK_COMMAND
;
139 TPM2_RESPONSE_HEADER Header
;
140 UINT32 AuthSessionSize
;
141 TPMS_AUTH_RESPONSE AuthSession
;
142 } TPM2_NV_WRITELOCK_RESPONSE
;
145 TPM2_COMMAND_HEADER Header
;
146 TPMI_RH_PROVISION AuthHandle
;
147 UINT32 AuthSessionSize
;
148 TPMS_AUTH_COMMAND AuthSession
;
149 } TPM2_NV_GLOBALWRITELOCK_COMMAND
;
152 TPM2_RESPONSE_HEADER Header
;
153 UINT32 AuthSessionSize
;
154 TPMS_AUTH_RESPONSE AuthSession
;
155 } TPM2_NV_GLOBALWRITELOCK_RESPONSE
;
160 This command is used to read the public area and Name of an NV Index.
162 @param[in] NvIndex The NV Index.
163 @param[out] NvPublic The public area of the index.
164 @param[out] NvName The Name of the nvIndex.
166 @retval EFI_SUCCESS Operation completed successfully.
167 @retval EFI_DEVICE_ERROR The command was unsuccessful.
168 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
173 IN TPMI_RH_NV_INDEX NvIndex
,
174 OUT TPM2B_NV_PUBLIC
*NvPublic
,
175 OUT TPM2B_NAME
*NvName
179 TPM2_NV_READPUBLIC_COMMAND SendBuffer
;
180 TPM2_NV_READPUBLIC_RESPONSE RecvBuffer
;
181 UINT32 SendBufferSize
;
182 UINT32 RecvBufferSize
;
191 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_NO_SESSIONS
);
192 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_ReadPublic
);
194 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
196 SendBufferSize
= (UINT32
) sizeof (SendBuffer
);
197 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
202 RecvBufferSize
= sizeof (RecvBuffer
);
203 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
204 if (EFI_ERROR (Status
)) {
208 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
209 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
210 return EFI_DEVICE_ERROR
;
212 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
213 if (ResponseCode
!= TPM_RC_SUCCESS
) {
214 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadPublic - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
216 switch (ResponseCode
) {
220 case TPM_RC_HANDLE
+ RC_NV_ReadPublic_nvIndex
: // TPM_RC_NV_DEFINED:
221 return EFI_NOT_FOUND
;
222 case TPM_RC_VALUE
+ RC_NV_ReadPublic_nvIndex
:
223 return EFI_INVALID_PARAMETER
;
225 return EFI_DEVICE_ERROR
;
228 if (RecvBufferSize
<= sizeof (TPM2_RESPONSE_HEADER
) + sizeof (UINT16
) + sizeof(UINT16
)) {
229 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - %x\n", RecvBufferSize
));
230 return EFI_NOT_FOUND
;
236 NvPublicSize
= SwapBytes16 (RecvBuffer
.NvPublic
.size
);
237 if (NvPublicSize
> sizeof(TPMS_NV_PUBLIC
)) {
238 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - NvPublic.size error %x\n", NvPublicSize
));
239 return EFI_DEVICE_ERROR
;
242 NvNameSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)((UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + NvPublicSize
)));
243 if (NvNameSize
> sizeof(TPMU_NAME
)){
244 DEBUG ((DEBUG_ERROR
, "Tpm2NvReadPublic - NvNameSize error %x\n", NvNameSize
));
245 return EFI_DEVICE_ERROR
;
248 if (RecvBufferSize
!= sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + NvPublicSize
+ sizeof(UINT16
) + NvNameSize
) {
249 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadPublic - RecvBufferSize Error - NvPublicSize %x\n", RecvBufferSize
));
250 return EFI_NOT_FOUND
;
254 // Return the response
256 CopyMem (NvPublic
, &RecvBuffer
.NvPublic
, sizeof(UINT16
) + NvPublicSize
);
257 NvPublic
->size
= NvPublicSize
;
258 NvPublic
->nvPublic
.nvIndex
= SwapBytes32 (NvPublic
->nvPublic
.nvIndex
);
259 NvPublic
->nvPublic
.nameAlg
= SwapBytes16 (NvPublic
->nvPublic
.nameAlg
);
260 WriteUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
, SwapBytes32 (ReadUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
)));
261 NvPublic
->nvPublic
.authPolicy
.size
= SwapBytes16 (NvPublic
->nvPublic
.authPolicy
.size
);
262 Buffer
= (UINT8
*)&RecvBuffer
.NvPublic
.nvPublic
.authPolicy
;
263 Buffer
+= sizeof(UINT16
) + NvPublic
->nvPublic
.authPolicy
.size
;
264 NvPublic
->nvPublic
.dataSize
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
266 CopyMem (NvName
->name
, (UINT8
*)&RecvBuffer
+ sizeof(TPM2_RESPONSE_HEADER
) + sizeof(UINT16
) + NvPublicSize
+ sizeof(UINT16
), NvNameSize
);
267 NvName
->size
= NvNameSize
;
273 This command defines the attributes of an NV Index and causes the TPM to
274 reserve space to hold the data associated with the index.
275 If a definition already exists at the index, the TPM will return TPM_RC_NV_DEFINED.
277 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
278 @param[in] AuthSession Auth Session context
279 @param[in] Auth The authorization data.
280 @param[in] NvPublic The public area of the index.
282 @retval EFI_SUCCESS Operation completed successfully.
283 @retval EFI_DEVICE_ERROR The command was unsuccessful.
284 @retval EFI_ALREADY_STARTED The command was returned successfully, but NvIndex is already defined.
289 IN TPMI_RH_PROVISION AuthHandle
,
290 IN TPMS_AUTH_COMMAND
*AuthSession
, OPTIONAL
292 IN TPM2B_NV_PUBLIC
*NvPublic
296 TPM2_NV_DEFINESPACE_COMMAND SendBuffer
;
297 TPM2_NV_DEFINESPACE_RESPONSE RecvBuffer
;
298 UINT32 SendBufferSize
;
299 UINT32 RecvBufferSize
;
302 UINT32 SessionInfoSize
;
308 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
309 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_DefineSpace
);
310 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
313 // Add in Auth session
315 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
318 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
319 Buffer
+= SessionInfoSize
;
320 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
325 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16(Auth
->size
));
326 Buffer
+= sizeof(UINT16
);
327 CopyMem(Buffer
, Auth
->buffer
, Auth
->size
);
328 Buffer
+= Auth
->size
;
333 NvPublicSize
= NvPublic
->size
;
335 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublicSize
));
336 Buffer
+= sizeof(UINT16
);
337 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (NvPublic
->nvPublic
.nvIndex
));
338 Buffer
+= sizeof(UINT32
);
339 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.nameAlg
));
340 Buffer
+= sizeof(UINT16
);
341 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (ReadUnaligned32 ((UINT32
*)&NvPublic
->nvPublic
.attributes
)));
342 Buffer
+= sizeof(UINT32
);
343 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.authPolicy
.size
));
344 Buffer
+= sizeof(UINT16
);
345 CopyMem (Buffer
, NvPublic
->nvPublic
.authPolicy
.buffer
, NvPublic
->nvPublic
.authPolicy
.size
);
346 Buffer
+= NvPublic
->nvPublic
.authPolicy
.size
;
347 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (NvPublic
->nvPublic
.dataSize
));
348 Buffer
+= sizeof(UINT16
);
350 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
351 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
356 RecvBufferSize
= sizeof (RecvBuffer
);
357 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
358 if (EFI_ERROR (Status
)) {
362 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
363 DEBUG ((EFI_D_ERROR
, "Tpm2NvDefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize
));
364 Status
= EFI_DEVICE_ERROR
;
368 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
369 if (ResponseCode
!= TPM_RC_SUCCESS
) {
370 DEBUG ((EFI_D_ERROR
, "Tpm2NvDefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
372 switch (ResponseCode
) {
376 case TPM_RC_SIZE
+ RC_NV_DefineSpace_publicInfo
:
377 case TPM_RC_SIZE
+ RC_NV_DefineSpace_auth
:
378 Status
= EFI_BAD_BUFFER_SIZE
;
380 case TPM_RC_ATTRIBUTES
:
381 case TPM_RC_ATTRIBUTES
+ RC_NV_DefineSpace_publicInfo
:
382 Status
= EFI_UNSUPPORTED
;
384 case TPM_RC_ATTRIBUTES
+ RC_NV_DefineSpace_authHandle
:
385 Status
= EFI_INVALID_PARAMETER
;
387 case TPM_RC_NV_DEFINED
:
388 Status
= EFI_ALREADY_STARTED
;
390 case TPM_RC_VALUE
+ RC_NV_DefineSpace_publicInfo
:
391 case TPM_RC_VALUE
+ RC_NV_DefineSpace_authHandle
:
392 Status
= EFI_INVALID_PARAMETER
;
394 case TPM_RC_NV_SPACE
:
395 Status
= EFI_OUT_OF_RESOURCES
;
398 Status
= EFI_DEVICE_ERROR
;
404 // Clear AuthSession Content
406 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
407 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
412 This command removes an index from the TPM.
414 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
415 @param[in] NvIndex The NV Index.
416 @param[in] AuthSession Auth Session context
418 @retval EFI_SUCCESS Operation completed successfully.
419 @retval EFI_DEVICE_ERROR The command was unsuccessful.
420 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
424 Tpm2NvUndefineSpace (
425 IN TPMI_RH_PROVISION AuthHandle
,
426 IN TPMI_RH_NV_INDEX NvIndex
,
427 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
431 TPM2_NV_UNDEFINESPACE_COMMAND SendBuffer
;
432 TPM2_NV_UNDEFINESPACE_RESPONSE RecvBuffer
;
433 UINT32 SendBufferSize
;
434 UINT32 RecvBufferSize
;
436 UINT32 SessionInfoSize
;
442 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
443 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_UndefineSpace
);
445 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
446 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
449 // Add in Auth session
451 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
454 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
455 Buffer
+= SessionInfoSize
;
456 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
458 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
459 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
464 RecvBufferSize
= sizeof (RecvBuffer
);
465 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
466 if (EFI_ERROR (Status
)) {
470 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
471 DEBUG ((EFI_D_ERROR
, "Tpm2NvUndefineSpace - RecvBufferSize Error - %x\n", RecvBufferSize
));
472 Status
= EFI_DEVICE_ERROR
;
476 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
477 if (ResponseCode
!= TPM_RC_SUCCESS
) {
478 DEBUG ((EFI_D_ERROR
, "Tpm2NvUndefineSpace - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
480 switch (ResponseCode
) {
484 case TPM_RC_ATTRIBUTES
:
485 case TPM_RC_ATTRIBUTES
+ RC_NV_UndefineSpace_nvIndex
:
486 Status
= EFI_UNSUPPORTED
;
488 case TPM_RC_NV_AUTHORIZATION
:
489 Status
= EFI_SECURITY_VIOLATION
;
491 case TPM_RC_HANDLE
+ RC_NV_UndefineSpace_nvIndex
: // TPM_RC_NV_DEFINED:
492 Status
= EFI_NOT_FOUND
;
494 case TPM_RC_HANDLE
+ RC_NV_UndefineSpace_authHandle
: // TPM_RC_NV_DEFINED:
495 Status
= EFI_INVALID_PARAMETER
;
497 case TPM_RC_VALUE
+ RC_NV_UndefineSpace_authHandle
:
498 case TPM_RC_VALUE
+ RC_NV_UndefineSpace_nvIndex
:
499 Status
= EFI_INVALID_PARAMETER
;
502 Status
= EFI_DEVICE_ERROR
;
508 // Clear AuthSession Content
510 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
511 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
516 This command reads a value from an area in NV memory previously defined by TPM2_NV_DefineSpace().
518 @param[in] AuthHandle the handle indicating the source of the authorization value.
519 @param[in] NvIndex The index to be read.
520 @param[in] AuthSession Auth Session context
521 @param[in] Size Number of bytes to read.
522 @param[in] Offset Byte offset into the area.
523 @param[in,out] OutData The data read.
525 @retval EFI_SUCCESS Operation completed successfully.
526 @retval EFI_DEVICE_ERROR The command was unsuccessful.
527 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
532 IN TPMI_RH_NV_AUTH AuthHandle
,
533 IN TPMI_RH_NV_INDEX NvIndex
,
534 IN TPMS_AUTH_COMMAND
*AuthSession
, OPTIONAL
537 IN OUT TPM2B_MAX_BUFFER
*OutData
541 TPM2_NV_READ_COMMAND SendBuffer
;
542 TPM2_NV_READ_RESPONSE RecvBuffer
;
543 UINT32 SendBufferSize
;
544 UINT32 RecvBufferSize
;
546 UINT32 SessionInfoSize
;
552 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
553 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_Read
);
555 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
556 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
559 // Add in Auth session
561 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
564 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
565 Buffer
+= SessionInfoSize
;
566 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
568 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Size
));
569 Buffer
+= sizeof(UINT16
);
570 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Offset
));
571 Buffer
+= sizeof(UINT16
);
573 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
574 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
579 RecvBufferSize
= sizeof (RecvBuffer
);
580 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
581 if (EFI_ERROR (Status
)) {
585 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
586 DEBUG ((EFI_D_ERROR
, "Tpm2NvRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
587 Status
= EFI_DEVICE_ERROR
;
590 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
591 if (ResponseCode
!= TPM_RC_SUCCESS
) {
592 DEBUG ((EFI_D_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
;
636 if (Status
!= EFI_SUCCESS
) {
641 // Return the response
643 OutData
->size
= SwapBytes16 (RecvBuffer
.Data
.size
);
644 if (OutData
->size
> MAX_DIGEST_BUFFER
) {
645 DEBUG ((DEBUG_ERROR
, "Tpm2NvRead - OutData->size error %x\n", OutData
->size
));
646 Status
= EFI_DEVICE_ERROR
;
650 CopyMem (OutData
->buffer
, &RecvBuffer
.Data
.buffer
, OutData
->size
);
654 // Clear AuthSession Content
656 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
657 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
662 This command writes a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
664 @param[in] AuthHandle the handle indicating the source of the authorization value.
665 @param[in] NvIndex The NV Index of the area to write.
666 @param[in] AuthSession Auth Session context
667 @param[in] InData The data to write.
668 @param[in] Offset The offset into the NV Area.
670 @retval EFI_SUCCESS Operation completed successfully.
671 @retval EFI_DEVICE_ERROR The command was unsuccessful.
672 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
677 IN TPMI_RH_NV_AUTH AuthHandle
,
678 IN TPMI_RH_NV_INDEX NvIndex
,
679 IN TPMS_AUTH_COMMAND
*AuthSession
, OPTIONAL
680 IN TPM2B_MAX_BUFFER
*InData
,
685 TPM2_NV_WRITE_COMMAND SendBuffer
;
686 TPM2_NV_WRITE_RESPONSE RecvBuffer
;
687 UINT32 SendBufferSize
;
688 UINT32 RecvBufferSize
;
690 UINT32 SessionInfoSize
;
696 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
697 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_Write
);
699 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
700 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
703 // Add in Auth session
705 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
708 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
709 Buffer
+= SessionInfoSize
;
710 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
712 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (InData
->size
));
713 Buffer
+= sizeof(UINT16
);
714 CopyMem (Buffer
, InData
->buffer
, InData
->size
);
715 Buffer
+= InData
->size
;
716 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Offset
));
717 Buffer
+= sizeof(UINT16
);
719 SendBufferSize
= (UINT32
) (Buffer
- (UINT8
*)&SendBuffer
);
720 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
725 RecvBufferSize
= sizeof (RecvBuffer
);
726 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
727 if (EFI_ERROR (Status
)) {
731 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
732 DEBUG ((EFI_D_ERROR
, "Tpm2NvWrite - RecvBufferSize Error - %x\n", RecvBufferSize
));
733 Status
= EFI_DEVICE_ERROR
;
736 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
737 if (ResponseCode
!= TPM_RC_SUCCESS
) {
738 DEBUG ((EFI_D_ERROR
, "Tpm2NvWrite - responseCode - %x\n", ResponseCode
));
740 switch (ResponseCode
) {
744 case TPM_RC_ATTRIBUTES
:
745 Status
= EFI_UNSUPPORTED
;
747 case TPM_RC_NV_AUTHORIZATION
:
748 Status
= EFI_SECURITY_VIOLATION
;
750 case TPM_RC_NV_LOCKED
:
751 Status
= EFI_ACCESS_DENIED
;
753 case TPM_RC_NV_RANGE
:
754 Status
= EFI_BAD_BUFFER_SIZE
;
756 case TPM_RC_HANDLE
+ RC_NV_Write_nvIndex
: // TPM_RC_NV_DEFINED:
757 Status
= EFI_NOT_FOUND
;
759 case TPM_RC_HANDLE
+ RC_NV_Write_authHandle
: // TPM_RC_NV_DEFINED:
760 Status
= EFI_INVALID_PARAMETER
;
762 case TPM_RC_VALUE
+ RC_NV_Write_nvIndex
:
763 case TPM_RC_VALUE
+ RC_NV_Write_authHandle
:
764 Status
= EFI_INVALID_PARAMETER
;
766 case TPM_RC_BAD_AUTH
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
767 Status
= EFI_INVALID_PARAMETER
;
769 case TPM_RC_AUTH_UNAVAILABLE
:
770 Status
= EFI_INVALID_PARAMETER
;
772 case TPM_RC_AUTH_FAIL
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
773 Status
= EFI_INVALID_PARAMETER
;
775 case TPM_RC_ATTRIBUTES
+ RC_NV_Write_authHandle
+ TPM_RC_S
:
776 Status
= EFI_UNSUPPORTED
;
779 Status
= EFI_DEVICE_ERROR
;
785 // Clear AuthSession Content
787 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
788 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
793 This command may be used to prevent further reads of the Index until the next TPM2_Startup (TPM_SU_CLEAR).
795 @param[in] AuthHandle the handle indicating the source of the authorization value.
796 @param[in] NvIndex The NV Index of the area to lock.
797 @param[in] AuthSession Auth Session context
799 @retval EFI_SUCCESS Operation completed successfully.
800 @retval EFI_DEVICE_ERROR The command was unsuccessful.
801 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
806 IN TPMI_RH_NV_AUTH AuthHandle
,
807 IN TPMI_RH_NV_INDEX NvIndex
,
808 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
812 TPM2_NV_READLOCK_COMMAND SendBuffer
;
813 TPM2_NV_READLOCK_RESPONSE RecvBuffer
;
814 UINT32 SendBufferSize
;
815 UINT32 RecvBufferSize
;
817 UINT32 SessionInfoSize
;
823 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
824 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_ReadLock
);
826 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
827 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
830 // Add in Auth session
832 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
835 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
836 Buffer
+= SessionInfoSize
;
837 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
839 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
840 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
845 RecvBufferSize
= sizeof (RecvBuffer
);
846 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
847 if (EFI_ERROR (Status
)) {
851 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
852 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
853 Status
= EFI_DEVICE_ERROR
;
857 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
858 if (ResponseCode
!= TPM_RC_SUCCESS
) {
859 DEBUG ((EFI_D_ERROR
, "Tpm2NvReadLock - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
861 switch (ResponseCode
) {
866 Status
= EFI_DEVICE_ERROR
;
872 // Clear AuthSession Content
874 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
875 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
880 This command may be used to inhibit further writes of the Index.
882 @param[in] AuthHandle the handle indicating the source of the authorization value.
883 @param[in] NvIndex The NV Index of the area to lock.
884 @param[in] AuthSession Auth Session context
886 @retval EFI_SUCCESS Operation completed successfully.
887 @retval EFI_DEVICE_ERROR The command was unsuccessful.
888 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
893 IN TPMI_RH_NV_AUTH AuthHandle
,
894 IN TPMI_RH_NV_INDEX NvIndex
,
895 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
899 TPM2_NV_WRITELOCK_COMMAND SendBuffer
;
900 TPM2_NV_WRITELOCK_RESPONSE RecvBuffer
;
901 UINT32 SendBufferSize
;
902 UINT32 RecvBufferSize
;
904 UINT32 SessionInfoSize
;
910 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
911 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_WriteLock
);
913 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
914 SendBuffer
.NvIndex
= SwapBytes32 (NvIndex
);
917 // Add in Auth session
919 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
922 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
923 Buffer
+= SessionInfoSize
;
924 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
926 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
927 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
932 RecvBufferSize
= sizeof (RecvBuffer
);
933 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
934 if (EFI_ERROR (Status
)) {
938 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
939 DEBUG ((EFI_D_ERROR
, "Tpm2NvWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
940 Status
= EFI_DEVICE_ERROR
;
944 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
945 if (ResponseCode
!= TPM_RC_SUCCESS
) {
946 DEBUG ((EFI_D_ERROR
, "Tpm2NvWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
948 switch (ResponseCode
) {
953 Status
= EFI_DEVICE_ERROR
;
959 // Clear AuthSession Content
961 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
962 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));
967 The command will SET TPMA_NV_WRITELOCKED for all indexes that have their TPMA_NV_GLOBALLOCK attribute SET.
969 @param[in] AuthHandle TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}.
970 @param[in] AuthSession Auth Session context
972 @retval EFI_SUCCESS Operation completed successfully.
973 @retval EFI_DEVICE_ERROR The command was unsuccessful.
974 @retval EFI_NOT_FOUND The command was returned successfully, but NvIndex is not found.
978 Tpm2NvGlobalWriteLock (
979 IN TPMI_RH_PROVISION AuthHandle
,
980 IN TPMS_AUTH_COMMAND
*AuthSession OPTIONAL
984 TPM2_NV_GLOBALWRITELOCK_COMMAND SendBuffer
;
985 TPM2_NV_GLOBALWRITELOCK_RESPONSE RecvBuffer
;
986 UINT32 SendBufferSize
;
987 UINT32 RecvBufferSize
;
989 UINT32 SessionInfoSize
;
995 SendBuffer
.Header
.tag
= SwapBytes16(TPM_ST_SESSIONS
);
996 SendBuffer
.Header
.commandCode
= SwapBytes32(TPM_CC_NV_GlobalWriteLock
);
998 SendBuffer
.AuthHandle
= SwapBytes32 (AuthHandle
);
1001 // Add in Auth session
1003 Buffer
= (UINT8
*)&SendBuffer
.AuthSession
;
1006 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
1007 Buffer
+= SessionInfoSize
;
1008 SendBuffer
.AuthSessionSize
= SwapBytes32(SessionInfoSize
);
1010 SendBufferSize
= (UINT32
)(Buffer
- (UINT8
*)&SendBuffer
);
1011 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
1016 RecvBufferSize
= sizeof (RecvBuffer
);
1017 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
1018 if (EFI_ERROR (Status
)) {
1022 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
1023 DEBUG ((EFI_D_ERROR
, "Tpm2NvGlobalWriteLock - RecvBufferSize Error - %x\n", RecvBufferSize
));
1024 Status
= EFI_DEVICE_ERROR
;
1028 ResponseCode
= SwapBytes32(RecvBuffer
.Header
.responseCode
);
1029 if (ResponseCode
!= TPM_RC_SUCCESS
) {
1030 DEBUG ((EFI_D_ERROR
, "Tpm2NvGlobalWriteLock - responseCode - %x\n", SwapBytes32(RecvBuffer
.Header
.responseCode
)));
1032 switch (ResponseCode
) {
1033 case TPM_RC_SUCCESS
:
1037 Status
= EFI_DEVICE_ERROR
;
1043 // Clear AuthSession Content
1045 ZeroMem (&SendBuffer
, sizeof(SendBuffer
));
1046 ZeroMem (&RecvBuffer
, sizeof(RecvBuffer
));