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