]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 Integrity related command.\r
3\r
8ed85689 4Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r
289b714b 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c1d93242
JY
6\r
7**/\r
8\r
9#include <IndustryStandard/UefiTcgPlatform.h>\r
10#include <Library/Tpm2CommandLib.h>\r
11#include <Library/Tpm2DeviceLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/BaseLib.h>\r
14#include <Library/DebugLib.h>\r
15\r
16#pragma pack(1)\r
17\r
18typedef struct {\r
c411b485
MK
19 TPM2_COMMAND_HEADER Header;\r
20 TPMI_DH_PCR PcrHandle;\r
21 UINT32 AuthorizationSize;\r
22 TPMS_AUTH_COMMAND AuthSessionPcr;\r
23 TPML_DIGEST_VALUES DigestValues;\r
c1d93242
JY
24} TPM2_PCR_EXTEND_COMMAND;\r
25\r
26typedef struct {\r
c411b485
MK
27 TPM2_RESPONSE_HEADER Header;\r
28 UINT32 ParameterSize;\r
29 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
c1d93242
JY
30} TPM2_PCR_EXTEND_RESPONSE;\r
31\r
32typedef struct {\r
c411b485
MK
33 TPM2_COMMAND_HEADER Header;\r
34 TPMI_DH_PCR PcrHandle;\r
35 UINT32 AuthorizationSize;\r
36 TPMS_AUTH_COMMAND AuthSessionPcr;\r
37 TPM2B_EVENT EventData;\r
c1d93242
JY
38} TPM2_PCR_EVENT_COMMAND;\r
39\r
40typedef struct {\r
c411b485
MK
41 TPM2_RESPONSE_HEADER Header;\r
42 UINT32 ParameterSize;\r
43 TPML_DIGEST_VALUES Digests;\r
44 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
c1d93242
JY
45} TPM2_PCR_EVENT_RESPONSE;\r
46\r
47typedef struct {\r
c411b485
MK
48 TPM2_COMMAND_HEADER Header;\r
49 TPML_PCR_SELECTION PcrSelectionIn;\r
c1d93242
JY
50} TPM2_PCR_READ_COMMAND;\r
51\r
52typedef struct {\r
c411b485
MK
53 TPM2_RESPONSE_HEADER Header;\r
54 UINT32 PcrUpdateCounter;\r
55 TPML_PCR_SELECTION PcrSelectionOut;\r
56 TPML_DIGEST PcrValues;\r
c1d93242
JY
57} TPM2_PCR_READ_RESPONSE;\r
58\r
59typedef struct {\r
c411b485
MK
60 TPM2_COMMAND_HEADER Header;\r
61 TPMI_RH_PLATFORM AuthHandle;\r
62 UINT32 AuthSessionSize;\r
63 TPMS_AUTH_COMMAND AuthSession;\r
64 TPML_PCR_SELECTION PcrAllocation;\r
c1d93242
JY
65} TPM2_PCR_ALLOCATE_COMMAND;\r
66\r
67typedef struct {\r
c411b485
MK
68 TPM2_RESPONSE_HEADER Header;\r
69 UINT32 AuthSessionSize;\r
70 TPMI_YES_NO AllocationSuccess;\r
71 UINT32 MaxPCR;\r
72 UINT32 SizeNeeded;\r
73 UINT32 SizeAvailable;\r
74 TPMS_AUTH_RESPONSE AuthSession;\r
c1d93242
JY
75} TPM2_PCR_ALLOCATE_RESPONSE;\r
76\r
77#pragma pack()\r
78\r
79/**\r
80 This command is used to cause an update to the indicated PCR.\r
81 The digests parameter contains one or more tagged digest value identified by an algorithm ID.\r
82 For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).\r
83\r
84 @param[in] PcrHandle Handle of the PCR\r
85 @param[in] Digests List of tagged digest values to be extended\r
86\r
87 @retval EFI_SUCCESS Operation completed successfully.\r
88 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
89**/\r
90EFI_STATUS\r
91EFIAPI\r
92Tpm2PcrExtend (\r
c411b485
MK
93 IN TPMI_DH_PCR PcrHandle,\r
94 IN TPML_DIGEST_VALUES *Digests\r
c1d93242
JY
95 )\r
96{\r
c411b485
MK
97 EFI_STATUS Status;\r
98 TPM2_PCR_EXTEND_COMMAND Cmd;\r
99 TPM2_PCR_EXTEND_RESPONSE Res;\r
100 UINT32 CmdSize;\r
101 UINT32 RespSize;\r
102 UINT32 ResultBufSize;\r
103 UINT8 *Buffer;\r
104 UINTN Index;\r
105 UINT32 SessionInfoSize;\r
106 UINT16 DigestSize;\r
c1d93242 107\r
c411b485
MK
108 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
109 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Extend);\r
110 Cmd.PcrHandle = SwapBytes32 (PcrHandle);\r
c1d93242
JY
111\r
112 //\r
113 // Add in Auth session\r
114 //\r
115 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
b3548d32 116\r
c1d93242 117 // sessionInfoSize\r
c411b485
MK
118 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
119 Buffer += SessionInfoSize;\r
120 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
b3548d32 121\r
c411b485
MK
122 // Digest Count\r
123 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Digests->count));\r
124 Buffer += sizeof (UINT32);\r
b3548d32 125\r
c411b485 126 // Digest\r
c1d93242 127 for (Index = 0; Index < Digests->count; Index++) {\r
c411b485
MK
128 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Digests->digests[Index].hashAlg));\r
129 Buffer += sizeof (UINT16);\r
c1d93242
JY
130 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
131 if (DigestSize == 0) {\r
e905fbb0 132 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
c1d93242
JY
133 return EFI_DEVICE_ERROR;\r
134 }\r
c411b485
MK
135\r
136 CopyMem (\r
c1d93242
JY
137 Buffer,\r
138 &Digests->digests[Index].digest,\r
139 DigestSize\r
140 );\r
8ed85689
RGC
141\r
142 DEBUG_CODE_BEGIN ();\r
143 UINTN Index2;\r
144 DEBUG ((\r
145 DEBUG_VERBOSE,\r
146 "Tpm2PcrExtend - Hash = 0x%04x, Pcr[%02d], digest = ",\r
147 Digests->digests[Index].hashAlg,\r
148 (UINT8)PcrHandle\r
149 ));\r
150\r
151 for (Index2 = 0; Index2 < DigestSize; Index2++) {\r
152 DEBUG ((DEBUG_VERBOSE, "%02x ", Buffer[Index2]));\r
153 }\r
154\r
155 DEBUG ((DEBUG_VERBOSE, "\n"));\r
156 DEBUG_CODE_END ();\r
157\r
c1d93242
JY
158 Buffer += DigestSize;\r
159 }\r
160\r
161 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
c411b485 162 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 163\r
c411b485
MK
164 ResultBufSize = sizeof (Res);\r
165 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
166 if (EFI_ERROR (Status)) {\r
c1d93242
JY
167 return Status;\r
168 }\r
169\r
c411b485 170 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 171 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
c1d93242
JY
172 return EFI_BUFFER_TOO_SMALL;\r
173 }\r
174\r
175 //\r
176 // Validate response headers\r
177 //\r
c411b485
MK
178 RespSize = SwapBytes32 (Res.Header.paramSize);\r
179 if (RespSize > sizeof (Res)) {\r
e905fbb0 180 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
c1d93242
JY
181 return EFI_BUFFER_TOO_SMALL;\r
182 }\r
183\r
184 //\r
185 // Fail if command failed\r
186 //\r
c411b485
MK
187 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
188 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
c1d93242
JY
189 return EFI_DEVICE_ERROR;\r
190 }\r
191\r
8ed85689
RGC
192 DEBUG_CODE_BEGIN ();\r
193 DEBUG ((DEBUG_VERBOSE, "Tpm2PcrExtend: PCR read after extend...\n"));\r
194 Tpm2PcrReadForActiveBank (PcrHandle, NULL);\r
195 DEBUG_CODE_END ();\r
196\r
c1d93242
JY
197 //\r
198 // Unmarshal the response\r
199 //\r
200\r
201 // None\r
202\r
203 return EFI_SUCCESS;\r
204}\r
205\r
206/**\r
207 This command is used to cause an update to the indicated PCR.\r
208 The data in eventData is hashed using the hash algorithm associated with each bank in which the\r
209 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle\r
210 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in\r
211 TPM2_PCR_Extend().\r
212 A TPM shall support an Event.size of zero through 1,024 inclusive.\r
213\r
214 @param[in] PcrHandle Handle of the PCR\r
215 @param[in] EventData Event data in sized buffer\r
216 @param[out] Digests List of digest\r
217\r
218 @retval EFI_SUCCESS Operation completed successfully.\r
219 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
220**/\r
221EFI_STATUS\r
222EFIAPI\r
223Tpm2PcrEvent (\r
c411b485
MK
224 IN TPMI_DH_PCR PcrHandle,\r
225 IN TPM2B_EVENT *EventData,\r
226 OUT TPML_DIGEST_VALUES *Digests\r
c1d93242
JY
227 )\r
228{\r
c411b485
MK
229 EFI_STATUS Status;\r
230 TPM2_PCR_EVENT_COMMAND Cmd;\r
231 TPM2_PCR_EVENT_RESPONSE Res;\r
232 UINT32 CmdSize;\r
233 UINT32 RespSize;\r
234 UINT32 ResultBufSize;\r
235 UINT8 *Buffer;\r
236 UINTN Index;\r
237 UINT32 SessionInfoSize;\r
238 UINT16 DigestSize;\r
239\r
240 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
241 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Event);\r
242 Cmd.PcrHandle = SwapBytes32 (PcrHandle);\r
c1d93242
JY
243\r
244 //\r
245 // Add in Auth session\r
246 //\r
247 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
248\r
249 // sessionInfoSize\r
c411b485
MK
250 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
251 Buffer += SessionInfoSize;\r
252 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
c1d93242
JY
253\r
254 // Event\r
c411b485
MK
255 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));\r
256 Buffer += sizeof (UINT16);\r
c1d93242
JY
257\r
258 CopyMem (Buffer, EventData->buffer, EventData->size);\r
259 Buffer += EventData->size;\r
b3548d32 260\r
c1d93242 261 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
c411b485 262 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 263\r
c411b485
MK
264 ResultBufSize = sizeof (Res);\r
265 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
266 if (EFI_ERROR (Status)) {\r
c1d93242
JY
267 return Status;\r
268 }\r
269\r
c411b485 270 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 271 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
c1d93242
JY
272 return EFI_BUFFER_TOO_SMALL;\r
273 }\r
274\r
275 //\r
276 // Validate response headers\r
277 //\r
c411b485
MK
278 RespSize = SwapBytes32 (Res.Header.paramSize);\r
279 if (RespSize > sizeof (Res)) {\r
e905fbb0 280 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
c1d93242
JY
281 return EFI_BUFFER_TOO_SMALL;\r
282 }\r
283\r
284 //\r
285 // Fail if command failed\r
286 //\r
c411b485
MK
287 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
288 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
c1d93242
JY
289 return EFI_DEVICE_ERROR;\r
290 }\r
291\r
292 //\r
293 // Unmarshal the response\r
294 //\r
295 Buffer = (UINT8 *)&Res.Digests;\r
296\r
297 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\r
dd577319
ZC
298 if (Digests->count > HASH_COUNT) {\r
299 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));\r
300 return EFI_DEVICE_ERROR;\r
301 }\r
302\r
c411b485 303 Buffer += sizeof (UINT32);\r
c1d93242
JY
304 for (Index = 0; Index < Digests->count; Index++) {\r
305 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
c411b485
MK
306 Buffer += sizeof (UINT16);\r
307 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
c1d93242 308 if (DigestSize == 0) {\r
e905fbb0 309 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
c1d93242
JY
310 return EFI_DEVICE_ERROR;\r
311 }\r
c411b485
MK
312\r
313 CopyMem (\r
c1d93242
JY
314 &Digests->digests[Index].digest,\r
315 Buffer,\r
316 DigestSize\r
317 );\r
318 Buffer += DigestSize;\r
319 }\r
320\r
321 return EFI_SUCCESS;\r
322}\r
323\r
324/**\r
325 This command returns the values of all PCR specified in pcrSelect.\r
326\r
327 @param[in] PcrSelectionIn The selection of PCR to read.\r
328 @param[out] PcrUpdateCounter The current value of the PCR update counter.\r
329 @param[out] PcrSelectionOut The PCR in the returned list.\r
330 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.\r
b3548d32 331\r
c1d93242
JY
332 @retval EFI_SUCCESS Operation completed successfully.\r
333 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
334**/\r
335EFI_STATUS\r
336EFIAPI\r
337Tpm2PcrRead (\r
c411b485
MK
338 IN TPML_PCR_SELECTION *PcrSelectionIn,\r
339 OUT UINT32 *PcrUpdateCounter,\r
340 OUT TPML_PCR_SELECTION *PcrSelectionOut,\r
341 OUT TPML_DIGEST *PcrValues\r
c1d93242
JY
342 )\r
343{\r
c411b485
MK
344 EFI_STATUS Status;\r
345 TPM2_PCR_READ_COMMAND SendBuffer;\r
346 TPM2_PCR_READ_RESPONSE RecvBuffer;\r
347 UINT32 SendBufferSize;\r
348 UINT32 RecvBufferSize;\r
349 UINTN Index;\r
350 TPML_DIGEST *PcrValuesOut;\r
351 TPM2B_DIGEST *Digests;\r
c1d93242
JY
352\r
353 //\r
354 // Construct command\r
355 //\r
c411b485
MK
356 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
357 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);\r
b3548d32 358\r
c411b485 359 SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);\r
c1d93242 360 for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
c411b485 361 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);\r
c1d93242
JY
362 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;\r
363 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);\r
364 }\r
365\r
c411b485 366 SendBufferSize = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
c1d93242
JY
367 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
368\r
369 //\r
370 // send Tpm command\r
371 //\r
372 RecvBufferSize = sizeof (RecvBuffer);\r
c411b485 373 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
c1d93242
JY
374 if (EFI_ERROR (Status)) {\r
375 return Status;\r
376 }\r
377\r
378 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
e905fbb0 379 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
380 return EFI_DEVICE_ERROR;\r
381 }\r
c411b485
MK
382\r
383 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
384 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
c1d93242
JY
385 return EFI_NOT_FOUND;\r
386 }\r
387\r
388 //\r
389 // Return the response\r
390 //\r
391\r
392 //\r
393 // PcrUpdateCounter\r
394 //\r
c411b485 395 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {\r
e905fbb0 396 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
397 return EFI_DEVICE_ERROR;\r
398 }\r
c411b485
MK
399\r
400 *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);\r
c1d93242
JY
401\r
402 //\r
403 // PcrSelectionOut\r
404 //\r
c411b485 405 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {\r
e905fbb0 406 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
407 return EFI_DEVICE_ERROR;\r
408 }\r
c411b485
MK
409\r
410 PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);\r
dd577319
ZC
411 if (PcrSelectionOut->count > HASH_COUNT) {\r
412 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));\r
413 return EFI_DEVICE_ERROR;\r
414 }\r
415\r
c411b485 416 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
e905fbb0 417 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
418 return EFI_DEVICE_ERROR;\r
419 }\r
c411b485 420\r
c1d93242 421 for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
c411b485 422 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
c1d93242 423 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
dd577319
ZC
424 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
425 return EFI_DEVICE_ERROR;\r
426 }\r
c411b485 427\r
c1d93242
JY
428 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
429 }\r
430\r
431 //\r
432 // PcrValues\r
433 //\r
c411b485
MK
434 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
435 PcrValues->count = SwapBytes32 (PcrValuesOut->count);\r
dd577319
ZC
436 //\r
437 // The number of digests in list is not greater than 8 per TPML_DIGEST definition\r
438 //\r
439 if (PcrValues->count > 8) {\r
440 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));\r
441 return EFI_DEVICE_ERROR;\r
442 }\r
c411b485 443\r
c1d93242
JY
444 Digests = PcrValuesOut->digests;\r
445 for (Index = 0; Index < PcrValues->count; Index++) {\r
c411b485
MK
446 PcrValues->digests[Index].size = SwapBytes16 (Digests->size);\r
447 if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {\r
dd577319
ZC
448 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));\r
449 return EFI_DEVICE_ERROR;\r
450 }\r
c411b485 451\r
c1d93242 452 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
c411b485 453 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);\r
c1d93242
JY
454 }\r
455\r
456 return EFI_SUCCESS;\r
457}\r
458\r
459/**\r
460 This command is used to set the desired PCR allocation of PCR and algorithms.\r
461\r
462 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
463 @param[in] AuthSession Auth Session context\r
464 @param[in] PcrAllocation The requested allocation\r
465 @param[out] AllocationSuccess YES if the allocation succeeded\r
466 @param[out] MaxPCR maximum number of PCR that may be in a bank\r
467 @param[out] SizeNeeded number of octets required to satisfy the request\r
468 @param[out] SizeAvailable Number of octets available. Computed before the allocation\r
b3548d32 469\r
c1d93242
JY
470 @retval EFI_SUCCESS Operation completed successfully.\r
471 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
472**/\r
473EFI_STATUS\r
474EFIAPI\r
475Tpm2PcrAllocate (\r
c411b485
MK
476 IN TPMI_RH_PLATFORM AuthHandle,\r
477 IN TPMS_AUTH_COMMAND *AuthSession,\r
478 IN TPML_PCR_SELECTION *PcrAllocation,\r
479 OUT TPMI_YES_NO *AllocationSuccess,\r
480 OUT UINT32 *MaxPCR,\r
481 OUT UINT32 *SizeNeeded,\r
482 OUT UINT32 *SizeAvailable\r
c1d93242
JY
483 )\r
484{\r
485 EFI_STATUS Status;\r
486 TPM2_PCR_ALLOCATE_COMMAND Cmd;\r
487 TPM2_PCR_ALLOCATE_RESPONSE Res;\r
488 UINT32 CmdSize;\r
489 UINT32 RespSize;\r
490 UINT8 *Buffer;\r
491 UINT32 SessionInfoSize;\r
492 UINT8 *ResultBuf;\r
493 UINT32 ResultBufSize;\r
494 UINTN Index;\r
495\r
496 //\r
497 // Construct command\r
498 //\r
c411b485
MK
499 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
500 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));\r
501 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);\r
502 Cmd.AuthHandle = SwapBytes32 (AuthHandle);\r
c1d93242
JY
503\r
504 //\r
505 // Add in Auth session\r
506 //\r
507 Buffer = (UINT8 *)&Cmd.AuthSession;\r
508\r
509 // sessionInfoSize\r
c411b485
MK
510 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
511 Buffer += SessionInfoSize;\r
512 Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);\r
c1d93242
JY
513\r
514 // Count\r
c411b485
MK
515 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));\r
516 Buffer += sizeof (UINT32);\r
c1d93242 517 for (Index = 0; Index < PcrAllocation->count; Index++) {\r
c411b485
MK
518 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));\r
519 Buffer += sizeof (UINT16);\r
c1d93242 520 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
58dbfc3c 521 Buffer++;\r
c1d93242
JY
522 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
523 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
524 }\r
525\r
c411b485
MK
526 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
527 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 528\r
c411b485
MK
529 ResultBuf = (UINT8 *)&Res;\r
530 ResultBufSize = sizeof (Res);\r
c1d93242
JY
531\r
532 //\r
533 // Call the TPM\r
534 //\r
535 Status = Tpm2SubmitCommand (\r
b3548d32
LG
536 CmdSize,\r
537 (UINT8 *)&Cmd,\r
c1d93242
JY
538 &ResultBufSize,\r
539 ResultBuf\r
540 );\r
c411b485 541 if (EFI_ERROR (Status)) {\r
7ae130da
JY
542 goto Done;\r
543 }\r
c1d93242 544\r
c411b485 545 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 546 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
7ae130da
JY
547 Status = EFI_BUFFER_TOO_SMALL;\r
548 goto Done;\r
c1d93242
JY
549 }\r
550\r
551 //\r
552 // Validate response headers\r
553 //\r
c411b485
MK
554 RespSize = SwapBytes32 (Res.Header.paramSize);\r
555 if (RespSize > sizeof (Res)) {\r
e905fbb0 556 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
7ae130da
JY
557 Status = EFI_BUFFER_TOO_SMALL;\r
558 goto Done;\r
c1d93242
JY
559 }\r
560\r
561 //\r
562 // Fail if command failed\r
563 //\r
c411b485
MK
564 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
565 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
7ae130da
JY
566 Status = EFI_DEVICE_ERROR;\r
567 goto Done;\r
c1d93242
JY
568 }\r
569\r
570 //\r
571 // Return the response\r
572 //\r
573 *AllocationSuccess = Res.AllocationSuccess;\r
c411b485
MK
574 *MaxPCR = SwapBytes32 (Res.MaxPCR);\r
575 *SizeNeeded = SwapBytes32 (Res.SizeNeeded);\r
576 *SizeAvailable = SwapBytes32 (Res.SizeAvailable);\r
c1d93242 577\r
7ae130da
JY
578Done:\r
579 //\r
580 // Clear AuthSession Content\r
581 //\r
c411b485
MK
582 ZeroMem (&Cmd, sizeof (Cmd));\r
583 ZeroMem (&Res, sizeof (Res));\r
7ae130da 584 return Status;\r
c1d93242 585}\r
f9c9a140
JY
586\r
587/**\r
588 Alloc PCR data.\r
589\r
590 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
591 @param[in] SupportedPCRBanks Supported PCR banks\r
592 @param[in] PCRBanks PCR banks\r
b3548d32 593\r
f9c9a140
JY
594 @retval EFI_SUCCESS Operation completed successfully.\r
595**/\r
596EFI_STATUS\r
597EFIAPI\r
598Tpm2PcrAllocateBanks (\r
c411b485
MK
599 IN TPM2B_AUTH *PlatformAuth OPTIONAL,\r
600 IN UINT32 SupportedPCRBanks,\r
601 IN UINT32 PCRBanks\r
f9c9a140
JY
602 )\r
603{\r
c411b485
MK
604 EFI_STATUS Status;\r
605 TPMS_AUTH_COMMAND *AuthSession;\r
606 TPMS_AUTH_COMMAND LocalAuthSession;\r
607 TPML_PCR_SELECTION PcrAllocation;\r
608 TPMI_YES_NO AllocationSuccess;\r
609 UINT32 MaxPCR;\r
610 UINT32 SizeNeeded;\r
611 UINT32 SizeAvailable;\r
f9c9a140
JY
612\r
613 if (PlatformAuth == NULL) {\r
614 AuthSession = NULL;\r
615 } else {\r
616 AuthSession = &LocalAuthSession;\r
c411b485 617 ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));\r
f9c9a140 618 LocalAuthSession.sessionHandle = TPM_RS_PW;\r
c411b485 619 LocalAuthSession.hmac.size = PlatformAuth->size;\r
f9c9a140
JY
620 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
621 }\r
622\r
623 //\r
624 // Fill input\r
625 //\r
c411b485 626 ZeroMem (&PcrAllocation, sizeof (PcrAllocation));\r
f9c9a140 627 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
c411b485 628 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;\r
f9c9a140
JY
629 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
630 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {\r
631 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
632 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
633 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
634 } else {\r
635 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
636 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
637 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
638 }\r
c411b485 639\r
f9c9a140
JY
640 PcrAllocation.count++;\r
641 }\r
c411b485 642\r
f9c9a140 643 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
c411b485 644 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;\r
f9c9a140
JY
645 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
646 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {\r
647 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
648 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
649 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
650 } else {\r
651 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
652 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
653 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
654 }\r
c411b485 655\r
f9c9a140
JY
656 PcrAllocation.count++;\r
657 }\r
c411b485 658\r
f9c9a140 659 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
c411b485 660 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;\r
f9c9a140
JY
661 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
662 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {\r
663 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
664 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
665 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
666 } else {\r
667 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
668 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
669 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
670 }\r
c411b485 671\r
f9c9a140
JY
672 PcrAllocation.count++;\r
673 }\r
c411b485 674\r
f9c9a140 675 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
c411b485 676 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;\r
f9c9a140
JY
677 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
678 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {\r
679 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
680 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
681 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
682 } else {\r
683 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
684 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
685 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
686 }\r
c411b485 687\r
f9c9a140
JY
688 PcrAllocation.count++;\r
689 }\r
c411b485 690\r
f9c9a140 691 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
c411b485 692 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;\r
f9c9a140
JY
693 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
694 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
695 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
696 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
697 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
698 } else {\r
699 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
700 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
701 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
702 }\r
c411b485 703\r
f9c9a140
JY
704 PcrAllocation.count++;\r
705 }\r
c411b485 706\r
f9c9a140
JY
707 Status = Tpm2PcrAllocate (\r
708 TPM_RH_PLATFORM,\r
709 AuthSession,\r
710 &PcrAllocation,\r
711 &AllocationSuccess,\r
712 &MaxPCR,\r
713 &SizeNeeded,\r
714 &SizeAvailable\r
715 );\r
e905fbb0 716 DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
f9c9a140
JY
717 if (EFI_ERROR (Status)) {\r
718 goto Done;\r
719 }\r
720\r
e905fbb0
MK
721 DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
722 DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));\r
723 DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));\r
724 DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));\r
f9c9a140
JY
725\r
726Done:\r
c411b485 727 ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));\r
f9c9a140 728 return Status;\r
b3548d32 729}\r
8ed85689
RGC
730\r
731/**\r
732 This function will query the TPM to determine which hashing algorithms and\r
733 get the digests of all active and supported PCR banks of a specific PCR register.\r
734\r
735 @param[in] PcrHandle The index of the PCR register to be read.\r
736 @param[out] HashList List of digests from PCR register being read.\r
737\r
738 @retval EFI_SUCCESS The Pcr was read successfully.\r
739 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
740**/\r
741EFI_STATUS\r
742EFIAPI\r
743Tpm2PcrReadForActiveBank (\r
744 IN TPMI_DH_PCR PcrHandle,\r
745 OUT TPML_DIGEST *HashList\r
746 )\r
747{\r
748 EFI_STATUS Status;\r
749 TPML_PCR_SELECTION Pcrs;\r
750 TPML_PCR_SELECTION PcrSelectionIn;\r
751 TPML_PCR_SELECTION PcrSelectionOut;\r
752 TPML_DIGEST PcrValues;\r
753 UINT32 PcrUpdateCounter;\r
754 UINT8 PcrIndex;\r
755 UINT32 TpmHashAlgorithmBitmap;\r
756 TPMI_ALG_HASH CurrentPcrBankHash;\r
757 UINT32 ActivePcrBanks;\r
758 UINT32 TcgRegistryHashAlg;\r
759 UINTN Index;\r
760 UINTN Index2;\r
761\r
762 PcrIndex = (UINT8)PcrHandle;\r
763\r
764 if ((PcrIndex < 0) ||\r
765 (PcrIndex >= IMPLEMENTATION_PCR))\r
766 {\r
767 return EFI_INVALID_PARAMETER;\r
768 }\r
769\r
770 ZeroMem (&PcrSelectionIn, sizeof (PcrSelectionIn));\r
771 ZeroMem (&PcrUpdateCounter, sizeof (UINT32));\r
772 ZeroMem (&PcrSelectionOut, sizeof (PcrSelectionOut));\r
773 ZeroMem (&PcrValues, sizeof (PcrValues));\r
774 ZeroMem (&Pcrs, sizeof (TPML_PCR_SELECTION));\r
775\r
776 DEBUG ((DEBUG_INFO, "ReadPcr - %02d\n", PcrIndex));\r
777\r
778 //\r
779 // Read TPM capabilities\r
780 //\r
781 Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
782\r
783 if (EFI_ERROR (Status)) {\r
784 DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities\n"));\r
785 return EFI_DEVICE_ERROR;\r
786 }\r
787\r
788 //\r
789 // Get Active Pcrs\r
790 //\r
791 Status = Tpm2GetCapabilitySupportedAndActivePcrs (\r
792 &TpmHashAlgorithmBitmap,\r
793 &ActivePcrBanks\r
794 );\r
795\r
796 if (EFI_ERROR (Status)) {\r
797 DEBUG ((DEBUG_ERROR, "ReadPcr: Unable to read TPM capabilities and active PCRs\n"));\r
798 return EFI_DEVICE_ERROR;\r
799 }\r
800\r
801 //\r
802 // Select from Active PCRs\r
803 //\r
804 for (Index = 0; Index < Pcrs.count; Index++) {\r
805 CurrentPcrBankHash = Pcrs.pcrSelections[Index].hash;\r
806\r
807 switch (CurrentPcrBankHash) {\r
808 case TPM_ALG_SHA1:\r
809 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA1 Present\n"));\r
810 TcgRegistryHashAlg = HASH_ALG_SHA1;\r
811 break;\r
812 case TPM_ALG_SHA256:\r
813 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA256 Present\n"));\r
814 TcgRegistryHashAlg = HASH_ALG_SHA256;\r
815 break;\r
816 case TPM_ALG_SHA384:\r
817 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA384 Present\n"));\r
818 TcgRegistryHashAlg = HASH_ALG_SHA384;\r
819 break;\r
820 case TPM_ALG_SHA512:\r
821 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SHA512 Present\n"));\r
822 TcgRegistryHashAlg = HASH_ALG_SHA512;\r
823 break;\r
824 case TPM_ALG_SM3_256:\r
825 DEBUG ((DEBUG_VERBOSE, "HASH_ALG_SM3 Present\n"));\r
826 TcgRegistryHashAlg = HASH_ALG_SM3_256;\r
827 break;\r
828 default:\r
829 //\r
830 // Unsupported algorithm\r
831 //\r
832 DEBUG ((DEBUG_VERBOSE, "Unknown algorithm present\n"));\r
833 TcgRegistryHashAlg = 0;\r
834 break;\r
835 }\r
836\r
837 //\r
838 // Skip unsupported and inactive PCR banks\r
839 //\r
840 if ((TcgRegistryHashAlg & ActivePcrBanks) == 0) {\r
841 DEBUG ((DEBUG_VERBOSE, "Skipping unsupported or inactive bank: 0x%04x\n", CurrentPcrBankHash));\r
842 continue;\r
843 }\r
844\r
845 //\r
846 // Select PCR from current active bank\r
847 //\r
848 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].hash = Pcrs.pcrSelections[Index].hash;\r
849 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].sizeofSelect = PCR_SELECT_MAX;\r
850 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[0] = (PcrIndex < 8) ? 1 << PcrIndex : 0;\r
851 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[1] = (PcrIndex > 7) && (PcrIndex < 16) ? 1 << (PcrIndex - 8) : 0;\r
852 PcrSelectionIn.pcrSelections[PcrSelectionIn.count].pcrSelect[2] = (PcrIndex > 15) ? 1 << (PcrIndex - 16) : 0;\r
853 PcrSelectionIn.count++;\r
854 }\r
855\r
856 //\r
857 // Read PCRs\r
858 //\r
859 Status = Tpm2PcrRead (\r
860 &PcrSelectionIn,\r
861 &PcrUpdateCounter,\r
862 &PcrSelectionOut,\r
863 &PcrValues\r
864 );\r
865\r
866 if (EFI_ERROR (Status)) {\r
867 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead failed Status = %r \n", Status));\r
868 return EFI_DEVICE_ERROR;\r
869 }\r
870\r
871 for (Index = 0; Index < PcrValues.count; Index++) {\r
872 DEBUG ((\r
873 DEBUG_INFO,\r
874 "ReadPcr - HashAlg = 0x%04x, Pcr[%02d], digest = ",\r
875 PcrSelectionOut.pcrSelections[Index].hash,\r
876 PcrIndex\r
877 ));\r
878\r
879 for (Index2 = 0; Index2 < PcrValues.digests[Index].size; Index2++) {\r
880 DEBUG ((DEBUG_INFO, "%02x ", PcrValues.digests[Index].buffer[Index2]));\r
881 }\r
882\r
883 DEBUG ((DEBUG_INFO, "\n"));\r
884 }\r
885\r
886 if (HashList != NULL) {\r
887 CopyMem (\r
888 HashList,\r
889 &PcrValues,\r
890 sizeof (TPML_DIGEST)\r
891 );\r
892 }\r
893\r
894 return EFI_SUCCESS;\r
895}\r