VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/SecurityPkg/Library/Tpm2CommandLib/Tpm2Capability.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 29.6 KB
Line 
1/** @file
2 Implement TPM2 Capability related command.
3
4Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
5SPDX-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
18typedef struct {
19 TPM2_COMMAND_HEADER Header;
20 TPM_CAP Capability;
21 UINT32 Property;
22 UINT32 PropertyCount;
23} TPM2_GET_CAPABILITY_COMMAND;
24
25typedef struct {
26 TPM2_RESPONSE_HEADER Header;
27 TPMI_YES_NO MoreData;
28 TPMS_CAPABILITY_DATA CapabilityData;
29} TPM2_GET_CAPABILITY_RESPONSE;
30
31typedef struct {
32 TPM2_COMMAND_HEADER Header;
33 TPMT_PUBLIC_PARMS Parameters;
34} TPM2_TEST_PARMS_COMMAND;
35
36typedef 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**/
69EFI_STATUS
70EFIAPI
71Tpm2GetCapability (
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**/
141EFI_STATUS
142EFIAPI
143Tpm2GetCapabilityFamily (
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**/
177EFI_STATUS
178EFIAPI
179Tpm2GetCapabilityManufactureID (
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**/
214EFI_STATUS
215EFIAPI
216Tpm2GetCapabilityFirmwareVersion (
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**/
265EFI_STATUS
266EFIAPI
267Tpm2GetCapabilityMaxCommandResponseSize (
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**/
315EFI_STATUS
316EFIAPI
317Tpm2GetCapabilitySupportedAlg (
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**/
363EFI_STATUS
364EFIAPI
365Tpm2GetCapabilityLockoutCounter (
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**/
399EFI_STATUS
400EFIAPI
401Tpm2GetCapabilityLockoutInterval (
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**/
436EFI_STATUS
437EFIAPI
438Tpm2GetCapabilityInputBufferSize (
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**/
472EFI_STATUS
473EFIAPI
474Tpm2GetCapabilityPcrs (
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**/
525EFI_STATUS
526EFIAPI
527Tpm2GetCapabilitySupportedAndActivePcrs (
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**/
633EFI_STATUS
634EFIAPI
635Tpm2GetCapabilityAlgorithmSet (
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**/
668EFI_STATUS
669EFIAPI
670Tpm2GetCapabilityIsCommandImplemented (
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**/
705EFI_STATUS
706EFIAPI
707Tpm2TestParms (
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 break;
747 case TPM_ALG_SYMCIPHER:
748 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.algorithm));
749 Buffer += sizeof (UINT16);
750 switch (Parameters->parameters.symDetail.algorithm) {
751 case TPM_ALG_AES:
752 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.aes));
753 Buffer += sizeof (UINT16);
754 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.aes));
755 Buffer += sizeof (UINT16);
756 break;
757 case TPM_ALG_SM4:
758 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.SM4));
759 Buffer += sizeof (UINT16);
760 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.mode.SM4));
761 Buffer += sizeof (UINT16);
762 break;
763 case TPM_ALG_XOR:
764 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.symDetail.keyBits.xor_));
765 Buffer += sizeof (UINT16);
766 break;
767 case TPM_ALG_NULL:
768 break;
769 default:
770 return EFI_INVALID_PARAMETER;
771 }
772
773 break;
774 case TPM_ALG_RSA:
775 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.algorithm));
776 Buffer += sizeof (UINT16);
777 switch (Parameters->parameters.rsaDetail.symmetric.algorithm) {
778 case TPM_ALG_AES:
779 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.aes));
780 Buffer += sizeof (UINT16);
781 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.aes));
782 Buffer += sizeof (UINT16);
783 break;
784 case TPM_ALG_SM4:
785 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.keyBits.SM4));
786 Buffer += sizeof (UINT16);
787 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.symmetric.mode.SM4));
788 Buffer += sizeof (UINT16);
789 break;
790 case TPM_ALG_NULL:
791 break;
792 default:
793 return EFI_INVALID_PARAMETER;
794 }
795
796 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.scheme));
797 Buffer += sizeof (UINT16);
798 switch (Parameters->parameters.rsaDetail.scheme.scheme) {
799 case TPM_ALG_RSASSA:
800 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsassa.hashAlg));
801 Buffer += sizeof (UINT16);
802 break;
803 case TPM_ALG_RSAPSS:
804 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.rsapss.hashAlg));
805 Buffer += sizeof (UINT16);
806 break;
807 case TPM_ALG_RSAES:
808 break;
809 case TPM_ALG_OAEP:
810 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.scheme.details.oaep.hashAlg));
811 Buffer += sizeof (UINT16);
812 break;
813 case TPM_ALG_NULL:
814 break;
815 default:
816 return EFI_INVALID_PARAMETER;
817 }
818
819 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.rsaDetail.keyBits));
820 Buffer += sizeof (UINT16);
821 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (Parameters->parameters.rsaDetail.exponent));
822 Buffer += sizeof (UINT32);
823 break;
824 case TPM_ALG_ECC:
825 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.algorithm));
826 Buffer += sizeof (UINT16);
827 switch (Parameters->parameters.eccDetail.symmetric.algorithm) {
828 case TPM_ALG_AES:
829 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.aes));
830 Buffer += sizeof (UINT16);
831 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.aes));
832 Buffer += sizeof (UINT16);
833 break;
834 case TPM_ALG_SM4:
835 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.keyBits.SM4));
836 Buffer += sizeof (UINT16);
837 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.symmetric.mode.SM4));
838 Buffer += sizeof (UINT16);
839 break;
840 case TPM_ALG_NULL:
841 break;
842 default:
843 return EFI_INVALID_PARAMETER;
844 }
845
846 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.scheme));
847 Buffer += sizeof (UINT16);
848 switch (Parameters->parameters.eccDetail.scheme.scheme) {
849 case TPM_ALG_ECDSA:
850 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdsa.hashAlg));
851 Buffer += sizeof (UINT16);
852 break;
853 case TPM_ALG_ECDAA:
854 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecdaa.hashAlg));
855 Buffer += sizeof (UINT16);
856 break;
857 case TPM_ALG_ECSCHNORR:
858 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.scheme.details.ecSchnorr.hashAlg));
859 Buffer += sizeof (UINT16);
860 break;
861 case TPM_ALG_ECDH:
862 break;
863 case TPM_ALG_NULL:
864 break;
865 default:
866 return EFI_INVALID_PARAMETER;
867 }
868
869 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.curveID));
870 Buffer += sizeof (UINT16);
871 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.scheme));
872 Buffer += sizeof (UINT16);
873 switch (Parameters->parameters.eccDetail.kdf.scheme) {
874 case TPM_ALG_MGF1:
875 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.mgf1.hashAlg));
876 Buffer += sizeof (UINT16);
877 break;
878 case TPM_ALG_KDF1_SP800_108:
879 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_sp800_108.hashAlg));
880 Buffer += sizeof (UINT16);
881 break;
882 case TPM_ALG_KDF1_SP800_56a:
883 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf1_SP800_56a.hashAlg));
884 Buffer += sizeof (UINT16);
885 break;
886 case TPM_ALG_KDF2:
887 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Parameters->parameters.eccDetail.kdf.details.kdf2.hashAlg));
888 Buffer += sizeof (UINT16);
889 break;
890 case TPM_ALG_NULL:
891 break;
892 default:
893 return EFI_INVALID_PARAMETER;
894 }
895
896 break;
897 default:
898 return EFI_INVALID_PARAMETER;
899 }
900
901 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
902 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
903
904 //
905 // send Tpm command
906 //
907 RecvBufferSize = sizeof (RecvBuffer);
908 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
909 if (EFI_ERROR (Status)) {
910 return Status;
911 }
912
913 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
914 DEBUG ((DEBUG_ERROR, "Tpm2TestParms - RecvBufferSize Error - %x\n", RecvBufferSize));
915 return EFI_DEVICE_ERROR;
916 }
917
918 if (SwapBytes32 (RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
919 DEBUG ((DEBUG_ERROR, "Tpm2TestParms - responseCode - %x\n", SwapBytes32 (RecvBuffer.Header.responseCode)));
920 return EFI_UNSUPPORTED;
921 }
922
923 return EFI_SUCCESS;
924}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette