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