2 Implement TPM2 Integrity related command.
4 Copyright (c) 2013 - 2021, 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>
19 TPM2_COMMAND_HEADER Header
;
20 TPMI_DH_PCR PcrHandle
;
21 UINT32 AuthorizationSize
;
22 TPMS_AUTH_COMMAND AuthSessionPcr
;
23 TPML_DIGEST_VALUES DigestValues
;
24 } TPM2_PCR_EXTEND_COMMAND
;
27 TPM2_RESPONSE_HEADER Header
;
29 TPMS_AUTH_RESPONSE AuthSessionPcr
;
30 } TPM2_PCR_EXTEND_RESPONSE
;
33 TPM2_COMMAND_HEADER Header
;
34 TPMI_DH_PCR PcrHandle
;
35 UINT32 AuthorizationSize
;
36 TPMS_AUTH_COMMAND AuthSessionPcr
;
37 TPM2B_EVENT EventData
;
38 } TPM2_PCR_EVENT_COMMAND
;
41 TPM2_RESPONSE_HEADER Header
;
43 TPML_DIGEST_VALUES Digests
;
44 TPMS_AUTH_RESPONSE AuthSessionPcr
;
45 } TPM2_PCR_EVENT_RESPONSE
;
48 TPM2_COMMAND_HEADER Header
;
49 TPML_PCR_SELECTION PcrSelectionIn
;
50 } TPM2_PCR_READ_COMMAND
;
53 TPM2_RESPONSE_HEADER Header
;
54 UINT32 PcrUpdateCounter
;
55 TPML_PCR_SELECTION PcrSelectionOut
;
56 TPML_DIGEST PcrValues
;
57 } TPM2_PCR_READ_RESPONSE
;
60 TPM2_COMMAND_HEADER Header
;
61 TPMI_RH_PLATFORM AuthHandle
;
62 UINT32 AuthSessionSize
;
63 TPMS_AUTH_COMMAND AuthSession
;
64 TPML_PCR_SELECTION PcrAllocation
;
65 } TPM2_PCR_ALLOCATE_COMMAND
;
68 TPM2_RESPONSE_HEADER Header
;
69 UINT32 AuthSessionSize
;
70 TPMI_YES_NO AllocationSuccess
;
74 TPMS_AUTH_RESPONSE AuthSession
;
75 } TPM2_PCR_ALLOCATE_RESPONSE
;
80 This command is used to cause an update to the indicated PCR.
81 The digests parameter contains one or more tagged digest value identified by an algorithm ID.
82 For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).
84 @param[in] PcrHandle Handle of the PCR
85 @param[in] Digests List of tagged digest values to be extended
87 @retval EFI_SUCCESS Operation completed successfully.
88 @retval EFI_DEVICE_ERROR Unexpected device behavior.
93 IN TPMI_DH_PCR PcrHandle
,
94 IN TPML_DIGEST_VALUES
*Digests
98 TPM2_PCR_EXTEND_COMMAND Cmd
;
99 TPM2_PCR_EXTEND_RESPONSE Res
;
102 UINT32 ResultBufSize
;
105 UINT32 SessionInfoSize
;
108 Cmd
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
109 Cmd
.Header
.commandCode
= SwapBytes32 (TPM_CC_PCR_Extend
);
110 Cmd
.PcrHandle
= SwapBytes32 (PcrHandle
);
113 // Add in Auth session
115 Buffer
= (UINT8
*)&Cmd
.AuthSessionPcr
;
118 SessionInfoSize
= CopyAuthSessionCommand (NULL
, Buffer
);
119 Buffer
+= SessionInfoSize
;
120 Cmd
.AuthorizationSize
= SwapBytes32 (SessionInfoSize
);
123 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (Digests
->count
));
124 Buffer
+= sizeof (UINT32
);
127 for (Index
= 0; Index
< Digests
->count
; Index
++) {
128 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (Digests
->digests
[Index
].hashAlg
));
129 Buffer
+= sizeof (UINT16
);
130 DigestSize
= GetHashSizeFromAlgo (Digests
->digests
[Index
].hashAlg
);
131 if (DigestSize
== 0) {
132 DEBUG ((DEBUG_ERROR
, "Unknown hash algorithm %d\r\n", Digests
->digests
[Index
].hashAlg
));
133 return EFI_DEVICE_ERROR
;
138 &Digests
->digests
[Index
].digest
,
146 "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",
147 Digests
->digests
[Index
].hashAlg
,
151 for (Index2
= 0; Index2
< DigestSize
; Index2
++) {
152 DEBUG ((DEBUG_VERBOSE
, "%02x ", Buffer
[Index2
]));
155 DEBUG ((DEBUG_VERBOSE
, "\n"));
158 Buffer
+= DigestSize
;
161 CmdSize
= (UINT32
)((UINTN
)Buffer
- (UINTN
)&Cmd
);
162 Cmd
.Header
.paramSize
= SwapBytes32 (CmdSize
);
164 ResultBufSize
= sizeof (Res
);
165 Status
= Tpm2SubmitCommand (CmdSize
, (UINT8
*)&Cmd
, &ResultBufSize
, (UINT8
*)&Res
);
166 if (EFI_ERROR (Status
)) {
170 if (ResultBufSize
> sizeof (Res
)) {
171 DEBUG ((DEBUG_ERROR
, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));
172 return EFI_BUFFER_TOO_SMALL
;
176 // Validate response headers
178 RespSize
= SwapBytes32 (Res
.Header
.paramSize
);
179 if (RespSize
> sizeof (Res
)) {
180 DEBUG ((DEBUG_ERROR
, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize
));
181 return EFI_BUFFER_TOO_SMALL
;
185 // Fail if command failed
187 if (SwapBytes32 (Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
188 DEBUG ((DEBUG_ERROR
, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res
.Header
.responseCode
)));
189 return EFI_DEVICE_ERROR
;
193 DEBUG ((DEBUG_VERBOSE
, "Tpm2PcrExtend: PCR read after extend...\n"));
194 Tpm2PcrReadForActiveBank (PcrHandle
, NULL
);
198 // Unmarshal the response
207 This command is used to cause an update to the indicated PCR.
208 The data in eventData is hashed using the hash algorithm associated with each bank in which the
209 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle
210 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in
212 A TPM shall support an Event.size of zero through 1,024 inclusive.
214 @param[in] PcrHandle Handle of the PCR
215 @param[in] EventData Event data in sized buffer
216 @param[out] Digests List of digest
218 @retval EFI_SUCCESS Operation completed successfully.
219 @retval EFI_DEVICE_ERROR Unexpected device behavior.
224 IN TPMI_DH_PCR PcrHandle
,
225 IN TPM2B_EVENT
*EventData
,
226 OUT TPML_DIGEST_VALUES
*Digests
230 TPM2_PCR_EVENT_COMMAND Cmd
;
231 TPM2_PCR_EVENT_RESPONSE Res
;
234 UINT32 ResultBufSize
;
237 UINT32 SessionInfoSize
;
240 Cmd
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
241 Cmd
.Header
.commandCode
= SwapBytes32 (TPM_CC_PCR_Event
);
242 Cmd
.PcrHandle
= SwapBytes32 (PcrHandle
);
245 // Add in Auth session
247 Buffer
= (UINT8
*)&Cmd
.AuthSessionPcr
;
250 SessionInfoSize
= CopyAuthSessionCommand (NULL
, Buffer
);
251 Buffer
+= SessionInfoSize
;
252 Cmd
.AuthorizationSize
= SwapBytes32 (SessionInfoSize
);
255 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (EventData
->size
));
256 Buffer
+= sizeof (UINT16
);
258 CopyMem (Buffer
, EventData
->buffer
, EventData
->size
);
259 Buffer
+= EventData
->size
;
261 CmdSize
= (UINT32
)((UINTN
)Buffer
- (UINTN
)&Cmd
);
262 Cmd
.Header
.paramSize
= SwapBytes32 (CmdSize
);
264 ResultBufSize
= sizeof (Res
);
265 Status
= Tpm2SubmitCommand (CmdSize
, (UINT8
*)&Cmd
, &ResultBufSize
, (UINT8
*)&Res
);
266 if (EFI_ERROR (Status
)) {
270 if (ResultBufSize
> sizeof (Res
)) {
271 DEBUG ((DEBUG_ERROR
, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));
272 return EFI_BUFFER_TOO_SMALL
;
276 // Validate response headers
278 RespSize
= SwapBytes32 (Res
.Header
.paramSize
);
279 if (RespSize
> sizeof (Res
)) {
280 DEBUG ((DEBUG_ERROR
, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize
));
281 return EFI_BUFFER_TOO_SMALL
;
285 // Fail if command failed
287 if (SwapBytes32 (Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
288 DEBUG ((DEBUG_ERROR
, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res
.Header
.responseCode
)));
289 return EFI_DEVICE_ERROR
;
293 // Unmarshal the response
295 Buffer
= (UINT8
*)&Res
.Digests
;
297 Digests
->count
= SwapBytes32 (ReadUnaligned32 ((UINT32
*)Buffer
));
298 if (Digests
->count
> HASH_COUNT
) {
299 DEBUG ((DEBUG_ERROR
, "Tpm2PcrEvent - Digests->count error %x\n", Digests
->count
));
300 return EFI_DEVICE_ERROR
;
303 Buffer
+= sizeof (UINT32
);
304 for (Index
= 0; Index
< Digests
->count
; Index
++) {
305 Digests
->digests
[Index
].hashAlg
= SwapBytes16 (ReadUnaligned16 ((UINT16
*)Buffer
));
306 Buffer
+= sizeof (UINT16
);
307 DigestSize
= GetHashSizeFromAlgo (Digests
->digests
[Index
].hashAlg
);
308 if (DigestSize
== 0) {
309 DEBUG ((DEBUG_ERROR
, "Unknown hash algorithm %d\r\n", Digests
->digests
[Index
].hashAlg
));
310 return EFI_DEVICE_ERROR
;
314 &Digests
->digests
[Index
].digest
,
318 Buffer
+= DigestSize
;
325 This command returns the values of all PCR specified in pcrSelect.
327 @param[in] PcrSelectionIn The selection of PCR to read.
328 @param[out] PcrUpdateCounter The current value of the PCR update counter.
329 @param[out] PcrSelectionOut The PCR in the returned list.
330 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.
332 @retval EFI_SUCCESS Operation completed successfully.
333 @retval EFI_DEVICE_ERROR The command was unsuccessful.
338 IN TPML_PCR_SELECTION
*PcrSelectionIn
,
339 OUT UINT32
*PcrUpdateCounter
,
340 OUT TPML_PCR_SELECTION
*PcrSelectionOut
,
341 OUT TPML_DIGEST
*PcrValues
345 TPM2_PCR_READ_COMMAND SendBuffer
;
346 TPM2_PCR_READ_RESPONSE RecvBuffer
;
347 UINT32 SendBufferSize
;
348 UINT32 RecvBufferSize
;
350 TPML_DIGEST
*PcrValuesOut
;
351 TPM2B_DIGEST
*Digests
;
356 SendBuffer
.Header
.tag
= SwapBytes16 (TPM_ST_NO_SESSIONS
);
357 SendBuffer
.Header
.commandCode
= SwapBytes32 (TPM_CC_PCR_Read
);
359 SendBuffer
.PcrSelectionIn
.count
= SwapBytes32 (PcrSelectionIn
->count
);
360 for (Index
= 0; Index
< PcrSelectionIn
->count
; Index
++) {
361 SendBuffer
.PcrSelectionIn
.pcrSelections
[Index
].hash
= SwapBytes16 (PcrSelectionIn
->pcrSelections
[Index
].hash
);
362 SendBuffer
.PcrSelectionIn
.pcrSelections
[Index
].sizeofSelect
= PcrSelectionIn
->pcrSelections
[Index
].sizeofSelect
;
363 CopyMem (&SendBuffer
.PcrSelectionIn
.pcrSelections
[Index
].pcrSelect
, &PcrSelectionIn
->pcrSelections
[Index
].pcrSelect
, SendBuffer
.PcrSelectionIn
.pcrSelections
[Index
].sizeofSelect
);
366 SendBufferSize
= sizeof (SendBuffer
.Header
) + sizeof (SendBuffer
.PcrSelectionIn
.count
) + sizeof (SendBuffer
.PcrSelectionIn
.pcrSelections
[0]) * PcrSelectionIn
->count
;
367 SendBuffer
.Header
.paramSize
= SwapBytes32 (SendBufferSize
);
372 RecvBufferSize
= sizeof (RecvBuffer
);
373 Status
= Tpm2SubmitCommand (SendBufferSize
, (UINT8
*)&SendBuffer
, &RecvBufferSize
, (UINT8
*)&RecvBuffer
);
374 if (EFI_ERROR (Status
)) {
378 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
)) {
379 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
380 return EFI_DEVICE_ERROR
;
383 if (SwapBytes32 (RecvBuffer
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
384 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer
.Header
.responseCode
)));
385 return EFI_NOT_FOUND
;
389 // Return the response
395 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
) + sizeof (RecvBuffer
.PcrUpdateCounter
)) {
396 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
397 return EFI_DEVICE_ERROR
;
400 *PcrUpdateCounter
= SwapBytes32 (RecvBuffer
.PcrUpdateCounter
);
405 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
) + sizeof (RecvBuffer
.PcrUpdateCounter
) + sizeof (RecvBuffer
.PcrSelectionOut
.count
)) {
406 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
407 return EFI_DEVICE_ERROR
;
410 PcrSelectionOut
->count
= SwapBytes32 (RecvBuffer
.PcrSelectionOut
.count
);
411 if (PcrSelectionOut
->count
> HASH_COUNT
) {
412 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut
->count
));
413 return EFI_DEVICE_ERROR
;
416 if (RecvBufferSize
< sizeof (TPM2_RESPONSE_HEADER
) + sizeof (RecvBuffer
.PcrUpdateCounter
) + sizeof (RecvBuffer
.PcrSelectionOut
.count
) + sizeof (RecvBuffer
.PcrSelectionOut
.pcrSelections
[0]) * PcrSelectionOut
->count
) {
417 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize
));
418 return EFI_DEVICE_ERROR
;
421 for (Index
= 0; Index
< PcrSelectionOut
->count
; Index
++) {
422 PcrSelectionOut
->pcrSelections
[Index
].hash
= SwapBytes16 (RecvBuffer
.PcrSelectionOut
.pcrSelections
[Index
].hash
);
423 PcrSelectionOut
->pcrSelections
[Index
].sizeofSelect
= RecvBuffer
.PcrSelectionOut
.pcrSelections
[Index
].sizeofSelect
;
424 if (PcrSelectionOut
->pcrSelections
[Index
].sizeofSelect
> PCR_SELECT_MAX
) {
425 return EFI_DEVICE_ERROR
;
428 CopyMem (&PcrSelectionOut
->pcrSelections
[Index
].pcrSelect
, &RecvBuffer
.PcrSelectionOut
.pcrSelections
[Index
].pcrSelect
, PcrSelectionOut
->pcrSelections
[Index
].sizeofSelect
);
434 PcrValuesOut
= (TPML_DIGEST
*)((UINT8
*)&RecvBuffer
+ sizeof (TPM2_RESPONSE_HEADER
) + sizeof (RecvBuffer
.PcrUpdateCounter
) + sizeof (RecvBuffer
.PcrSelectionOut
.count
) + sizeof (RecvBuffer
.PcrSelectionOut
.pcrSelections
[0]) * PcrSelectionOut
->count
);
435 PcrValues
->count
= SwapBytes32 (PcrValuesOut
->count
);
437 // The number of digests in list is not greater than 8 per TPML_DIGEST definition
439 if (PcrValues
->count
> 8) {
440 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues
->count
));
441 return EFI_DEVICE_ERROR
;
444 Digests
= PcrValuesOut
->digests
;
445 for (Index
= 0; Index
< PcrValues
->count
; Index
++) {
446 PcrValues
->digests
[Index
].size
= SwapBytes16 (Digests
->size
);
447 if (PcrValues
->digests
[Index
].size
> sizeof (TPMU_HA
)) {
448 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead - Digest.size error %x\n", PcrValues
->digests
[Index
].size
));
449 return EFI_DEVICE_ERROR
;
452 CopyMem (&PcrValues
->digests
[Index
].buffer
, &Digests
->buffer
, PcrValues
->digests
[Index
].size
);
453 Digests
= (TPM2B_DIGEST
*)((UINT8
*)Digests
+ sizeof (Digests
->size
) + PcrValues
->digests
[Index
].size
);
460 This command is used to set the desired PCR allocation of PCR and algorithms.
462 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
463 @param[in] AuthSession Auth Session context
464 @param[in] PcrAllocation The requested allocation
465 @param[out] AllocationSuccess YES if the allocation succeeded
466 @param[out] MaxPCR maximum number of PCR that may be in a bank
467 @param[out] SizeNeeded number of octets required to satisfy the request
468 @param[out] SizeAvailable Number of octets available. Computed before the allocation
470 @retval EFI_SUCCESS Operation completed successfully.
471 @retval EFI_DEVICE_ERROR The command was unsuccessful.
476 IN TPMI_RH_PLATFORM AuthHandle
,
477 IN TPMS_AUTH_COMMAND
*AuthSession
,
478 IN TPML_PCR_SELECTION
*PcrAllocation
,
479 OUT TPMI_YES_NO
*AllocationSuccess
,
481 OUT UINT32
*SizeNeeded
,
482 OUT UINT32
*SizeAvailable
486 TPM2_PCR_ALLOCATE_COMMAND Cmd
;
487 TPM2_PCR_ALLOCATE_RESPONSE Res
;
491 UINT32 SessionInfoSize
;
493 UINT32 ResultBufSize
;
499 Cmd
.Header
.tag
= SwapBytes16 (TPM_ST_SESSIONS
);
500 Cmd
.Header
.paramSize
= SwapBytes32 (sizeof (Cmd
));
501 Cmd
.Header
.commandCode
= SwapBytes32 (TPM_CC_PCR_Allocate
);
502 Cmd
.AuthHandle
= SwapBytes32 (AuthHandle
);
505 // Add in Auth session
507 Buffer
= (UINT8
*)&Cmd
.AuthSession
;
510 SessionInfoSize
= CopyAuthSessionCommand (AuthSession
, Buffer
);
511 Buffer
+= SessionInfoSize
;
512 Cmd
.AuthSessionSize
= SwapBytes32 (SessionInfoSize
);
515 WriteUnaligned32 ((UINT32
*)Buffer
, SwapBytes32 (PcrAllocation
->count
));
516 Buffer
+= sizeof (UINT32
);
517 for (Index
= 0; Index
< PcrAllocation
->count
; Index
++) {
518 WriteUnaligned16 ((UINT16
*)Buffer
, SwapBytes16 (PcrAllocation
->pcrSelections
[Index
].hash
));
519 Buffer
+= sizeof (UINT16
);
520 *(UINT8
*)Buffer
= PcrAllocation
->pcrSelections
[Index
].sizeofSelect
;
522 CopyMem (Buffer
, PcrAllocation
->pcrSelections
[Index
].pcrSelect
, PcrAllocation
->pcrSelections
[Index
].sizeofSelect
);
523 Buffer
+= PcrAllocation
->pcrSelections
[Index
].sizeofSelect
;
526 CmdSize
= (UINT32
)(Buffer
- (UINT8
*)&Cmd
);
527 Cmd
.Header
.paramSize
= SwapBytes32 (CmdSize
);
529 ResultBuf
= (UINT8
*)&Res
;
530 ResultBufSize
= sizeof (Res
);
535 Status
= Tpm2SubmitCommand (
541 if (EFI_ERROR (Status
)) {
545 if (ResultBufSize
> sizeof (Res
)) {
546 DEBUG ((DEBUG_ERROR
, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));
547 Status
= EFI_BUFFER_TOO_SMALL
;
552 // Validate response headers
554 RespSize
= SwapBytes32 (Res
.Header
.paramSize
);
555 if (RespSize
> sizeof (Res
)) {
556 DEBUG ((DEBUG_ERROR
, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize
));
557 Status
= EFI_BUFFER_TOO_SMALL
;
562 // Fail if command failed
564 if (SwapBytes32 (Res
.Header
.responseCode
) != TPM_RC_SUCCESS
) {
565 DEBUG ((DEBUG_ERROR
, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res
.Header
.responseCode
)));
566 Status
= EFI_DEVICE_ERROR
;
571 // Return the response
573 *AllocationSuccess
= Res
.AllocationSuccess
;
574 *MaxPCR
= SwapBytes32 (Res
.MaxPCR
);
575 *SizeNeeded
= SwapBytes32 (Res
.SizeNeeded
);
576 *SizeAvailable
= SwapBytes32 (Res
.SizeAvailable
);
580 // Clear AuthSession Content
582 ZeroMem (&Cmd
, sizeof (Cmd
));
583 ZeroMem (&Res
, sizeof (Res
));
590 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
591 @param[in] SupportedPCRBanks Supported PCR banks
592 @param[in] PCRBanks PCR banks
594 @retval EFI_SUCCESS Operation completed successfully.
598 Tpm2PcrAllocateBanks (
599 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
,
600 IN UINT32 SupportedPCRBanks
,
605 TPMS_AUTH_COMMAND
*AuthSession
;
606 TPMS_AUTH_COMMAND LocalAuthSession
;
607 TPML_PCR_SELECTION PcrAllocation
;
608 TPMI_YES_NO AllocationSuccess
;
611 UINT32 SizeAvailable
;
613 if (PlatformAuth
== NULL
) {
616 AuthSession
= &LocalAuthSession
;
617 ZeroMem (&LocalAuthSession
, sizeof (LocalAuthSession
));
618 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
619 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
620 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
626 ZeroMem (&PcrAllocation
, sizeof (PcrAllocation
));
627 if ((HASH_ALG_SHA1
& SupportedPCRBanks
) != 0) {
628 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].hash
= TPM_ALG_SHA1
;
629 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].sizeofSelect
= PCR_SELECT_MAX
;
630 if ((HASH_ALG_SHA1
& PCRBanks
) != 0) {
631 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0xFF;
632 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0xFF;
633 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0xFF;
635 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0x00;
636 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0x00;
637 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0x00;
640 PcrAllocation
.count
++;
643 if ((HASH_ALG_SHA256
& SupportedPCRBanks
) != 0) {
644 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].hash
= TPM_ALG_SHA256
;
645 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].sizeofSelect
= PCR_SELECT_MAX
;
646 if ((HASH_ALG_SHA256
& PCRBanks
) != 0) {
647 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0xFF;
648 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0xFF;
649 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0xFF;
651 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0x00;
652 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0x00;
653 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0x00;
656 PcrAllocation
.count
++;
659 if ((HASH_ALG_SHA384
& SupportedPCRBanks
) != 0) {
660 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].hash
= TPM_ALG_SHA384
;
661 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].sizeofSelect
= PCR_SELECT_MAX
;
662 if ((HASH_ALG_SHA384
& PCRBanks
) != 0) {
663 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0xFF;
664 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0xFF;
665 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0xFF;
667 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0x00;
668 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0x00;
669 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0x00;
672 PcrAllocation
.count
++;
675 if ((HASH_ALG_SHA512
& SupportedPCRBanks
) != 0) {
676 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].hash
= TPM_ALG_SHA512
;
677 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].sizeofSelect
= PCR_SELECT_MAX
;
678 if ((HASH_ALG_SHA512
& PCRBanks
) != 0) {
679 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0xFF;
680 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0xFF;
681 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0xFF;
683 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0x00;
684 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0x00;
685 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0x00;
688 PcrAllocation
.count
++;
691 if ((HASH_ALG_SM3_256
& SupportedPCRBanks
) != 0) {
692 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].hash
= TPM_ALG_SM3_256
;
693 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].sizeofSelect
= PCR_SELECT_MAX
;
694 if ((HASH_ALG_SM3_256
& PCRBanks
) != 0) {
695 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0xFF;
696 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0xFF;
697 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0xFF;
699 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[0] = 0x00;
700 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[1] = 0x00;
701 PcrAllocation
.pcrSelections
[PcrAllocation
.count
].pcrSelect
[2] = 0x00;
704 PcrAllocation
.count
++;
707 Status
= Tpm2PcrAllocate (
716 DEBUG ((DEBUG_INFO
, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status
));
717 if (EFI_ERROR (Status
)) {
721 DEBUG ((DEBUG_INFO
, "AllocationSuccess - %02x\n", AllocationSuccess
));
722 DEBUG ((DEBUG_INFO
, "MaxPCR - %08x\n", MaxPCR
));
723 DEBUG ((DEBUG_INFO
, "SizeNeeded - %08x\n", SizeNeeded
));
724 DEBUG ((DEBUG_INFO
, "SizeAvailable - %08x\n", SizeAvailable
));
727 ZeroMem (&LocalAuthSession
.hmac
, sizeof (LocalAuthSession
.hmac
));
732 This function will query the TPM to determine which hashing algorithms and
733 get the digests of all active and supported PCR banks of a specific PCR register.
735 @param[in] PcrHandle The index of the PCR register to be read.
736 @param[out] HashList List of digests from PCR register being read.
738 @retval EFI_SUCCESS The Pcr was read successfully.
739 @retval EFI_DEVICE_ERROR The command was unsuccessful.
743 Tpm2PcrReadForActiveBank (
744 IN TPMI_DH_PCR PcrHandle
,
745 OUT TPML_DIGEST
*HashList
749 TPML_PCR_SELECTION Pcrs
;
750 TPML_PCR_SELECTION PcrSelectionIn
;
751 TPML_PCR_SELECTION PcrSelectionOut
;
752 TPML_DIGEST PcrValues
;
753 UINT32 PcrUpdateCounter
;
755 UINT32 TpmHashAlgorithmBitmap
;
756 TPMI_ALG_HASH CurrentPcrBankHash
;
757 UINT32 ActivePcrBanks
;
758 UINT32 TcgRegistryHashAlg
;
762 PcrIndex
= (UINT8
)PcrHandle
;
764 if ((PcrIndex
< 0) ||
765 (PcrIndex
>= IMPLEMENTATION_PCR
))
767 return EFI_INVALID_PARAMETER
;
770 ZeroMem (&PcrSelectionIn
, sizeof (PcrSelectionIn
));
771 ZeroMem (&PcrUpdateCounter
, sizeof (UINT32
));
772 ZeroMem (&PcrSelectionOut
, sizeof (PcrSelectionOut
));
773 ZeroMem (&PcrValues
, sizeof (PcrValues
));
774 ZeroMem (&Pcrs
, sizeof (TPML_PCR_SELECTION
));
776 DEBUG ((DEBUG_INFO
, "ReadPcr - %02d\n", PcrIndex
));
779 // Read TPM capabilities
781 Status
= Tpm2GetCapabilityPcrs (&Pcrs
);
783 if (EFI_ERROR (Status
)) {
784 DEBUG ((DEBUG_ERROR
, "ReadPcr: Unable to read TPM capabilities\n"));
785 return EFI_DEVICE_ERROR
;
791 Status
= Tpm2GetCapabilitySupportedAndActivePcrs (
792 &TpmHashAlgorithmBitmap
,
796 if (EFI_ERROR (Status
)) {
797 DEBUG ((DEBUG_ERROR
, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));
798 return EFI_DEVICE_ERROR
;
802 // Select from Active PCRs
804 for (Index
= 0; Index
< Pcrs
.count
; Index
++) {
805 CurrentPcrBankHash
= Pcrs
.pcrSelections
[Index
].hash
;
807 switch (CurrentPcrBankHash
) {
809 DEBUG ((DEBUG_VERBOSE
, "HASH_ALG_SHA1 Present\n"));
810 TcgRegistryHashAlg
= HASH_ALG_SHA1
;
813 DEBUG ((DEBUG_VERBOSE
, "HASH_ALG_SHA256 Present\n"));
814 TcgRegistryHashAlg
= HASH_ALG_SHA256
;
817 DEBUG ((DEBUG_VERBOSE
, "HASH_ALG_SHA384 Present\n"));
818 TcgRegistryHashAlg
= HASH_ALG_SHA384
;
821 DEBUG ((DEBUG_VERBOSE
, "HASH_ALG_SHA512 Present\n"));
822 TcgRegistryHashAlg
= HASH_ALG_SHA512
;
824 case TPM_ALG_SM3_256
:
825 DEBUG ((DEBUG_VERBOSE
, "HASH_ALG_SM3 Present\n"));
826 TcgRegistryHashAlg
= HASH_ALG_SM3_256
;
830 // Unsupported algorithm
832 DEBUG ((DEBUG_VERBOSE
, "Unknown algorithm present\n"));
833 TcgRegistryHashAlg
= 0;
838 // Skip unsupported and inactive PCR banks
840 if ((TcgRegistryHashAlg
& ActivePcrBanks
) == 0) {
841 DEBUG ((DEBUG_VERBOSE
, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash
));
846 // Select PCR from current active bank
848 PcrSelectionIn
.pcrSelections
[PcrSelectionIn
.count
].hash
= Pcrs
.pcrSelections
[Index
].hash
;
849 PcrSelectionIn
.pcrSelections
[PcrSelectionIn
.count
].sizeofSelect
= PCR_SELECT_MAX
;
850 PcrSelectionIn
.pcrSelections
[PcrSelectionIn
.count
].pcrSelect
[0] = (PcrIndex
< 8) ? 1 << PcrIndex
: 0;
851 PcrSelectionIn
.pcrSelections
[PcrSelectionIn
.count
].pcrSelect
[1] = (PcrIndex
> 7) && (PcrIndex
< 16) ? 1 << (PcrIndex
- 8) : 0;
852 PcrSelectionIn
.pcrSelections
[PcrSelectionIn
.count
].pcrSelect
[2] = (PcrIndex
> 15) ? 1 << (PcrIndex
- 16) : 0;
853 PcrSelectionIn
.count
++;
859 Status
= Tpm2PcrRead (
866 if (EFI_ERROR (Status
)) {
867 DEBUG ((DEBUG_ERROR
, "Tpm2PcrRead failed Status = %r \n", Status
));
868 return EFI_DEVICE_ERROR
;
871 for (Index
= 0; Index
< PcrValues
.count
; Index
++) {
874 "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",
875 PcrSelectionOut
.pcrSelections
[Index
].hash
,
879 for (Index2
= 0; Index2
< PcrValues
.digests
[Index
].size
; Index2
++) {
880 DEBUG ((DEBUG_INFO
, "%02x ", PcrValues
.digests
[Index
].buffer
[Index2
]));
883 DEBUG ((DEBUG_INFO
, "\n"));
886 if (HashList
!= NULL
) {