]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Integrity.c
SecurityPkg: Apply uncrustify changes
[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
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
141 Buffer += DigestSize;\r
142 }\r
143\r
144 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
c411b485 145 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 146\r
c411b485
MK
147 ResultBufSize = sizeof (Res);\r
148 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
149 if (EFI_ERROR (Status)) {\r
c1d93242
JY
150 return Status;\r
151 }\r
152\r
c411b485 153 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 154 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
c1d93242
JY
155 return EFI_BUFFER_TOO_SMALL;\r
156 }\r
157\r
158 //\r
159 // Validate response headers\r
160 //\r
c411b485
MK
161 RespSize = SwapBytes32 (Res.Header.paramSize);\r
162 if (RespSize > sizeof (Res)) {\r
e905fbb0 163 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response size too large! %d\r\n", RespSize));\r
c1d93242
JY
164 return EFI_BUFFER_TOO_SMALL;\r
165 }\r
166\r
167 //\r
168 // Fail if command failed\r
169 //\r
c411b485
MK
170 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
171 DEBUG ((DEBUG_ERROR, "Tpm2PcrExtend: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
c1d93242
JY
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
c411b485
MK
202 IN TPMI_DH_PCR PcrHandle,\r
203 IN TPM2B_EVENT *EventData,\r
204 OUT TPML_DIGEST_VALUES *Digests\r
c1d93242
JY
205 )\r
206{\r
c411b485
MK
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
c1d93242
JY
221\r
222 //\r
223 // Add in Auth session\r
224 //\r
225 Buffer = (UINT8 *)&Cmd.AuthSessionPcr;\r
226\r
227 // sessionInfoSize\r
c411b485
MK
228 SessionInfoSize = CopyAuthSessionCommand (NULL, Buffer);\r
229 Buffer += SessionInfoSize;\r
230 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);\r
c1d93242
JY
231\r
232 // Event\r
c411b485
MK
233 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (EventData->size));\r
234 Buffer += sizeof (UINT16);\r
c1d93242
JY
235\r
236 CopyMem (Buffer, EventData->buffer, EventData->size);\r
237 Buffer += EventData->size;\r
b3548d32 238\r
c1d93242 239 CmdSize = (UINT32)((UINTN)Buffer - (UINTN)&Cmd);\r
c411b485 240 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 241\r
c411b485
MK
242 ResultBufSize = sizeof (Res);\r
243 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);\r
244 if (EFI_ERROR (Status)) {\r
c1d93242
JY
245 return Status;\r
246 }\r
247\r
c411b485 248 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 249 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
c1d93242
JY
250 return EFI_BUFFER_TOO_SMALL;\r
251 }\r
252\r
253 //\r
254 // Validate response headers\r
255 //\r
c411b485
MK
256 RespSize = SwapBytes32 (Res.Header.paramSize);\r
257 if (RespSize > sizeof (Res)) {\r
e905fbb0 258 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response size too large! %d\r\n", RespSize));\r
c1d93242
JY
259 return EFI_BUFFER_TOO_SMALL;\r
260 }\r
261\r
262 //\r
263 // Fail if command failed\r
264 //\r
c411b485
MK
265 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
266 DEBUG ((DEBUG_ERROR, "Tpm2PcrEvent: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
c1d93242
JY
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
c411b485 281 Buffer += sizeof (UINT32);\r
c1d93242
JY
282 for (Index = 0; Index < Digests->count; Index++) {\r
283 Digests->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));\r
c411b485
MK
284 Buffer += sizeof (UINT16);\r
285 DigestSize = GetHashSizeFromAlgo (Digests->digests[Index].hashAlg);\r
c1d93242 286 if (DigestSize == 0) {\r
e905fbb0 287 DEBUG ((DEBUG_ERROR, "Unknown hash algorithm %d\r\n", Digests->digests[Index].hashAlg));\r
c1d93242
JY
288 return EFI_DEVICE_ERROR;\r
289 }\r
c411b485
MK
290\r
291 CopyMem (\r
c1d93242
JY
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
b3548d32 309\r
c1d93242
JY
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
c411b485
MK
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
c1d93242
JY
320 )\r
321{\r
c411b485
MK
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
c1d93242
JY
330\r
331 //\r
332 // Construct command\r
333 //\r
c411b485
MK
334 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
335 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Read);\r
b3548d32 336\r
c411b485 337 SendBuffer.PcrSelectionIn.count = SwapBytes32 (PcrSelectionIn->count);\r
c1d93242 338 for (Index = 0; Index < PcrSelectionIn->count; Index++) {\r
c411b485 339 SendBuffer.PcrSelectionIn.pcrSelections[Index].hash = SwapBytes16 (PcrSelectionIn->pcrSelections[Index].hash);\r
c1d93242
JY
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
c411b485 344 SendBufferSize = sizeof (SendBuffer.Header) + sizeof (SendBuffer.PcrSelectionIn.count) + sizeof (SendBuffer.PcrSelectionIn.pcrSelections[0]) * PcrSelectionIn->count;\r
c1d93242
JY
345 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
346\r
347 //\r
348 // send Tpm command\r
349 //\r
350 RecvBufferSize = sizeof (RecvBuffer);\r
c411b485 351 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
c1d93242
JY
352 if (EFI_ERROR (Status)) {\r
353 return Status;\r
354 }\r
355\r
356 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
e905fbb0 357 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
358 return EFI_DEVICE_ERROR;\r
359 }\r
c411b485
MK
360\r
361 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
362 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
c1d93242
JY
363 return EFI_NOT_FOUND;\r
364 }\r
365\r
366 //\r
367 // Return the response\r
368 //\r
369\r
370 //\r
371 // PcrUpdateCounter\r
372 //\r
c411b485 373 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter)) {\r
e905fbb0 374 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
375 return EFI_DEVICE_ERROR;\r
376 }\r
c411b485
MK
377\r
378 *PcrUpdateCounter = SwapBytes32 (RecvBuffer.PcrUpdateCounter);\r
c1d93242
JY
379\r
380 //\r
381 // PcrSelectionOut\r
382 //\r
c411b485 383 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count)) {\r
e905fbb0 384 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
385 return EFI_DEVICE_ERROR;\r
386 }\r
c411b485
MK
387\r
388 PcrSelectionOut->count = SwapBytes32 (RecvBuffer.PcrSelectionOut.count);\r
dd577319
ZC
389 if (PcrSelectionOut->count > HASH_COUNT) {\r
390 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrSelectionOut->count error %x\n", PcrSelectionOut->count));\r
391 return EFI_DEVICE_ERROR;\r
392 }\r
393\r
c411b485 394 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count) {\r
e905fbb0 395 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
396 return EFI_DEVICE_ERROR;\r
397 }\r
c411b485 398\r
c1d93242 399 for (Index = 0; Index < PcrSelectionOut->count; Index++) {\r
c411b485 400 PcrSelectionOut->pcrSelections[Index].hash = SwapBytes16 (RecvBuffer.PcrSelectionOut.pcrSelections[Index].hash);\r
c1d93242 401 PcrSelectionOut->pcrSelections[Index].sizeofSelect = RecvBuffer.PcrSelectionOut.pcrSelections[Index].sizeofSelect;\r
dd577319
ZC
402 if (PcrSelectionOut->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
403 return EFI_DEVICE_ERROR;\r
404 }\r
c411b485 405\r
c1d93242
JY
406 CopyMem (&PcrSelectionOut->pcrSelections[Index].pcrSelect, &RecvBuffer.PcrSelectionOut.pcrSelections[Index].pcrSelect, PcrSelectionOut->pcrSelections[Index].sizeofSelect);\r
407 }\r
408\r
409 //\r
410 // PcrValues\r
411 //\r
c411b485
MK
412 PcrValuesOut = (TPML_DIGEST *)((UINT8 *)&RecvBuffer + sizeof (TPM2_RESPONSE_HEADER) + sizeof (RecvBuffer.PcrUpdateCounter) + sizeof (RecvBuffer.PcrSelectionOut.count) + sizeof (RecvBuffer.PcrSelectionOut.pcrSelections[0]) * PcrSelectionOut->count);\r
413 PcrValues->count = SwapBytes32 (PcrValuesOut->count);\r
dd577319
ZC
414 //\r
415 // The number of digests in list is not greater than 8 per TPML_DIGEST definition\r
416 //\r
417 if (PcrValues->count > 8) {\r
418 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - PcrValues->count error %x\n", PcrValues->count));\r
419 return EFI_DEVICE_ERROR;\r
420 }\r
c411b485 421\r
c1d93242
JY
422 Digests = PcrValuesOut->digests;\r
423 for (Index = 0; Index < PcrValues->count; Index++) {\r
c411b485
MK
424 PcrValues->digests[Index].size = SwapBytes16 (Digests->size);\r
425 if (PcrValues->digests[Index].size > sizeof (TPMU_HA)) {\r
dd577319
ZC
426 DEBUG ((DEBUG_ERROR, "Tpm2PcrRead - Digest.size error %x\n", PcrValues->digests[Index].size));\r
427 return EFI_DEVICE_ERROR;\r
428 }\r
c411b485 429\r
c1d93242 430 CopyMem (&PcrValues->digests[Index].buffer, &Digests->buffer, PcrValues->digests[Index].size);\r
c411b485 431 Digests = (TPM2B_DIGEST *)((UINT8 *)Digests + sizeof (Digests->size) + PcrValues->digests[Index].size);\r
c1d93242
JY
432 }\r
433\r
434 return EFI_SUCCESS;\r
435}\r
436\r
437/**\r
438 This command is used to set the desired PCR allocation of PCR and algorithms.\r
439\r
440 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}\r
441 @param[in] AuthSession Auth Session context\r
442 @param[in] PcrAllocation The requested allocation\r
443 @param[out] AllocationSuccess YES if the allocation succeeded\r
444 @param[out] MaxPCR maximum number of PCR that may be in a bank\r
445 @param[out] SizeNeeded number of octets required to satisfy the request\r
446 @param[out] SizeAvailable Number of octets available. Computed before the allocation\r
b3548d32 447\r
c1d93242
JY
448 @retval EFI_SUCCESS Operation completed successfully.\r
449 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
450**/\r
451EFI_STATUS\r
452EFIAPI\r
453Tpm2PcrAllocate (\r
c411b485
MK
454 IN TPMI_RH_PLATFORM AuthHandle,\r
455 IN TPMS_AUTH_COMMAND *AuthSession,\r
456 IN TPML_PCR_SELECTION *PcrAllocation,\r
457 OUT TPMI_YES_NO *AllocationSuccess,\r
458 OUT UINT32 *MaxPCR,\r
459 OUT UINT32 *SizeNeeded,\r
460 OUT UINT32 *SizeAvailable\r
c1d93242
JY
461 )\r
462{\r
463 EFI_STATUS Status;\r
464 TPM2_PCR_ALLOCATE_COMMAND Cmd;\r
465 TPM2_PCR_ALLOCATE_RESPONSE Res;\r
466 UINT32 CmdSize;\r
467 UINT32 RespSize;\r
468 UINT8 *Buffer;\r
469 UINT32 SessionInfoSize;\r
470 UINT8 *ResultBuf;\r
471 UINT32 ResultBufSize;\r
472 UINTN Index;\r
473\r
474 //\r
475 // Construct command\r
476 //\r
c411b485
MK
477 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);\r
478 Cmd.Header.paramSize = SwapBytes32 (sizeof (Cmd));\r
479 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_PCR_Allocate);\r
480 Cmd.AuthHandle = SwapBytes32 (AuthHandle);\r
c1d93242
JY
481\r
482 //\r
483 // Add in Auth session\r
484 //\r
485 Buffer = (UINT8 *)&Cmd.AuthSession;\r
486\r
487 // sessionInfoSize\r
c411b485
MK
488 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);\r
489 Buffer += SessionInfoSize;\r
490 Cmd.AuthSessionSize = SwapBytes32 (SessionInfoSize);\r
c1d93242
JY
491\r
492 // Count\r
c411b485
MK
493 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (PcrAllocation->count));\r
494 Buffer += sizeof (UINT32);\r
c1d93242 495 for (Index = 0; Index < PcrAllocation->count; Index++) {\r
c411b485
MK
496 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (PcrAllocation->pcrSelections[Index].hash));\r
497 Buffer += sizeof (UINT16);\r
c1d93242 498 *(UINT8 *)Buffer = PcrAllocation->pcrSelections[Index].sizeofSelect;\r
58dbfc3c 499 Buffer++;\r
c1d93242
JY
500 CopyMem (Buffer, PcrAllocation->pcrSelections[Index].pcrSelect, PcrAllocation->pcrSelections[Index].sizeofSelect);\r
501 Buffer += PcrAllocation->pcrSelections[Index].sizeofSelect;\r
502 }\r
503\r
c411b485
MK
504 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);\r
505 Cmd.Header.paramSize = SwapBytes32 (CmdSize);\r
c1d93242 506\r
c411b485
MK
507 ResultBuf = (UINT8 *)&Res;\r
508 ResultBufSize = sizeof (Res);\r
c1d93242
JY
509\r
510 //\r
511 // Call the TPM\r
512 //\r
513 Status = Tpm2SubmitCommand (\r
b3548d32
LG
514 CmdSize,\r
515 (UINT8 *)&Cmd,\r
c1d93242
JY
516 &ResultBufSize,\r
517 ResultBuf\r
518 );\r
c411b485 519 if (EFI_ERROR (Status)) {\r
7ae130da
JY
520 goto Done;\r
521 }\r
c1d93242 522\r
c411b485 523 if (ResultBufSize > sizeof (Res)) {\r
e905fbb0 524 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Failed ExecuteCommand: Buffer Too Small\r\n"));\r
7ae130da
JY
525 Status = EFI_BUFFER_TOO_SMALL;\r
526 goto Done;\r
c1d93242
JY
527 }\r
528\r
529 //\r
530 // Validate response headers\r
531 //\r
c411b485
MK
532 RespSize = SwapBytes32 (Res.Header.paramSize);\r
533 if (RespSize > sizeof (Res)) {\r
e905fbb0 534 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response size too large! %d\r\n", RespSize));\r
7ae130da
JY
535 Status = EFI_BUFFER_TOO_SMALL;\r
536 goto Done;\r
c1d93242
JY
537 }\r
538\r
539 //\r
540 // Fail if command failed\r
541 //\r
c411b485
MK
542 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {\r
543 DEBUG ((DEBUG_ERROR, "Tpm2PcrAllocate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));\r
7ae130da
JY
544 Status = EFI_DEVICE_ERROR;\r
545 goto Done;\r
c1d93242
JY
546 }\r
547\r
548 //\r
549 // Return the response\r
550 //\r
551 *AllocationSuccess = Res.AllocationSuccess;\r
c411b485
MK
552 *MaxPCR = SwapBytes32 (Res.MaxPCR);\r
553 *SizeNeeded = SwapBytes32 (Res.SizeNeeded);\r
554 *SizeAvailable = SwapBytes32 (Res.SizeAvailable);\r
c1d93242 555\r
7ae130da
JY
556Done:\r
557 //\r
558 // Clear AuthSession Content\r
559 //\r
c411b485
MK
560 ZeroMem (&Cmd, sizeof (Cmd));\r
561 ZeroMem (&Res, sizeof (Res));\r
7ae130da 562 return Status;\r
c1d93242 563}\r
f9c9a140
JY
564\r
565/**\r
566 Alloc PCR data.\r
567\r
568 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.\r
569 @param[in] SupportedPCRBanks Supported PCR banks\r
570 @param[in] PCRBanks PCR banks\r
b3548d32 571\r
f9c9a140
JY
572 @retval EFI_SUCCESS Operation completed successfully.\r
573**/\r
574EFI_STATUS\r
575EFIAPI\r
576Tpm2PcrAllocateBanks (\r
c411b485
MK
577 IN TPM2B_AUTH *PlatformAuth OPTIONAL,\r
578 IN UINT32 SupportedPCRBanks,\r
579 IN UINT32 PCRBanks\r
f9c9a140
JY
580 )\r
581{\r
c411b485
MK
582 EFI_STATUS Status;\r
583 TPMS_AUTH_COMMAND *AuthSession;\r
584 TPMS_AUTH_COMMAND LocalAuthSession;\r
585 TPML_PCR_SELECTION PcrAllocation;\r
586 TPMI_YES_NO AllocationSuccess;\r
587 UINT32 MaxPCR;\r
588 UINT32 SizeNeeded;\r
589 UINT32 SizeAvailable;\r
f9c9a140
JY
590\r
591 if (PlatformAuth == NULL) {\r
592 AuthSession = NULL;\r
593 } else {\r
594 AuthSession = &LocalAuthSession;\r
c411b485 595 ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));\r
f9c9a140 596 LocalAuthSession.sessionHandle = TPM_RS_PW;\r
c411b485 597 LocalAuthSession.hmac.size = PlatformAuth->size;\r
f9c9a140
JY
598 CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);\r
599 }\r
600\r
601 //\r
602 // Fill input\r
603 //\r
c411b485 604 ZeroMem (&PcrAllocation, sizeof (PcrAllocation));\r
f9c9a140 605 if ((HASH_ALG_SHA1 & SupportedPCRBanks) != 0) {\r
c411b485 606 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA1;\r
f9c9a140
JY
607 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
608 if ((HASH_ALG_SHA1 & PCRBanks) != 0) {\r
609 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
610 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
611 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
612 } else {\r
613 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
614 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
615 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
616 }\r
c411b485 617\r
f9c9a140
JY
618 PcrAllocation.count++;\r
619 }\r
c411b485 620\r
f9c9a140 621 if ((HASH_ALG_SHA256 & SupportedPCRBanks) != 0) {\r
c411b485 622 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA256;\r
f9c9a140
JY
623 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
624 if ((HASH_ALG_SHA256 & PCRBanks) != 0) {\r
625 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
626 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
627 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
628 } else {\r
629 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
630 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
631 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
632 }\r
c411b485 633\r
f9c9a140
JY
634 PcrAllocation.count++;\r
635 }\r
c411b485 636\r
f9c9a140 637 if ((HASH_ALG_SHA384 & SupportedPCRBanks) != 0) {\r
c411b485 638 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA384;\r
f9c9a140
JY
639 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
640 if ((HASH_ALG_SHA384 & PCRBanks) != 0) {\r
641 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
642 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
643 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
644 } else {\r
645 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
646 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
647 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
648 }\r
c411b485 649\r
f9c9a140
JY
650 PcrAllocation.count++;\r
651 }\r
c411b485 652\r
f9c9a140 653 if ((HASH_ALG_SHA512 & SupportedPCRBanks) != 0) {\r
c411b485 654 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SHA512;\r
f9c9a140
JY
655 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
656 if ((HASH_ALG_SHA512 & 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
c411b485 665\r
f9c9a140
JY
666 PcrAllocation.count++;\r
667 }\r
c411b485 668\r
f9c9a140 669 if ((HASH_ALG_SM3_256 & SupportedPCRBanks) != 0) {\r
c411b485 670 PcrAllocation.pcrSelections[PcrAllocation.count].hash = TPM_ALG_SM3_256;\r
f9c9a140
JY
671 PcrAllocation.pcrSelections[PcrAllocation.count].sizeofSelect = PCR_SELECT_MAX;\r
672 if ((HASH_ALG_SM3_256 & PCRBanks) != 0) {\r
673 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0xFF;\r
674 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0xFF;\r
675 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0xFF;\r
676 } else {\r
677 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[0] = 0x00;\r
678 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[1] = 0x00;\r
679 PcrAllocation.pcrSelections[PcrAllocation.count].pcrSelect[2] = 0x00;\r
680 }\r
c411b485 681\r
f9c9a140
JY
682 PcrAllocation.count++;\r
683 }\r
c411b485 684\r
f9c9a140
JY
685 Status = Tpm2PcrAllocate (\r
686 TPM_RH_PLATFORM,\r
687 AuthSession,\r
688 &PcrAllocation,\r
689 &AllocationSuccess,\r
690 &MaxPCR,\r
691 &SizeNeeded,\r
692 &SizeAvailable\r
693 );\r
e905fbb0 694 DEBUG ((DEBUG_INFO, "Tpm2PcrAllocateBanks call Tpm2PcrAllocate - %r\n", Status));\r
f9c9a140
JY
695 if (EFI_ERROR (Status)) {\r
696 goto Done;\r
697 }\r
698\r
e905fbb0
MK
699 DEBUG ((DEBUG_INFO, "AllocationSuccess - %02x\n", AllocationSuccess));\r
700 DEBUG ((DEBUG_INFO, "MaxPCR - %08x\n", MaxPCR));\r
701 DEBUG ((DEBUG_INFO, "SizeNeeded - %08x\n", SizeNeeded));\r
702 DEBUG ((DEBUG_INFO, "SizeAvailable - %08x\n", SizeAvailable));\r
f9c9a140
JY
703\r
704Done:\r
c411b485 705 ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));\r
f9c9a140 706 return Status;\r
b3548d32 707}\r