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