]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / Library / Tpm2CommandLib / Tpm2Capability.c
CommitLineData
c1d93242
JY
1/** @file\r
2 Implement TPM2 Capability 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 TPM_CAP Capability;\r
21 UINT32 Property;\r
22 UINT32 PropertyCount;\r
c1d93242
JY
23} TPM2_GET_CAPABILITY_COMMAND;\r
24\r
25typedef struct {\r
c411b485
MK
26 TPM2_RESPONSE_HEADER Header;\r
27 TPMI_YES_NO MoreData;\r
28 TPMS_CAPABILITY_DATA CapabilityData;\r
c1d93242
JY
29} TPM2_GET_CAPABILITY_RESPONSE;\r
30\r
31typedef struct {\r
c411b485
MK
32 TPM2_COMMAND_HEADER Header;\r
33 TPMT_PUBLIC_PARMS Parameters;\r
c1d93242
JY
34} TPM2_TEST_PARMS_COMMAND;\r
35\r
36typedef struct {\r
c411b485 37 TPM2_RESPONSE_HEADER Header;\r
c1d93242
JY
38} TPM2_TEST_PARMS_RESPONSE;\r
39\r
40#pragma pack()\r
41\r
1b0d659e
ZQ
42#define TPMA_CC_COMMANDINDEX_MASK 0x2000FFFF\r
43\r
c1d93242
JY
44/**\r
45 This command returns various information regarding the TPM and its current state.\r
46\r
b3548d32
LG
47 The capability parameter determines the category of data returned. The property parameter\r
48 selects the first value of the selected category to be returned. If there is no property\r
c1d93242 49 that corresponds to the value of property, the next higher value is returned, if it exists.\r
b3548d32 50 The moreData parameter will have a value of YES if there are more values of the requested\r
c1d93242 51 type that were not returned.\r
b3548d32 52 If no next capability exists, the TPM will return a zero-length list and moreData will have\r
c1d93242
JY
53 a value of NO.\r
54\r
b3548d32
LG
55 NOTE:\r
56 To simplify this function, leave returned CapabilityData for caller to unpack since there are\r
c1d93242 57 many capability categories and only few categories will be used in firmware. It means the caller\r
d6b926e7 58 need swap the byte order for the fields in CapabilityData.\r
c1d93242
JY
59\r
60 @param[in] Capability Group selection; determines the format of the response.\r
b3548d32 61 @param[in] Property Further definition of information.\r
c1d93242
JY
62 @param[in] PropertyCount Number of properties of the indicated type to return.\r
63 @param[out] MoreData Flag to indicate if there are more values of this type.\r
64 @param[out] CapabilityData The capability data.\r
b3548d32 65\r
c1d93242
JY
66 @retval EFI_SUCCESS Operation completed successfully.\r
67 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
68**/\r
69EFI_STATUS\r
70EFIAPI\r
71Tpm2GetCapability (\r
c411b485
MK
72 IN TPM_CAP Capability,\r
73 IN UINT32 Property,\r
74 IN UINT32 PropertyCount,\r
75 OUT TPMI_YES_NO *MoreData,\r
76 OUT TPMS_CAPABILITY_DATA *CapabilityData\r
c1d93242
JY
77 )\r
78{\r
c411b485
MK
79 EFI_STATUS Status;\r
80 TPM2_GET_CAPABILITY_COMMAND SendBuffer;\r
81 TPM2_GET_CAPABILITY_RESPONSE RecvBuffer;\r
82 UINT32 SendBufferSize;\r
83 UINT32 RecvBufferSize;\r
c1d93242
JY
84\r
85 //\r
86 // Construct command\r
87 //\r
c411b485
MK
88 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
89 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_GetCapability);\r
c1d93242 90\r
c411b485
MK
91 SendBuffer.Capability = SwapBytes32 (Capability);\r
92 SendBuffer.Property = SwapBytes32 (Property);\r
c1d93242 93 SendBuffer.PropertyCount = SwapBytes32 (PropertyCount);\r
b3548d32 94\r
c411b485 95 SendBufferSize = (UINT32)sizeof (SendBuffer);\r
c1d93242 96 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
b3548d32 97\r
c1d93242
JY
98 //\r
99 // send Tpm command\r
100 //\r
101 RecvBufferSize = sizeof (RecvBuffer);\r
c411b485 102 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
c1d93242
JY
103 if (EFI_ERROR (Status)) {\r
104 return Status;\r
105 }\r
106\r
107 if (RecvBufferSize <= sizeof (TPM2_RESPONSE_HEADER) + sizeof (UINT8)) {\r
108 return EFI_DEVICE_ERROR;\r
109 }\r
110\r
dd577319
ZC
111 //\r
112 // Fail if command failed\r
113 //\r
c411b485
MK
114 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
115 DEBUG ((DEBUG_ERROR, "Tpm2GetCapability: Response Code error! 0x%08x\r\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
dd577319
ZC
116 return EFI_DEVICE_ERROR;\r
117 }\r
118\r
c1d93242
JY
119 //\r
120 // Return the response\r
121 //\r
122 *MoreData = RecvBuffer.MoreData;\r
123 //\r
d6b926e7 124 // Does not unpack all possible property here, the caller should unpack it and note the byte order.\r
c1d93242
JY
125 //\r
126 CopyMem (CapabilityData, &RecvBuffer.CapabilityData, RecvBufferSize - sizeof (TPM2_RESPONSE_HEADER) - sizeof (UINT8));\r
b3548d32 127\r
c1d93242
JY
128 return EFI_SUCCESS;\r
129}\r
130\r
131/**\r
132 This command returns the information of TPM Family.\r
133\r
134 This function parse the value got from TPM2_GetCapability and return the Family.\r
135\r
136 @param[out] Family The Family of TPM. (a 4-octet character string)\r
b3548d32 137\r
c1d93242
JY
138 @retval EFI_SUCCESS Operation completed successfully.\r
139 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
143Tpm2GetCapabilityFamily (\r
c411b485 144 OUT CHAR8 *Family\r
c1d93242
JY
145 )\r
146{\r
c411b485
MK
147 TPMS_CAPABILITY_DATA TpmCap;\r
148 TPMI_YES_NO MoreData;\r
149 EFI_STATUS Status;\r
c1d93242
JY
150\r
151 Status = Tpm2GetCapability (\r
b3548d32
LG
152 TPM_CAP_TPM_PROPERTIES,\r
153 TPM_PT_FAMILY_INDICATOR,\r
154 1,\r
155 &MoreData,\r
c1d93242
JY
156 &TpmCap\r
157 );\r
158 if (EFI_ERROR (Status)) {\r
159 return Status;\r
160 }\r
c411b485 161\r
c1d93242
JY
162 CopyMem (Family, &TpmCap.data.tpmProperties.tpmProperty->value, 4);\r
163\r
164 return EFI_SUCCESS;\r
165}\r
166\r
167/**\r
168 This command returns the information of TPM manufacture ID.\r
169\r
170 This function parse the value got from TPM2_GetCapability and return the TPM manufacture ID.\r
171\r
172 @param[out] ManufactureId The manufacture ID of TPM.\r
b3548d32 173\r
c1d93242
JY
174 @retval EFI_SUCCESS Operation completed successfully.\r
175 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
176**/\r
177EFI_STATUS\r
178EFIAPI\r
179Tpm2GetCapabilityManufactureID (\r
c411b485 180 OUT UINT32 *ManufactureId\r
c1d93242
JY
181 )\r
182{\r
c411b485
MK
183 TPMS_CAPABILITY_DATA TpmCap;\r
184 TPMI_YES_NO MoreData;\r
185 EFI_STATUS Status;\r
c1d93242
JY
186\r
187 Status = Tpm2GetCapability (\r
b3548d32
LG
188 TPM_CAP_TPM_PROPERTIES,\r
189 TPM_PT_MANUFACTURER,\r
190 1,\r
191 &MoreData,\r
c1d93242
JY
192 &TpmCap\r
193 );\r
194 if (EFI_ERROR (Status)) {\r
195 return Status;\r
196 }\r
c411b485 197\r
73126ac2 198 *ManufactureId = TpmCap.data.tpmProperties.tpmProperty->value;\r
c1d93242
JY
199\r
200 return EFI_SUCCESS;\r
201}\r
202\r
203/**\r
204 This command returns the information of TPM FirmwareVersion.\r
205\r
206 This function parse the value got from TPM2_GetCapability and return the TPM FirmwareVersion.\r
207\r
208 @param[out] FirmwareVersion1 The FirmwareVersion1.\r
209 @param[out] FirmwareVersion2 The FirmwareVersion2.\r
b3548d32 210\r
c1d93242
JY
211 @retval EFI_SUCCESS Operation completed successfully.\r
212 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
213**/\r
214EFI_STATUS\r
215EFIAPI\r
216Tpm2GetCapabilityFirmwareVersion (\r
c411b485
MK
217 OUT UINT32 *FirmwareVersion1,\r
218 OUT UINT32 *FirmwareVersion2\r
c1d93242
JY
219 )\r
220{\r
c411b485
MK
221 TPMS_CAPABILITY_DATA TpmCap;\r
222 TPMI_YES_NO MoreData;\r
223 EFI_STATUS Status;\r
c1d93242
JY
224\r
225 Status = Tpm2GetCapability (\r
b3548d32
LG
226 TPM_CAP_TPM_PROPERTIES,\r
227 TPM_PT_FIRMWARE_VERSION_1,\r
228 1,\r
229 &MoreData,\r
c1d93242
JY
230 &TpmCap\r
231 );\r
232 if (EFI_ERROR (Status)) {\r
233 return Status;\r
234 }\r
c411b485 235\r
c1d93242
JY
236 *FirmwareVersion1 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
237\r
238 Status = Tpm2GetCapability (\r
b3548d32
LG
239 TPM_CAP_TPM_PROPERTIES,\r
240 TPM_PT_FIRMWARE_VERSION_2,\r
241 1,\r
242 &MoreData,\r
c1d93242
JY
243 &TpmCap\r
244 );\r
245 if (EFI_ERROR (Status)) {\r
246 return Status;\r
247 }\r
c411b485 248\r
c1d93242
JY
249 *FirmwareVersion2 = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
250\r
251 return EFI_SUCCESS;\r
252}\r
253\r
254/**\r
255 This command returns the information of the maximum value for commandSize and responseSize in a command.\r
256\r
257 This function parse the value got from TPM2_GetCapability and return the max command size and response size\r
258\r
259 @param[out] MaxCommandSize The maximum value for commandSize in a command.\r
260 @param[out] MaxResponseSize The maximum value for responseSize in a command.\r
b3548d32 261\r
c1d93242
JY
262 @retval EFI_SUCCESS Operation completed successfully.\r
263 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
264**/\r
265EFI_STATUS\r
266EFIAPI\r
267Tpm2GetCapabilityMaxCommandResponseSize (\r
c411b485
MK
268 OUT UINT32 *MaxCommandSize,\r
269 OUT UINT32 *MaxResponseSize\r
c1d93242
JY
270 )\r
271{\r
c411b485
MK
272 TPMS_CAPABILITY_DATA TpmCap;\r
273 TPMI_YES_NO MoreData;\r
274 EFI_STATUS Status;\r
c1d93242
JY
275\r
276 Status = Tpm2GetCapability (\r
b3548d32
LG
277 TPM_CAP_TPM_PROPERTIES,\r
278 TPM_PT_MAX_COMMAND_SIZE,\r
279 1,\r
280 &MoreData,\r
c1d93242
JY
281 &TpmCap\r
282 );\r
283 if (EFI_ERROR (Status)) {\r
284 return Status;\r
285 }\r
286\r
287 *MaxCommandSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
288\r
289 Status = Tpm2GetCapability (\r
b3548d32
LG
290 TPM_CAP_TPM_PROPERTIES,\r
291 TPM_PT_MAX_RESPONSE_SIZE,\r
292 1,\r
293 &MoreData,\r
c1d93242
JY
294 &TpmCap\r
295 );\r
296 if (EFI_ERROR (Status)) {\r
297 return Status;\r
298 }\r
299\r
300 *MaxResponseSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
b3548d32 301 return EFI_SUCCESS;\r
c1d93242
JY
302}\r
303\r
304/**\r
305 This command returns Returns a list of TPMS_ALG_PROPERTIES. Each entry is an\r
b3548d32 306 algorithm ID and a set of properties of the algorithm.\r
c1d93242
JY
307\r
308 This function parse the value got from TPM2_GetCapability and return the list.\r
309\r
310 @param[out] AlgList List of algorithm.\r
b3548d32 311\r
c1d93242
JY
312 @retval EFI_SUCCESS Operation completed successfully.\r
313 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
314**/\r
315EFI_STATUS\r
316EFIAPI\r
317Tpm2GetCapabilitySupportedAlg (\r
c411b485 318 OUT TPML_ALG_PROPERTY *AlgList\r
c1d93242
JY
319 )\r
320{\r
c411b485
MK
321 TPMS_CAPABILITY_DATA TpmCap;\r
322 TPMI_YES_NO MoreData;\r
323 UINTN Index;\r
324 EFI_STATUS Status;\r
b3548d32 325\r
c1d93242 326 Status = Tpm2GetCapability (\r
b3548d32
LG
327 TPM_CAP_ALGS,\r
328 1,\r
329 MAX_CAP_ALGS,\r
330 &MoreData,\r
c1d93242
JY
331 &TpmCap\r
332 );\r
333 if (EFI_ERROR (Status)) {\r
334 return Status;\r
335 }\r
b3548d32 336\r
c1d93242
JY
337 CopyMem (AlgList, &TpmCap.data.algorithms, sizeof (TPML_ALG_PROPERTY));\r
338\r
339 AlgList->count = SwapBytes32 (AlgList->count);\r
dd577319
ZC
340 if (AlgList->count > MAX_CAP_ALGS) {\r
341 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilitySupportedAlg - AlgList->count error %x\n", AlgList->count));\r
b3548d32 342 return EFI_DEVICE_ERROR;\r
dd577319
ZC
343 }\r
344\r
c1d93242
JY
345 for (Index = 0; Index < AlgList->count; Index++) {\r
346 AlgList->algProperties[Index].alg = SwapBytes16 (AlgList->algProperties[Index].alg);\r
347 WriteUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties, SwapBytes32 (ReadUnaligned32 ((UINT32 *)&AlgList->algProperties[Index].algProperties)));\r
348 }\r
349\r
350 return EFI_SUCCESS;\r
351}\r
352\r
353/**\r
354 This command returns the information of TPM LockoutCounter.\r
355\r
356 This function parse the value got from TPM2_GetCapability and return the LockoutCounter.\r
357\r
358 @param[out] LockoutCounter The LockoutCounter of TPM.\r
b3548d32 359\r
c1d93242
JY
360 @retval EFI_SUCCESS Operation completed successfully.\r
361 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
362**/\r
363EFI_STATUS\r
364EFIAPI\r
365Tpm2GetCapabilityLockoutCounter (\r
c411b485 366 OUT UINT32 *LockoutCounter\r
c1d93242
JY
367 )\r
368{\r
c411b485
MK
369 TPMS_CAPABILITY_DATA TpmCap;\r
370 TPMI_YES_NO MoreData;\r
371 EFI_STATUS Status;\r
c1d93242
JY
372\r
373 Status = Tpm2GetCapability (\r
b3548d32
LG
374 TPM_CAP_TPM_PROPERTIES,\r
375 TPM_PT_LOCKOUT_COUNTER,\r
376 1,\r
377 &MoreData,\r
c1d93242
JY
378 &TpmCap\r
379 );\r
380 if (EFI_ERROR (Status)) {\r
381 return Status;\r
382 }\r
c411b485 383\r
c1d93242
JY
384 *LockoutCounter = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
385\r
386 return EFI_SUCCESS;\r
387}\r
388\r
389/**\r
390 This command returns the information of TPM LockoutInterval.\r
391\r
392 This function parse the value got from TPM2_GetCapability and return the LockoutInterval.\r
393\r
394 @param[out] LockoutInterval The LockoutInterval of TPM.\r
b3548d32 395\r
c1d93242
JY
396 @retval EFI_SUCCESS Operation completed successfully.\r
397 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
398**/\r
399EFI_STATUS\r
400EFIAPI\r
401Tpm2GetCapabilityLockoutInterval (\r
c411b485 402 OUT UINT32 *LockoutInterval\r
c1d93242
JY
403 )\r
404{\r
c411b485
MK
405 TPMS_CAPABILITY_DATA TpmCap;\r
406 TPMI_YES_NO MoreData;\r
407 EFI_STATUS Status;\r
c1d93242
JY
408\r
409 Status = Tpm2GetCapability (\r
b3548d32
LG
410 TPM_CAP_TPM_PROPERTIES,\r
411 TPM_PT_LOCKOUT_INTERVAL,\r
412 1,\r
413 &MoreData,\r
c1d93242
JY
414 &TpmCap\r
415 );\r
416 if (EFI_ERROR (Status)) {\r
417 return Status;\r
418 }\r
c411b485 419\r
c1d93242
JY
420 *LockoutInterval = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
421\r
422 return EFI_SUCCESS;\r
423}\r
424\r
425/**\r
426 This command returns the information of TPM InputBufferSize.\r
427\r
428 This function parse the value got from TPM2_GetCapability and return the InputBufferSize.\r
429\r
430 @param[out] InputBufferSize The InputBufferSize of TPM.\r
431 the maximum size of a parameter (typically, a TPM2B_MAX_BUFFER)\r
b3548d32 432\r
c1d93242
JY
433 @retval EFI_SUCCESS Operation completed successfully.\r
434 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
435**/\r
436EFI_STATUS\r
437EFIAPI\r
438Tpm2GetCapabilityInputBufferSize (\r
c411b485 439 OUT UINT32 *InputBufferSize\r
c1d93242
JY
440 )\r
441{\r
c411b485
MK
442 TPMS_CAPABILITY_DATA TpmCap;\r
443 TPMI_YES_NO MoreData;\r
444 EFI_STATUS Status;\r
c1d93242
JY
445\r
446 Status = Tpm2GetCapability (\r
b3548d32
LG
447 TPM_CAP_TPM_PROPERTIES,\r
448 TPM_PT_INPUT_BUFFER,\r
449 1,\r
450 &MoreData,\r
c1d93242
JY
451 &TpmCap\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 return Status;\r
455 }\r
c411b485 456\r
c1d93242
JY
457 *InputBufferSize = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
458\r
459 return EFI_SUCCESS;\r
460}\r
461\r
462/**\r
463 This command returns the information of TPM PCRs.\r
464\r
465 This function parse the value got from TPM2_GetCapability and return the PcrSelection.\r
466\r
467 @param[out] Pcrs The Pcr Selection\r
b3548d32 468\r
c1d93242
JY
469 @retval EFI_SUCCESS Operation completed successfully.\r
470 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
471**/\r
472EFI_STATUS\r
473EFIAPI\r
474Tpm2GetCapabilityPcrs (\r
c411b485 475 OUT TPML_PCR_SELECTION *Pcrs\r
c1d93242
JY
476 )\r
477{\r
c411b485
MK
478 TPMS_CAPABILITY_DATA TpmCap;\r
479 TPMI_YES_NO MoreData;\r
480 EFI_STATUS Status;\r
481 UINTN Index;\r
c1d93242
JY
482\r
483 Status = Tpm2GetCapability (\r
b3548d32
LG
484 TPM_CAP_PCRS,\r
485 0,\r
486 1,\r
487 &MoreData,\r
c1d93242
JY
488 &TpmCap\r
489 );\r
490 if (EFI_ERROR (Status)) {\r
491 return Status;\r
492 }\r
493\r
494 Pcrs->count = SwapBytes32 (TpmCap.data.assignedPCR.count);\r
dd577319
ZC
495 if (Pcrs->count > HASH_COUNT) {\r
496 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - Pcrs->count error %x\n", Pcrs->count));\r
497 return EFI_DEVICE_ERROR;\r
498 }\r
499\r
c1d93242 500 for (Index = 0; Index < Pcrs->count; Index++) {\r
c411b485 501 Pcrs->pcrSelections[Index].hash = SwapBytes16 (TpmCap.data.assignedPCR.pcrSelections[Index].hash);\r
c1d93242 502 Pcrs->pcrSelections[Index].sizeofSelect = TpmCap.data.assignedPCR.pcrSelections[Index].sizeofSelect;\r
dd577319
ZC
503 if (Pcrs->pcrSelections[Index].sizeofSelect > PCR_SELECT_MAX) {\r
504 DEBUG ((DEBUG_ERROR, "Tpm2GetCapabilityPcrs - sizeofSelect error %x\n", Pcrs->pcrSelections[Index].sizeofSelect));\r
505 return EFI_DEVICE_ERROR;\r
506 }\r
c411b485 507\r
c1d93242
JY
508 CopyMem (Pcrs->pcrSelections[Index].pcrSelect, TpmCap.data.assignedPCR.pcrSelections[Index].pcrSelect, Pcrs->pcrSelections[Index].sizeofSelect);\r
509 }\r
510\r
511 return EFI_SUCCESS;\r
512}\r
513\r
07cdba18
JY
514/**\r
515 This function will query the TPM to determine which hashing algorithms\r
516 are supported and which PCR banks are currently active.\r
517\r
518 @param[out] TpmHashAlgorithmBitmap A bitmask containing the algorithms supported by the TPM.\r
519 @param[out] ActivePcrBanks A bitmask containing the PCRs currently allocated.\r
520\r
521 @retval EFI_SUCCESS TPM was successfully queried and return values can be trusted.\r
522 @retval Others An error occurred, likely in communication with the TPM.\r
523\r
524**/\r
525EFI_STATUS\r
526EFIAPI\r
527Tpm2GetCapabilitySupportedAndActivePcrs (\r
c411b485
MK
528 OUT UINT32 *TpmHashAlgorithmBitmap,\r
529 OUT UINT32 *ActivePcrBanks\r
07cdba18
JY
530 )\r
531{\r
c411b485
MK
532 EFI_STATUS Status;\r
533 TPML_PCR_SELECTION Pcrs;\r
534 UINTN Index;\r
535 UINT8 ActivePcrBankCount;\r
07cdba18
JY
536\r
537 //\r
3c610775 538 // Get supported PCR\r
07cdba18
JY
539 //\r
540 Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
3c610775
RGC
541 DEBUG ((DEBUG_INFO, "Supported PCRs - Count = %08x\n", Pcrs.count));\r
542 ActivePcrBankCount = 0;\r
07cdba18
JY
543 //\r
544 // If error, assume that we have at least SHA-1 (and return the error.)\r
545 //\r
546 if (EFI_ERROR (Status)) {\r
3c610775 547 DEBUG ((DEBUG_ERROR, "GetSupportedAndActivePcrs - Tpm2GetCapabilityPcrs fail!\n"));\r
07cdba18
JY
548 *TpmHashAlgorithmBitmap = HASH_ALG_SHA1;\r
549 *ActivePcrBanks = HASH_ALG_SHA1;\r
c411b485 550 ActivePcrBankCount = 1;\r
07cdba18
JY
551 }\r
552 //\r
553 // Otherwise, process the return data to determine what algorithms are supported\r
554 // and currently allocated.\r
555 //\r
556 else {\r
07cdba18
JY
557 *TpmHashAlgorithmBitmap = 0;\r
558 *ActivePcrBanks = 0;\r
559 for (Index = 0; Index < Pcrs.count; Index++) {\r
560 switch (Pcrs.pcrSelections[Index].hash) {\r
c411b485
MK
561 case TPM_ALG_SHA1:\r
562 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA1 present.\n"));\r
563 *TpmHashAlgorithmBitmap |= HASH_ALG_SHA1;\r
564 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
565 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA1 active.\n"));\r
566 *ActivePcrBanks |= HASH_ALG_SHA1;\r
567 ActivePcrBankCount++;\r
568 }\r
569\r
570 break;\r
571 case TPM_ALG_SHA256:\r
572 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA256 present.\n"));\r
573 *TpmHashAlgorithmBitmap |= HASH_ALG_SHA256;\r
574 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
575 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA256 active.\n"));\r
576 *ActivePcrBanks |= HASH_ALG_SHA256;\r
577 ActivePcrBankCount++;\r
578 }\r
579\r
580 break;\r
581 case TPM_ALG_SHA384:\r
582 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA384 present.\n"));\r
583 *TpmHashAlgorithmBitmap |= HASH_ALG_SHA384;\r
584 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
585 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA384 active.\n"));\r
586 *ActivePcrBanks |= HASH_ALG_SHA384;\r
587 ActivePcrBankCount++;\r
588 }\r
589\r
590 break;\r
591 case TPM_ALG_SHA512:\r
592 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA512 present.\n"));\r
593 *TpmHashAlgorithmBitmap |= HASH_ALG_SHA512;\r
594 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
595 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SHA512 active.\n"));\r
596 *ActivePcrBanks |= HASH_ALG_SHA512;\r
597 ActivePcrBankCount++;\r
598 }\r
599\r
600 break;\r
601 case TPM_ALG_SM3_256:\r
602 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SM3_256 present.\n"));\r
603 *TpmHashAlgorithmBitmap |= HASH_ALG_SM3_256;\r
604 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {\r
605 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - HASH_ALG_SM3_256 active.\n"));\r
606 *ActivePcrBanks |= HASH_ALG_SM3_256;\r
607 ActivePcrBankCount++;\r
608 }\r
609\r
610 break;\r
611 default:\r
612 DEBUG ((DEBUG_VERBOSE, "GetSupportedAndActivePcrs - Unsupported bank 0x%04x.\n", Pcrs.pcrSelections[Index].hash));\r
613 continue;\r
614 break;\r
07cdba18
JY
615 }\r
616 }\r
617 }\r
618\r
3c610775 619 DEBUG ((DEBUG_INFO, "GetSupportedAndActivePcrs - Count = %08x\n", ActivePcrBankCount));\r
07cdba18
JY
620 return Status;\r
621}\r
622\r
c1d93242
JY
623/**\r
624 This command returns the information of TPM AlgorithmSet.\r
625\r
626 This function parse the value got from TPM2_GetCapability and return the AlgorithmSet.\r
627\r
628 @param[out] AlgorithmSet The AlgorithmSet of TPM.\r
b3548d32 629\r
c1d93242
JY
630 @retval EFI_SUCCESS Operation completed successfully.\r
631 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
632**/\r
633EFI_STATUS\r
634EFIAPI\r
635Tpm2GetCapabilityAlgorithmSet (\r
c411b485 636 OUT UINT32 *AlgorithmSet\r
c1d93242
JY
637 )\r
638{\r
c411b485
MK
639 TPMS_CAPABILITY_DATA TpmCap;\r
640 TPMI_YES_NO MoreData;\r
641 EFI_STATUS Status;\r
c1d93242
JY
642\r
643 Status = Tpm2GetCapability (\r
b3548d32
LG
644 TPM_CAP_TPM_PROPERTIES,\r
645 TPM_PT_ALGORITHM_SET,\r
646 1,\r
647 &MoreData,\r
c1d93242
JY
648 &TpmCap\r
649 );\r
650 if (EFI_ERROR (Status)) {\r
651 return Status;\r
652 }\r
c411b485 653\r
c1d93242
JY
654 *AlgorithmSet = SwapBytes32 (TpmCap.data.tpmProperties.tpmProperty->value);\r
655\r
656 return EFI_SUCCESS;\r
657}\r
658\r
1b0d659e
ZQ
659/**\r
660 This function will query if the command is supported.\r
661\r
662 @param[In] Command TPM_CC command starts from TPM_CC_FIRST.\r
663 @param[out] IsCmdImpl The command is supported or not.\r
664\r
665 @retval EFI_SUCCESS Operation completed successfully.\r
666 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
667**/\r
668EFI_STATUS\r
669EFIAPI\r
670Tpm2GetCapabilityIsCommandImplemented (\r
c411b485
MK
671 IN TPM_CC Command,\r
672 OUT BOOLEAN *IsCmdImpl\r
1b0d659e
ZQ
673 )\r
674{\r
c411b485
MK
675 TPMS_CAPABILITY_DATA TpmCap;\r
676 TPMI_YES_NO MoreData;\r
677 EFI_STATUS Status;\r
678 UINT32 Attribute;\r
1b0d659e
ZQ
679\r
680 Status = Tpm2GetCapability (\r
681 TPM_CAP_COMMANDS,\r
682 Command,\r
683 1,\r
684 &MoreData,\r
685 &TpmCap\r
686 );\r
687 if (EFI_ERROR (Status)) {\r
688 return Status;\r
689 }\r
690\r
691 CopyMem (&Attribute, &TpmCap.data.command.commandAttributes[0], sizeof (UINT32));\r
c411b485 692 *IsCmdImpl = (Command == (SwapBytes32 (Attribute) & TPMA_CC_COMMANDINDEX_MASK));\r
1b0d659e
ZQ
693\r
694 return EFI_SUCCESS;\r
695}\r
696\r
c1d93242
JY
697/**\r
698 This command is used to check to see if specific combinations of algorithm parameters are supported.\r
699\r
700 @param[in] Parameters Algorithm parameters to be validated\r
701\r
702 @retval EFI_SUCCESS Operation completed successfully.\r
703 @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
704**/\r
705EFI_STATUS\r
706EFIAPI\r
707Tpm2TestParms (\r
c411b485 708 IN TPMT_PUBLIC_PARMS *Parameters\r
c1d93242
JY
709 )\r
710{\r
c411b485
MK
711 EFI_STATUS Status;\r
712 TPM2_TEST_PARMS_COMMAND SendBuffer;\r
713 TPM2_TEST_PARMS_RESPONSE RecvBuffer;\r
714 UINT32 SendBufferSize;\r
715 UINT32 RecvBufferSize;\r
716 UINT8 *Buffer;\r
c1d93242
JY
717\r
718 //\r
719 // Construct command\r
720 //\r
c411b485
MK
721 SendBuffer.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);\r
722 SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_TestParms);\r
c1d93242
JY
723\r
724 Buffer = (UINT8 *)&SendBuffer.Parameters;\r
725 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->type));\r
c411b485 726 Buffer += sizeof (UINT16);\r
c1d93242 727 switch (Parameters->type) {\r
c411b485
MK
728 case TPM_ALG_KEYEDHASH:\r
729 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.scheme));\r
730 Buffer += sizeof (UINT16);\r
731 switch (Parameters->parameters.keyedHashDetail.scheme.scheme) {\r
732 case TPM_ALG_HMAC:\r
733 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.hmac.hashAlg));\r
734 Buffer += sizeof (UINT16);\r
735 break;\r
736 case TPM_ALG_XOR:\r
737 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.hashAlg));\r
738 Buffer += sizeof (UINT16);\r
739 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.keyedHashDetail.scheme.details.xor.kdf));\r
740 Buffer += sizeof (UINT16);\r
741 break;\r
742 default:\r
743 return EFI_INVALID_PARAMETER;\r
744 }\r
745\r
746 case TPM_ALG_SYMCIPHER:\r
747 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.algorithm));\r
748 Buffer += sizeof (UINT16);\r
749 switch (Parameters->parameters.symDetail.algorithm) {\r
750 case TPM_ALG_AES:\r
751 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.aes));\r
752 Buffer += sizeof (UINT16);\r
753 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.aes));\r
754 Buffer += sizeof (UINT16);\r
755 break;\r
756 case TPM_ALG_SM4:\r
757 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.SM4));\r
758 Buffer += sizeof (UINT16);\r
759 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.SM4));\r
760 Buffer += sizeof (UINT16);\r
761 break;\r
762 case TPM_ALG_XOR:\r
763 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.xor));\r
764 Buffer += sizeof (UINT16);\r
765 break;\r
766 case TPM_ALG_NULL:\r
767 break;\r
768 default:\r
769 return EFI_INVALID_PARAMETER;\r
770 }\r
771\r
c1d93242 772 break;\r
c411b485
MK
773 case TPM_ALG_RSA:\r
774 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.algorithm));\r
775 Buffer += sizeof (UINT16);\r
776 switch (Parameters->parameters.rsaDetail.symmetric.algorithm) {\r
777 case TPM_ALG_AES:\r
778 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.aes));\r
779 Buffer += sizeof (UINT16);\r
780 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.aes));\r
781 Buffer += sizeof (UINT16);\r
782 break;\r
783 case TPM_ALG_SM4:\r
784 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.SM4));\r
785 Buffer += sizeof (UINT16);\r
786 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.SM4));\r
787 Buffer += sizeof (UINT16);\r
788 break;\r
789 case TPM_ALG_NULL:\r
790 break;\r
791 default:\r
792 return EFI_INVALID_PARAMETER;\r
793 }\r
794\r
795 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.scheme));\r
796 Buffer += sizeof (UINT16);\r
797 switch (Parameters->parameters.rsaDetail.scheme.scheme) {\r
798 case TPM_ALG_RSASSA:\r
799 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsassa.hashAlg));\r
800 Buffer += sizeof (UINT16);\r
801 break;\r
802 case TPM_ALG_RSAPSS:\r
803 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsapss.hashAlg));\r
804 Buffer += sizeof (UINT16);\r
805 break;\r
806 case TPM_ALG_RSAES:\r
807 break;\r
808 case TPM_ALG_OAEP:\r
809 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.oaep.hashAlg));\r
810 Buffer += sizeof (UINT16);\r
811 break;\r
812 case TPM_ALG_NULL:\r
813 break;\r
814 default:\r
815 return EFI_INVALID_PARAMETER;\r
816 }\r
817\r
818 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.keyBits));\r
819 Buffer += sizeof (UINT16);\r
820 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Parameters->parameters.rsaDetail.exponent));\r
821 Buffer += sizeof (UINT32);\r
c1d93242 822 break;\r
c411b485
MK
823 case TPM_ALG_ECC:\r
824 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.algorithm));\r
825 Buffer += sizeof (UINT16);\r
826 switch (Parameters->parameters.eccDetail.symmetric.algorithm) {\r
827 case TPM_ALG_AES:\r
828 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.aes));\r
829 Buffer += sizeof (UINT16);\r
830 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.aes));\r
831 Buffer += sizeof (UINT16);\r
832 break;\r
833 case TPM_ALG_SM4:\r
834 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.SM4));\r
835 Buffer += sizeof (UINT16);\r
836 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.SM4));\r
837 Buffer += sizeof (UINT16);\r
838 break;\r
839 case TPM_ALG_NULL:\r
840 break;\r
841 default:\r
842 return EFI_INVALID_PARAMETER;\r
843 }\r
844\r
845 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.scheme));\r
846 Buffer += sizeof (UINT16);\r
847 switch (Parameters->parameters.eccDetail.scheme.scheme) {\r
848 case TPM_ALG_ECDSA:\r
849 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdsa.hashAlg));\r
850 Buffer += sizeof (UINT16);\r
851 break;\r
852 case TPM_ALG_ECDAA:\r
853 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdaa.hashAlg));\r
854 Buffer += sizeof (UINT16);\r
855 break;\r
856 case TPM_ALG_ECSCHNORR:\r
857 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecSchnorr.hashAlg));\r
858 Buffer += sizeof (UINT16);\r
859 break;\r
860 case TPM_ALG_ECDH:\r
861 break;\r
862 case TPM_ALG_NULL:\r
863 break;\r
864 default:\r
865 return EFI_INVALID_PARAMETER;\r
866 }\r
867\r
868 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.curveID));\r
869 Buffer += sizeof (UINT16);\r
870 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.scheme));\r
871 Buffer += sizeof (UINT16);\r
872 switch (Parameters->parameters.eccDetail.kdf.scheme) {\r
873 case TPM_ALG_MGF1:\r
874 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.mgf1.hashAlg));\r
875 Buffer += sizeof (UINT16);\r
876 break;\r
877 case TPM_ALG_KDF1_SP800_108:\r
878 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg));\r
879 Buffer += sizeof (UINT16);\r
880 break;\r
881 case TPM_ALG_KDF1_SP800_56a:\r
882 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg));\r
883 Buffer += sizeof (UINT16);\r
884 break;\r
885 case TPM_ALG_KDF2:\r
886 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf2.hashAlg));\r
887 Buffer += sizeof (UINT16);\r
888 break;\r
889 case TPM_ALG_NULL:\r
890 break;\r
891 default:\r
892 return EFI_INVALID_PARAMETER;\r
893 }\r
894\r
c1d93242
JY
895 break;\r
896 default:\r
897 return EFI_INVALID_PARAMETER;\r
c1d93242
JY
898 }\r
899\r
c411b485 900 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);\r
c1d93242
JY
901 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);\r
902\r
903 //\r
904 // send Tpm command\r
905 //\r
906 RecvBufferSize = sizeof (RecvBuffer);\r
c411b485 907 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);\r
c1d93242
JY
908 if (EFI_ERROR (Status)) {\r
909 return Status;\r
910 }\r
911\r
912 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {\r
3c610775 913 DEBUG ((DEBUG_ERROR, "Tpm2TestParms - RecvBufferSize Error - %x\n", RecvBufferSize));\r
c1d93242
JY
914 return EFI_DEVICE_ERROR;\r
915 }\r
c411b485
MK
916\r
917 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {\r
918 DEBUG ((DEBUG_ERROR, "Tpm2TestParms - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));\r
c1d93242
JY
919 return EFI_UNSUPPORTED;\r
920 }\r
921\r
922 return EFI_SUCCESS;\r
923}\r