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