]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
SecurityPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Integrity.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 Integrity related command.\r
3\r
dd577319 4Copyright (c) 2013 - 2018, 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
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
24} TPM2_PCR_EXTEND_COMMAND;\r
25\r
26typedef struct {\r
27 TPM2_RESPONSE_HEADER Header;\r
28 UINT32 ParameterSize;\r
29 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
30} TPM2_PCR_EXTEND_RESPONSE;\r
31\r
32typedef struct {\r
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
38} TPM2_PCR_EVENT_COMMAND;\r
39\r
40typedef struct {\r
41 TPM2_RESPONSE_HEADER Header;\r
42 UINT32 ParameterSize;\r
43 TPML_DIGEST_VALUES Digests;\r
44 TPMS_AUTH_RESPONSE AuthSessionPcr;\r
45} TPM2_PCR_EVENT_RESPONSE;\r
46\r
47typedef struct {\r
48 TPM2_COMMAND_HEADER Header;\r
49 TPML_PCR_SELECTION PcrSelectionIn;\r
50} TPM2_PCR_READ_COMMAND;\r
51\r
52typedef struct {\r
53 TPM2_RESPONSE_HEADER Header;\r
54 UINT32 PcrUpdateCounter;\r
55 TPML_PCR_SELECTION PcrSelectionOut;\r
56 TPML_DIGEST PcrValues;\r
57} TPM2_PCR_READ_RESPONSE;\r
58\r
59typedef struct {\r
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
65} TPM2_PCR_ALLOCATE_COMMAND;\r
66\r
67typedef struct {\r
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
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
93 IN TPMI_DH_PCR PcrHandle,\r
94 IN TPML_DIGEST_VALUES *Digests\r
95 )\r
96{\r
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
107\r
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
111\r
112\r
113 //\r
114 // Add in Auth session\r
115 //\r
116 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
b3548d32 117\r
c1d93242
JY
118 // sessionInfoSize\r
119 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
120 Buffer += SessionInfoSize;\r
121 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
b3548d32 122\r
c1d93242
JY
123 //Digest Count\r
124 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Digests->count));\r
125 Buffer += sizeof(UINT32);\r
b3548d32 126\r
c1d93242
JY
127 //Digest\r
128 for (Index = 0; Index < Digests->count; Index++) {\r
129 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(Digests->digests[Index].hashAlg));\r
130 Buffer += sizeof(UINT16);\r
131 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
132 if (DigestSize == 0) {\r
133 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
134 return EFI_DEVICE_ERROR;\r
135 }\r
136 CopyMem(\r
137 Buffer,\r
138 &Digests->digests[Index].digest,\r
139 DigestSize\r
140 );\r
141 Buffer += DigestSize;\r
142 }\r
143\r
144 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
145 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
146\r
147 ResultBufSize = sizeof(Res);\r
148 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
149 if (EFI_ERROR(Status)) {\r
150 return Status;\r
151 }\r
152\r
153 if (ResultBufSize > sizeof(Res)) {\r
154 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
155 return EFI_BUFFER_TOO_SMALL;\r
156 }\r
157\r
158 //\r
159 // Validate response headers\r
160 //\r
161 RespSize = SwapBytes32(Res.Header.paramSize);\r
162 if (RespSize > sizeof(Res)) {\r
163 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
164 return EFI_BUFFER_TOO_SMALL;\r
165 }\r
166\r
167 //\r
168 // Fail if command failed\r
169 //\r
170 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
171 DEBUG ((EFI_D_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
172 return EFI_DEVICE_ERROR;\r
173 }\r
174\r
175 //\r
176 // Unmarshal the response\r
177 //\r
178\r
179 // None\r
180\r
181 return EFI_SUCCESS;\r
182}\r
183\r
184/**\r
185 This command is used to cause an update to the indicated PCR.\r
186 The data in eventData is hashed using the hash algorithm associated with each bank in which the\r
187 indicated PCR has been allocated. After the data is hashed, the digests list is returned. If the pcrHandle\r
188 references an implemented PCR and not TPM_ALG_NULL, digests list is processed as in\r
189 TPM2_PCR_Extend().\r
190 A TPM shall support an Event.size of zero through 1,024 inclusive.\r
191\r
192 @param[in] PcrHandle Handle of the PCR\r
193 @param[in] EventData Event data in sized buffer\r
194 @param[out] Digests List of digest\r
195\r
196 @retval EFI_SUCCESS Operation completed successfully.\r
197 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
198**/\r
199EFI_STATUS\r
200EFIAPI\r
201Tpm2PcrEvent (\r
202 IN TPMI_DH_PCR PcrHandle,\r
203 IN TPM2B_EVENT *EventData,\r
204 OUT TPML_DIGEST_VALUES *Digests\r
205 )\r
206{\r
207 EFI_STATUS Status;\r
208 TPM2_PCR_EVENT_COMMAND Cmd;\r
209 TPM2_PCR_EVENT_RESPONSE Res;\r
210 UINT32 CmdSize;\r
211 UINT32 RespSize;\r
212 UINT32 ResultBufSize;\r
213 UINT8 *Buffer;\r
214 UINTN Index;\r
215 UINT32 SessionInfoSize;\r
216 UINT16 DigestSize;\r
217\r
218 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
219 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Event);\r
220 Cmd.PcrHandle = SwapBytes32(PcrHandle);\r
221\r
222 //\r
223 // Add in Auth session\r
224 //\r
225 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
226\r
227 // sessionInfoSize\r
228 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
229 Buffer += SessionInfoSize;\r
230 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);\r
231\r
232 // Event\r
233 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(EventData->size));\r
234 Buffer += sizeof(UINT16);\r
235\r
236 CopyMem (Buffer, EventData->buffer, EventData->size);\r
237 Buffer += EventData->size;\r
b3548d32 238\r
c1d93242
JY
239 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
240 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
241\r
242 ResultBufSize = sizeof(Res);\r
243 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
244 if (EFI_ERROR(Status)) {\r
245 return Status;\r
246 }\r
247\r
248 if (ResultBufSize > sizeof(Res)) {\r
249 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
250 return EFI_BUFFER_TOO_SMALL;\r
251 }\r
252\r
253 //\r
254 // Validate response headers\r
255 //\r
256 RespSize = SwapBytes32(Res.Header.paramSize);\r
257 if (RespSize > sizeof(Res)) {\r
258 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
259 return EFI_BUFFER_TOO_SMALL;\r
260 }\r
261\r
262 //\r
263 // Fail if command failed\r
264 //\r
265 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
266 DEBUG ((EFI_D_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
267 return EFI_DEVICE_ERROR;\r
268 }\r
269\r
270 //\r
271 // Unmarshal the response\r
272 //\r
273 Buffer = (UINT8 *)&Res.Digests;\r
274\r
275 Digests->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));\r
dd577319
ZC
276 if (Digests->count > HASH_COUNT) {\r
277 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent - Digests->count error %x\n", Digests->count));\r
278 return EFI_DEVICE_ERROR;\r
279 }\r
280\r
c1d93242
JY
281 Buffer += sizeof(UINT32);\r
282 for (Index = 0; Index < Digests->count; Index++) {\r
283 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
284 Buffer += sizeof(UINT16);\r
285 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
286 if (DigestSize == 0) {\r
287 DEBUG ((EFI_D_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
288 return EFI_DEVICE_ERROR;\r
289 }\r
290 CopyMem(\r
291 &Digests->digests[Index].digest,\r
292 Buffer,\r
293 DigestSize\r
294 );\r
295 Buffer += DigestSize;\r
296 }\r
297\r
298 return EFI_SUCCESS;\r
299}\r
300\r
301/**\r
302 This command returns the values of all PCR specified in pcrSelect.\r
303\r
304 @param[in] PcrSelectionIn The selection of PCR to read.\r
305 @param[out] PcrUpdateCounter The current value of the PCR update counter.\r
306 @param[out] PcrSelectionOut The PCR in the returned list.\r
307 @param[out] PcrValues The contents of the PCR indicated in pcrSelect.\r
b3548d32 308\r
c1d93242
JY
309 @retval EFI_SUCCESS Operation completed successfully.\r
310 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
311**/\r
312EFI_STATUS\r
313EFIAPI\r
314Tpm2PcrRead (\r
315 IN TPML_PCR_SELECTION *PcrSelectionIn,\r
316 OUT UINT32 *PcrUpdateCounter,\r
317 OUT TPML_PCR_SELECTION *PcrSelectionOut,\r
318 OUT TPML_DIGEST *PcrValues\r
319 )\r
320{\r
321 EFI_STATUS Status;\r
322 TPM2_PCR_READ_COMMAND SendBuffer;\r
323 TPM2_PCR_READ_RESPONSE RecvBuffer;\r
324 UINT32 SendBufferSize;\r
325 UINT32 RecvBufferSize;\r
326 UINTN Index;\r
327 TPML_DIGEST *PcrValuesOut;\r
328 TPM2B_DIGEST *Digests;\r
329\r
330 //\r
331 // Construct command\r
332 //\r
333 SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);\r
334 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PCR_Read);\r
b3548d32 335\r
c1d93242
JY
336 SendBuffer.PcrSelectionIn.count = SwapBytes32(PcrSelectionIn->count);\r
337 for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
338 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16(PcrSelectionIn->pcrSelections[Index].hash);\r
339 SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect = PcrSelectionIn->pcrSelections[Index].sizeofSelect;\r
340 CopyMem (&SendBuffer.PcrSelectionIn.pcrSelections[Index].pcrSelect, &PcrSelectionIn->pcrSelections[Index].pcrSelect, SendBuffer.PcrSelectionIn.pcrSelections[Index].sizeofSelect);\r
341 }\r
342\r
343 SendBufferSize = sizeof(SendBuffer.Header) + sizeof(SendBuffer.PcrSelectionIn.count) + sizeof(SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
344 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
345\r
346 //\r
347 // send Tpm command\r
348 //\r
349 RecvBufferSize = sizeof (RecvBuffer);\r
350 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
351 if (EFI_ERROR (Status)) {\r
352 return Status;\r
353 }\r
354\r
355 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
356 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
357 return EFI_DEVICE_ERROR;\r
358 }\r
359 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
360 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));\r
361 return EFI_NOT_FOUND;\r
362 }\r
363\r
364 //\r
365 // Return the response\r
366 //\r
367\r
368 //\r
369 // PcrUpdateCounter\r
370 //\r
371 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter)) {\r
372 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
373 return EFI_DEVICE_ERROR;\r
374 }\r
375 *PcrUpdateCounter = SwapBytes32(RecvBuffer.PcrUpdateCounter);\r
376\r
377 //\r
378 // PcrSelectionOut\r
379 //\r
380 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count)) {\r
381 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
382 return EFI_DEVICE_ERROR;\r
383 }\r
384 PcrSelectionOut->count = SwapBytes32(RecvBuffer.PcrSelectionOut.count);\r
dd577319
ZC
385 if (PcrSelectionOut->count > HASH_COUNT) {\r
386 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));\r
387 return EFI_DEVICE_ERROR;\r
388 }\r
389\r
c1d93242
JY
390 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
391 DEBUG ((EFI_D_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
392 return EFI_DEVICE_ERROR;\r
393 }\r
394 for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
395 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16(RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
396 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
dd577319
ZC
397 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
398 return EFI_DEVICE_ERROR;\r
399 }\r
c1d93242
JY
400 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
401 }\r
402\r
403 //\r
404 // PcrValues\r
405 //\r
406 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof(RecvBuffer.PcrUpdateCounter) + sizeof(RecvBuffer.PcrSelectionOut.count) + sizeof(RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
407 PcrValues->count = SwapBytes32(PcrValuesOut->count);\r
dd577319
ZC
408 //\r
409 // The number of digests in list is not greater than 8 per TPML_DIGEST definition\r
410 //\r
411 if (PcrValues->count > 8) {\r
412 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));\r
413 return EFI_DEVICE_ERROR;\r
414 }\r
c1d93242
JY
415 Digests = PcrValuesOut->digests;\r
416 for (Index = 0; Index < PcrValues->count; Index++) {\r
417 PcrValues->digests[Index].size = SwapBytes16(Digests->size);\r
dd577319
ZC
418 if (PcrValues->digests[Index].size > sizeof(TPMU_HA)) {\r
419 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));\r
420 return EFI_DEVICE_ERROR;\r
421 }\r
c1d93242
JY
422 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
423 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof(Digests->size) + PcrValues->digests[Index].size);\r
424 }\r
425\r
426 return EFI_SUCCESS;\r
427}\r
428\r
429/**\r
430 This command is used to set the desired PCR allocation of PCR and algorithms.\r
431\r
432 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
433 @param[in] AuthSession Auth Session context\r
434 @param[in] PcrAllocation The requested allocation\r
435 @param[out] AllocationSuccess YES if the allocation succeeded\r
436 @param[out] MaxPCR maximum number of PCR that may be in a bank\r
437 @param[out] SizeNeeded number of octets required to satisfy the request\r
438 @param[out] SizeAvailable Number of octets available. Computed before the allocation\r
b3548d32 439\r
c1d93242
JY
440 @retval EFI_SUCCESS Operation completed successfully.\r
441 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
442**/\r
443EFI_STATUS\r
444EFIAPI\r
445Tpm2PcrAllocate (\r
446 IN TPMI_RH_PLATFORM AuthHandle,\r
447 IN TPMS_AUTH_COMMAND *AuthSession,\r
448 IN TPML_PCR_SELECTION *PcrAllocation,\r
449 OUT TPMI_YES_NO *AllocationSuccess,\r
450 OUT UINT32 *MaxPCR,\r
451 OUT UINT32 *SizeNeeded,\r
452 OUT UINT32 *SizeAvailable\r
453 )\r
454{\r
455 EFI_STATUS Status;\r
456 TPM2_PCR_ALLOCATE_COMMAND Cmd;\r
457 TPM2_PCR_ALLOCATE_RESPONSE Res;\r
458 UINT32 CmdSize;\r
459 UINT32 RespSize;\r
460 UINT8 *Buffer;\r
461 UINT32 SessionInfoSize;\r
462 UINT8 *ResultBuf;\r
463 UINT32 ResultBufSize;\r
464 UINTN Index;\r
465\r
466 //\r
467 // Construct command\r
468 //\r
469 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);\r
470 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));\r
471 Cmd.Header.commandCode = SwapBytes32(TPM_CC_PCR_Allocate);\r
472 Cmd.AuthHandle = SwapBytes32(AuthHandle);\r
473\r
474 //\r
475 // Add in Auth session\r
476 //\r
477 Buffer = (UINT8 *)&Cmd.AuthSession;\r
478\r
479 // sessionInfoSize\r
480 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
481 Buffer += SessionInfoSize;\r
482 Cmd.AuthSessionSize = SwapBytes32(SessionInfoSize);\r
483\r
484 // Count\r
485 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(PcrAllocation->count));\r
486 Buffer += sizeof(UINT32);\r
487 for (Index = 0; Index < PcrAllocation->count; Index++) {\r
488 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PcrAllocation->pcrSelections[Index].hash));\r
489 Buffer += sizeof(UINT16);\r
490 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
58dbfc3c 491 Buffer++;\r
c1d93242
JY
492 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
493 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
494 }\r
495\r
496 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
497 Cmd.Header.paramSize = SwapBytes32(CmdSize);\r
498\r
499 ResultBuf = (UINT8 *) &Res;\r
500 ResultBufSize = sizeof(Res);\r
501\r
502 //\r
503 // Call the TPM\r
504 //\r
505 Status = Tpm2SubmitCommand (\r
b3548d32
LG
506 CmdSize,\r
507 (UINT8 *)&Cmd,\r
c1d93242
JY
508 &ResultBufSize,\r
509 ResultBuf\r
510 );\r
7ae130da
JY
511 if (EFI_ERROR(Status)) {\r
512 goto Done;\r
513 }\r
c1d93242
JY
514\r
515 if (ResultBufSize > sizeof(Res)) {\r
516 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
7ae130da
JY
517 Status = EFI_BUFFER_TOO_SMALL;\r
518 goto Done;\r
c1d93242
JY
519 }\r
520\r
521 //\r
522 // Validate response headers\r
523 //\r
524 RespSize = SwapBytes32(Res.Header.paramSize);\r
525 if (RespSize > sizeof(Res)) {\r
526 DEBUG ((EFI_D_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
7ae130da
JY
527 Status = EFI_BUFFER_TOO_SMALL;\r
528 goto Done;\r
c1d93242
JY
529 }\r
530\r
531 //\r
532 // Fail if command failed\r
533 //\r
534 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
535 DEBUG((EFI_D_ERROR,"Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));\r
7ae130da
JY
536 Status = EFI_DEVICE_ERROR;\r
537 goto Done;\r
c1d93242
JY
538 }\r
539\r
540 //\r
541 // Return the response\r
542 //\r
543 *AllocationSuccess = Res.AllocationSuccess;\r
544 *MaxPCR = SwapBytes32(Res.MaxPCR);\r
545 *SizeNeeded = SwapBytes32(Res.SizeNeeded);\r
546 *SizeAvailable = SwapBytes32(Res.SizeAvailable);\r
547\r
7ae130da
JY
548Done:\r
549 //\r
550 // Clear AuthSession Content\r
551 //\r
552 ZeroMem (&Cmd, sizeof(Cmd));\r
553 ZeroMem (&Res, sizeof(Res));\r
554 return Status;\r
c1d93242 555}\r
f9c9a140
JY
556\r
557/**\r
558 Alloc PCR data.\r
559\r
560 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
561 @param[in] SupportedPCRBanks Supported PCR banks\r
562 @param[in] PCRBanks PCR banks\r
b3548d32 563\r
f9c9a140
JY
564 @retval EFI_SUCCESS Operation completed successfully.\r
565**/\r
566EFI_STATUS\r
567EFIAPI\r
568Tpm2PcrAllocateBanks (\r
569 IN TPM2B_AUTH *PlatformAuth, OPTIONAL\r
570 IN UINT32 SupportedPCRBanks,\r
571 IN UINT32 PCRBanks\r
572 )\r
573{\r
574 EFI_STATUS Status;\r
575 TPMS_AUTH_COMMAND *AuthSession;\r
576 TPMS_AUTH_COMMAND LocalAuthSession;\r
577 TPML_PCR_SELECTION PcrAllocation;\r
578 TPMI_YES_NO AllocationSuccess;\r
579 UINT32 MaxPCR;\r
580 UINT32 SizeNeeded;\r
581 UINT32 SizeAvailable;\r
582\r
583 if (PlatformAuth == NULL) {\r
584 AuthSession = NULL;\r
585 } else {\r
586 AuthSession = &LocalAuthSession;\r
587 ZeroMem (&LocalAuthSession, sizeof(LocalAuthSession));\r
588 LocalAuthSession.sessionHandle = TPM_RS_PW;\r
589 LocalAuthSession.hmac.size = PlatformAuth->size;\r
590 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
591 }\r
592\r
593 //\r
594 // Fill input\r
595 //\r
596 ZeroMem (&PcrAllocation, sizeof(PcrAllocation));\r
597 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
598 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;\r
599 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
600 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {\r
601 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
602 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
603 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
604 } else {\r
605 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
606 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
607 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
608 }\r
609 PcrAllocation.count++;\r
610 }\r
611 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
612 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;\r
613 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
614 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {\r
615 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
616 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
617 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
618 } else {\r
619 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
620 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
621 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
622 }\r
623 PcrAllocation.count++;\r
624 }\r
625 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
626 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;\r
627 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
628 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {\r
629 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
630 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
631 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
632 } else {\r
633 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
634 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
635 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
636 }\r
637 PcrAllocation.count++;\r
638 }\r
639 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
640 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;\r
641 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
642 if ((HASH_ALG_SHA512 & PCRBanks) != 0) {\r
643 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
644 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
645 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
646 } else {\r
647 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
648 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
649 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
650 }\r
651 PcrAllocation.count++;\r
652 }\r
653 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
654 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;\r
655 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
656 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
657 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
658 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
659 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
660 } else {\r
661 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
662 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
663 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
664 }\r
665 PcrAllocation.count++;\r
666 }\r
667 Status = Tpm2PcrAllocate (\r
668 TPM_RH_PLATFORM,\r
669 AuthSession,\r
670 &PcrAllocation,\r
671 &AllocationSuccess,\r
672 &MaxPCR,\r
673 &SizeNeeded,\r
674 &SizeAvailable\r
675 );\r
676 DEBUG ((EFI_D_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
677 if (EFI_ERROR (Status)) {\r
678 goto Done;\r
679 }\r
680\r
681 DEBUG ((EFI_D_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
682 DEBUG ((EFI_D_INFO, "MaxPCR - %08x\n", MaxPCR));\r
683 DEBUG ((EFI_D_INFO, "SizeNeeded - %08x\n", SizeNeeded));\r
684 DEBUG ((EFI_D_INFO, "SizeAvailable - %08x\n", SizeAvailable));\r
685\r
686Done:\r
687 ZeroMem(&LocalAuthSession.hmac, sizeof(LocalAuthSession.hmac));\r
688 return Status;\r
b3548d32 689}\r