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