]>
Commit | Line | Data |
---|---|---|
c1d93242 JY |
1 | /** @file\r |
2 | Implement TPM2 Integrity related command.\r | |
3 | \r | |
8ed85689 | 4 | Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>\r |
289b714b | 5 | SPDX-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 | |
18 | typedef 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 | |
26 | typedef 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 | |
32 | typedef 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 | |
40 | typedef 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 | |
47 | typedef 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 | |
52 | typedef 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 | |
59 | typedef 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 | |
67 | typedef 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 | |
90 | EFI_STATUS\r | |
91 | EFIAPI\r | |
92 | Tpm2PcrExtend (\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 | |
221 | EFI_STATUS\r | |
222 | EFIAPI\r | |
223 | Tpm2PcrEvent (\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 | |
335 | EFI_STATUS\r | |
336 | EFIAPI\r | |
337 | Tpm2PcrRead (\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 | |
473 | EFI_STATUS\r | |
474 | EFIAPI\r | |
475 | Tpm2PcrAllocate (\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 |
578 | Done:\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 | |
596 | EFI_STATUS\r | |
597 | EFIAPI\r | |
598 | Tpm2PcrAllocateBanks (\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 |
726 | Done:\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 | |
741 | EFI_STATUS\r | |
742 | EFIAPI\r | |
743 | Tpm2PcrReadForActiveBank (\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 |