]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
SecurityPkg: Fix bug in TPM 1.2 SelfTest
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 Integrity related command.\r
3\r
7ae130da 4Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>\r
c1d93242
JY
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <IndustryStandard/UefiTcgPlatform.h>\r
16#include <Library/Tpm2CommandLib.h>\r
17#include <Library/Tpm2DeviceLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21\r
22#pragma pack(1)\r
23\r
24typedef struct {\r
25 TPM2_COMMAND_HEADER Header;\r
26 TPMI_DH_PCR PcrHandle;\r
27 UINT32 AuthorizationSize;\r
28 TPMS_AUTH_COMMAND AuthSessionPcr;\r
29 TPML_DIGEST_VALUES DigestValues;\r
30} TPM2_PCR_EXTEND_COMMAND;\r
31\r
32typedef struct {\r
33 TPM2_RESPONSE_HEADER Header;\r
34 UINT32 ParameterSize;\r
35 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
36} TPM2_PCR_EXTEND_RESPONSE;\r
37\r
38typedef struct {\r
39 TPM2_COMMAND_HEADER Header;\r
40 TPMI_DH_PCR PcrHandle;\r
41 UINT32 AuthorizationSize;\r
42 TPMS_AUTH_COMMAND AuthSessionPcr;\r
43 TPM2B_EVENT EventData;\r
44} TPM2_PCR_EVENT_COMMAND;\r
45\r
46typedef struct {\r
47 TPM2_RESPONSE_HEADER Header;\r
48 UINT32 ParameterSize;\r
49 TPML_DIGEST_VALUES Digests;\r
50 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
51} TPM2_PCR_EVENT_RESPONSE;\r
52\r
53typedef struct {\r
54 TPM2_COMMAND_HEADER Header;\r
55 TPML_PCR_SELECTION PcrSelectionIn;\r
56} TPM2_PCR_READ_COMMAND;\r
57\r
58typedef struct {\r
59 TPM2_RESPONSE_HEADER Header;\r
60 UINT32 PcrUpdateCounter;\r
61 TPML_PCR_SELECTION PcrSelectionOut;\r
62 TPML_DIGEST PcrValues;\r
63} TPM2_PCR_READ_RESPONSE;\r
64\r
65typedef struct {\r
66 TPM2_COMMAND_HEADER Header;\r
67 TPMI_RH_PLATFORM AuthHandle;\r
68 UINT32 AuthSessionSize;\r
69 TPMS_AUTH_COMMAND AuthSession;\r
70 TPML_PCR_SELECTION PcrAllocation;\r
71} TPM2_PCR_ALLOCATE_COMMAND;\r
72\r
73typedef struct {\r
74 TPM2_RESPONSE_HEADER Header;\r
75 UINT32 AuthSessionSize;\r
76 TPMI_YES_NO AllocationSuccess;\r
77 UINT32 MaxPCR;\r
78 UINT32 SizeNeeded;\r
79 UINT32 SizeAvailable;\r
80 TPMS_AUTH_RESPONSE AuthSession;\r
81} TPM2_PCR_ALLOCATE_RESPONSE;\r
82\r
83#pragma pack()\r
84\r
85/**\r
86 This command is used to cause an update to the indicated PCR.\r
87 The digests parameter contains one or more tagged digest value identified by an algorithm ID.\r
88 For each digest, the PCR associated with pcrHandle is Extended into the bank identified by the tag (hashAlg).\r
89\r
90 @param[in] PcrHandle Handle of the PCR\r
91 @param[in] Digests List of tagged digest values to be extended\r
92\r
93 @retval EFI_SUCCESS Operation completed successfully.\r
94 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
95**/\r
96EFI_STATUS\r
97EFIAPI\r
98Tpm2PcrExtend (\r
99 IN TPMI_DH_PCR PcrHandle,\r
100 IN TPML_DIGEST_VALUES *Digests\r
101 )\r
102{\r
103 EFI_STATUS Status;\r
104 TPM2_PCR_EXTEND_COMMAND Cmd;\r
105 TPM2_PCR_EXTEND_RESPONSE Res;\r
106 UINT32 CmdSize;\r
107 UINT32 RespSize;\r
108 UINT32 ResultBufSize;\r
109 UINT8 *Buffer;\r
110 UINTN Index;\r
111 UINT32 SessionInfoSize;\r
112 UINT16 DigestSize;\r
113\r
114 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
115 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Extend);\r
116 Cmd.PcrHandle = SwapBytes32(PcrHandle);\r
117\r
118\r
119 //\r
120 // Add in Auth session\r
121 //\r
122 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
123 \r
124 // sessionInfoSize\r
125 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
126 Buffer += SessionInfoSize;\r
127 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
128 \r
129 //Digest Count\r
130 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));\r
131 Buffer += sizeof(UINT32);\r
132 \r
133 //Digest\r
134 for (Index = 0; Index < Digests->count; Index++) {\r
135 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));\r
136 Buffer += sizeof(UINT16);\r
137 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
138 if (DigestSize == 0) {\r
139 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
140 return EFI_DEVICE_ERROR;\r
141 }\r
142 CopyMem(\r
143 Buffer,\r
144 &Digests->digests[Index].digest,\r
145 DigestSize\r
146 );\r
147 Buffer += DigestSize;\r
148 }\r
149\r
150 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
151 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
152\r
153 ResultBufSize = sizeof(Res);\r
154 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
155 if (EFI_ERROR(Status)) {\r
156 return Status;\r
157 }\r
158\r
159 if (ResultBufSize > sizeof(Res)) {\r
160 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
161 return EFI_BUFFER_TOO_SMALL;\r
162 }\r
163\r
164 //\r
165 // Validate response headers\r
166 //\r
167 RespSize = SwapBytes32(Res.Header.paramSize);\r
168 if (RespSize > sizeof(Res)) {\r
169 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
170 return EFI_BUFFER_TOO_SMALL;\r
171 }\r
172\r
173 //\r
174 // Fail if command failed\r
175 //\r
176 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
177 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
178 return EFI_DEVICE_ERROR;\r
179 }\r
180\r
181 //\r
182 // Unmarshal the response\r
183 //\r
184\r
185 // None\r
186\r
187 return EFI_SUCCESS;\r
188}\r
189\r
190/**\r
191 This command is used to cause an update to the indicated PCR.\r
192 The data in eventData is hashed using the hash algorithm associated with each bank in which the\r
193 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle\r
194 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in\r
195 TPM2_PCR_Extend().\r
196 A TPM shall support an Event.size of zero through 1,024 inclusive.\r
197\r
198 @param[in] PcrHandle Handle of the PCR\r
199 @param[in] EventData Event data in sized buffer\r
200 @param[out] Digests List of digest\r
201\r
202 @retval EFI_SUCCESS Operation completed successfully.\r
203 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
204**/\r
205EFI_STATUS\r
206EFIAPI\r
207Tpm2PcrEvent (\r
208 IN TPMI_DH_PCR PcrHandle,\r
209 IN TPM2B_EVENT *EventData,\r
210 OUT TPML_DIGEST_VALUES *Digests\r
211 )\r
212{\r
213 EFI_STATUS Status;\r
214 TPM2_PCR_EVENT_COMMAND Cmd;\r
215 TPM2_PCR_EVENT_RESPONSE Res;\r
216 UINT32 CmdSize;\r
217 UINT32 RespSize;\r
218 UINT32 ResultBufSize;\r
219 UINT8 *Buffer;\r
220 UINTN Index;\r
221 UINT32 SessionInfoSize;\r
222 UINT16 DigestSize;\r
223\r
224 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
225 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);\r
226 Cmd.PcrHandle = SwapBytes32(PcrHandle);\r
227\r
228 //\r
229 // Add in Auth session\r
230 //\r
231 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
232\r
233 // sessionInfoSize\r
234 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
235 Buffer += SessionInfoSize;\r
236 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
237\r
238 // Event\r
239 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));\r
240 Buffer += sizeof(UINT16);\r
241\r
242 CopyMem (Buffer, EventData->buffer, EventData->size);\r
243 Buffer += EventData->size;\r
244 \r
245 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
246 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
247\r
248 ResultBufSize = sizeof(Res);\r
249 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
250 if (EFI_ERROR(Status)) {\r
251 return Status;\r
252 }\r
253\r
254 if (ResultBufSize > sizeof(Res)) {\r
255 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
256 return EFI_BUFFER_TOO_SMALL;\r
257 }\r
258\r
259 //\r
260 // Validate response headers\r
261 //\r
262 RespSize = SwapBytes32(Res.Header.paramSize);\r
263 if (RespSize > sizeof(Res)) {\r
264 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
265 return EFI_BUFFER_TOO_SMALL;\r
266 }\r
267\r
268 //\r
269 // Fail if command failed\r
270 //\r
271 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
272 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
273 return EFI_DEVICE_ERROR;\r
274 }\r
275\r
276 //\r
277 // Unmarshal the response\r
278 //\r
279 Buffer = (UINT8 *)&Res.Digests;\r
280\r
281 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\r
282 Buffer += sizeof(UINT32);\r
283 for (Index = 0; Index < Digests->count; Index++) {\r
284 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
285 Buffer += sizeof(UINT16);\r
286 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
287 if (DigestSize == 0) {\r
288 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
289 return EFI_DEVICE_ERROR;\r
290 }\r
291 CopyMem(\r
292 &Digests->digests[Index].digest,\r
293 Buffer,\r
294 DigestSize\r
295 );\r
296 Buffer += DigestSize;\r
297 }\r
298\r
299 return EFI_SUCCESS;\r
300}\r
301\r
302/**\r
303 This command returns the values of all PCR specified in pcrSelect.\r
304\r
305 @param[in] PcrSelectionIn The selection of PCR to read.\r
306 @param[out] PcrUpdateCounter The current value of the PCR update counter.\r
307 @param[out] PcrSelectionOut The PCR in the returned list.\r
308 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.\r
309 \r
310 @retval EFI_SUCCESS Operation completed successfully.\r
311 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
312**/\r
313EFI_STATUS\r
314EFIAPI\r
315Tpm2PcrRead (\r
316 IN TPML_PCR_SELECTION *PcrSelectionIn,\r
317 OUT UINT32 *PcrUpdateCounter,\r
318 OUT TPML_PCR_SELECTION *PcrSelectionOut,\r
319 OUT TPML_DIGEST *PcrValues\r
320 )\r
321{\r
322 EFI_STATUS Status;\r
323 TPM2_PCR_READ_COMMAND SendBuffer;\r
324 TPM2_PCR_READ_RESPONSE RecvBuffer;\r
325 UINT32 SendBufferSize;\r
326 UINT32 RecvBufferSize;\r
327 UINTN Index;\r
328 TPML_DIGEST *PcrValuesOut;\r
329 TPM2B_DIGEST *Digests;\r
330\r
331 //\r
332 // Construct command\r
333 //\r
334 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
335 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);\r
336 \r
337 SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);\r
338 for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
339 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);\r
340 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;\r
341 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);\r
342 }\r
343\r
344 SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
345 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
346\r
347 //\r
348 // send Tpm command\r
349 //\r
350 RecvBufferSize = sizeof (RecvBuffer);\r
351 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
352 if (EFI_ERROR (Status)) {\r
353 return Status;\r
354 }\r
355\r
356 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
357 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
358 return EFI_DEVICE_ERROR;\r
359 }\r
360 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
361 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
362 return EFI_NOT_FOUND;\r
363 }\r
364\r
365 //\r
366 // Return the response\r
367 //\r
368\r
369 //\r
370 // PcrUpdateCounter\r
371 //\r
372 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {\r
373 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
374 return EFI_DEVICE_ERROR;\r
375 }\r
376 *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);\r
377\r
378 //\r
379 // PcrSelectionOut\r
380 //\r
381 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {\r
382 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
383 return EFI_DEVICE_ERROR;\r
384 }\r
385 PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);\r
386 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
387 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
388 return EFI_DEVICE_ERROR;\r
389 }\r
390 for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
391 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
392 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
393 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
394 }\r
395\r
396 //\r
397 // PcrValues\r
398 //\r
399 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
400 PcrValues->count = SwapBytes32(PcrValuesOut->count);\r
401 Digests = PcrValuesOut->digests;\r
402 for (Index = 0; Index < PcrValues->count; Index++) {\r
403 PcrValues->digests[Index].size = SwapBytes16(Digests->size);\r
404 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
405 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);\r
406 }\r
407\r
408 return EFI_SUCCESS;\r
409}\r
410\r
411/**\r
412 This command is used to set the desired PCR allocation of PCR and algorithms.\r
413\r
414 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
415 @param[in] AuthSession Auth Session context\r
416 @param[in] PcrAllocation The requested allocation\r
417 @param[out] AllocationSuccess YES if the allocation succeeded\r
418 @param[out] MaxPCR maximum number of PCR that may be in a bank\r
419 @param[out] SizeNeeded number of octets required to satisfy the request\r
420 @param[out] SizeAvailable Number of octets available. Computed before the allocation\r
421 \r
422 @retval EFI_SUCCESS Operation completed successfully.\r
423 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
424**/\r
425EFI_STATUS\r
426EFIAPI\r
427Tpm2PcrAllocate (\r
428 IN TPMI_RH_PLATFORM AuthHandle,\r
429 IN TPMS_AUTH_COMMAND *AuthSession,\r
430 IN TPML_PCR_SELECTION *PcrAllocation,\r
431 OUT TPMI_YES_NO *AllocationSuccess,\r
432 OUT UINT32 *MaxPCR,\r
433 OUT UINT32 *SizeNeeded,\r
434 OUT UINT32 *SizeAvailable\r
435 )\r
436{\r
437 EFI_STATUS Status;\r
438 TPM2_PCR_ALLOCATE_COMMAND Cmd;\r
439 TPM2_PCR_ALLOCATE_RESPONSE Res;\r
440 UINT32 CmdSize;\r
441 UINT32 RespSize;\r
442 UINT8 *Buffer;\r
443 UINT32 SessionInfoSize;\r
444 UINT8 *ResultBuf;\r
445 UINT32 ResultBufSize;\r
446 UINTN Index;\r
447\r
448 //\r
449 // Construct command\r
450 //\r
451 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
452 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
453 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);\r
454 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
455\r
456 //\r
457 // Add in Auth session\r
458 //\r
459 Buffer = (UINT8 *)&Cmd.AuthSession;\r
460\r
461 // sessionInfoSize\r
462 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
463 Buffer += SessionInfoSize;\r
464 Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
465\r
466 // Count\r
467 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));\r
468 Buffer += sizeof(UINT32);\r
469 for (Index = 0; Index < PcrAllocation->count; Index++) {\r
470 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));\r
471 Buffer += sizeof(UINT16);\r
472 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
58dbfc3c 473 Buffer++;\r
c1d93242
JY
474 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
475 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
476 }\r
477\r
478 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
479 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
480\r
481 ResultBuf = (UINT8 *) &Res;\r
482 ResultBufSize = sizeof(Res);\r
483\r
484 //\r
485 // Call the TPM\r
486 //\r
487 Status = Tpm2SubmitCommand (\r
488 CmdSize, \r
489 (UINT8 *)&Cmd, \r
490 &ResultBufSize,\r
491 ResultBuf\r
492 );\r
7ae130da
JY
493 if (EFI_ERROR(Status)) {\r
494 goto Done;\r
495 }\r
c1d93242
JY
496\r
497 if (ResultBufSize > sizeof(Res)) {\r
498 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
7ae130da
JY
499 Status = EFI_BUFFER_TOO_SMALL;\r
500 goto Done;\r
c1d93242
JY
501 }\r
502\r
503 //\r
504 // Validate response headers\r
505 //\r
506 RespSize = SwapBytes32(Res.Header.paramSize);\r
507 if (RespSize > sizeof(Res)) {\r
508 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
7ae130da
JY
509 Status = EFI_BUFFER_TOO_SMALL;\r
510 goto Done;\r
c1d93242
JY
511 }\r
512\r
513 //\r
514 // Fail if command failed\r
515 //\r
516 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
517 DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
7ae130da
JY
518 Status = EFI_DEVICE_ERROR;\r
519 goto Done;\r
c1d93242
JY
520 }\r
521\r
522 //\r
523 // Return the response\r
524 //\r
525 *AllocationSuccess = Res.AllocationSuccess;\r
526 *MaxPCR = SwapBytes32(Res.MaxPCR);\r
527 *SizeNeeded = SwapBytes32(Res.SizeNeeded);\r
528 *SizeAvailable = SwapBytes32(Res.SizeAvailable);\r
529\r
7ae130da
JY
530Done:\r
531 //\r
532 // Clear AuthSession Content\r
533 //\r
534 ZeroMem (&Cmd, sizeof(Cmd));\r
535 ZeroMem (&Res, sizeof(Res));\r
536 return Status;\r
c1d93242 537}\r