]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigImpl.c
OvmfPkg/Csm/LegacyBiosDxe: Update to make it build for OVMF
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Config / Tcg2ConfigImpl.c
1 /** @file
2 HII Config Access protocol implementation of TCG2 configuration module.
3 NOTE: This module is only for reference only, each platform should have its own setup page.
4
5 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "Tcg2ConfigImpl.h"
12 #include <Library/PcdLib.h>
13 #include <Library/Tpm2CommandLib.h>
14 #include <Library/Tpm2DeviceLib.h>
15 #include <Library/IoLib.h>
16
17 #include <Guid/TpmInstance.h>
18
19 #include <IndustryStandard/TpmPtp.h>
20
21 #define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
22
23 TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1] = TPM_INSTANCE_ID_LIST;
24
25 TCG2_CONFIG_PRIVATE_DATA *mTcg2ConfigPrivateDate;
26 TCG2_CONFIG_PRIVATE_DATA mTcg2ConfigPrivateDateTemplate = {
27 TCG2_CONFIG_PRIVATE_DATA_SIGNATURE,
28 {
29 Tcg2ExtractConfig,
30 Tcg2RouteConfig,
31 Tcg2Callback
32 }
33 };
34
35 HII_VENDOR_DEVICE_PATH mTcg2HiiVendorDevicePath = {
36 {
37 {
38 HARDWARE_DEVICE_PATH,
39 HW_VENDOR_DP,
40 {
41 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
42 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
43 }
44 },
45 TCG2_CONFIG_FORM_SET_GUID
46 },
47 {
48 END_DEVICE_PATH_TYPE,
49 END_ENTIRE_DEVICE_PATH_SUBTYPE,
50 {
51 (UINT8) (END_DEVICE_PATH_LENGTH),
52 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
53 }
54 }
55 };
56
57 UINT8 mCurrentPpRequest;
58
59 /**
60 Return if PTP CRB is supported.
61
62 @param[in] Register Pointer to PTP register.
63
64 @retval TRUE PTP CRB is supported.
65 @retval FALSE PTP CRB is unsupported.
66 **/
67 BOOLEAN
68 IsPtpCrbSupported (
69 IN VOID *Register
70 )
71 {
72 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
73
74 //
75 // Check interface id
76 //
77 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
78
79 if (((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) ||
80 (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) &&
81 (InterfaceId.Bits.CapCRB != 0)) {
82 return TRUE;
83 }
84 return FALSE;
85 }
86
87 /**
88 Return if PTP FIFO is supported.
89
90 @param[in] Register Pointer to PTP register.
91
92 @retval TRUE PTP FIFO is supported.
93 @retval FALSE PTP FIFO is unsupported.
94 **/
95 BOOLEAN
96 IsPtpFifoSupported (
97 IN VOID *Register
98 )
99 {
100 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
101
102 //
103 // Check interface id
104 //
105 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
106
107 if (((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) ||
108 (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) &&
109 (InterfaceId.Bits.CapFIFO != 0)) {
110 return TRUE;
111 }
112 return FALSE;
113 }
114
115 /**
116 Set PTP interface type.
117 Do not update PcdActiveTpmInterfaceType here because interface change only happens on next _TPM_INIT
118
119 @param[in] Register Pointer to PTP register.
120 @param[in] PtpInterface PTP interface type.
121
122 @retval EFI_SUCCESS PTP interface type is set.
123 @retval EFI_INVALID_PARAMETER PTP interface type is invalid.
124 @retval EFI_UNSUPPORTED PTP interface type is unsupported.
125 @retval EFI_WRITE_PROTECTED PTP interface is locked.
126 **/
127 EFI_STATUS
128 SetPtpInterface (
129 IN VOID *Register,
130 IN UINT8 PtpInterface
131 )
132 {
133 TPM2_PTP_INTERFACE_TYPE PtpInterfaceCurrent;
134 PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
135
136 PtpInterfaceCurrent = PcdGet8(PcdActiveTpmInterfaceType);
137 if ((PtpInterfaceCurrent != Tpm2PtpInterfaceFifo) &&
138 (PtpInterfaceCurrent != Tpm2PtpInterfaceCrb)) {
139 return EFI_UNSUPPORTED;
140 }
141 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
142 if (InterfaceId.Bits.IntfSelLock != 0) {
143 return EFI_WRITE_PROTECTED;
144 }
145
146 switch (PtpInterface) {
147 case Tpm2PtpInterfaceFifo:
148 if (InterfaceId.Bits.CapFIFO == 0) {
149 return EFI_UNSUPPORTED;
150 }
151 InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_FIFO;
152 MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);
153 return EFI_SUCCESS;
154 case Tpm2PtpInterfaceCrb:
155 if (InterfaceId.Bits.CapCRB == 0) {
156 return EFI_UNSUPPORTED;
157 }
158 InterfaceId.Bits.InterfaceSelector = PTP_INTERFACE_IDENTIFIER_INTERFACE_SELECTOR_CRB;
159 MmioWrite32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId, InterfaceId.Uint32);
160 return EFI_SUCCESS;
161 default:
162 return EFI_INVALID_PARAMETER;
163 }
164 }
165
166 /**
167 This function allows a caller to extract the current configuration for one
168 or more named elements from the target driver.
169
170 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
171 @param[in] Request A null-terminated Unicode string in
172 <ConfigRequest> format.
173 @param[out] Progress On return, points to a character in the Request
174 string. Points to the string's null terminator if
175 request was successful. Points to the most recent
176 '&' before the first failing name/value pair (or
177 the beginning of the string if the failure is in
178 the first name/value pair) if the request was not
179 successful.
180 @param[out] Results A null-terminated Unicode string in
181 <ConfigAltResp> format which has all values filled
182 in for the names in the Request string. String to
183 be allocated by the called function.
184
185 @retval EFI_SUCCESS The Results is filled with the requested values.
186 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
187 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
188 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
189 driver.
190
191 **/
192 EFI_STATUS
193 EFIAPI
194 Tcg2ExtractConfig (
195 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
196 IN CONST EFI_STRING Request,
197 OUT EFI_STRING *Progress,
198 OUT EFI_STRING *Results
199 )
200 {
201 if (Progress == NULL || Results == NULL) {
202 return EFI_INVALID_PARAMETER;
203 }
204
205 *Progress = Request;
206 return EFI_NOT_FOUND;
207 }
208
209 /**
210 Save TPM request to variable space.
211
212 @param[in] PpRequest Physical Presence request command.
213
214 @retval EFI_SUCCESS The operation is finished successfully.
215 @retval Others Other errors as indicated.
216
217 **/
218 EFI_STATUS
219 SaveTcg2PpRequest (
220 IN UINT8 PpRequest
221 )
222 {
223 UINT32 ReturnCode;
224 EFI_STATUS Status;
225
226 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
227 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
228 mCurrentPpRequest = PpRequest;
229 Status = EFI_SUCCESS;
230 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
231 Status = EFI_OUT_OF_RESOURCES;
232 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
233 Status = EFI_UNSUPPORTED;
234 } else {
235 Status = EFI_DEVICE_ERROR;
236 }
237
238 return Status;
239 }
240
241 /**
242 Save TPM request to variable space.
243
244 @param[in] PpRequestParameter Physical Presence request parameter.
245
246 @retval EFI_SUCCESS The operation is finished successfully.
247 @retval Others Other errors as indicated.
248
249 **/
250 EFI_STATUS
251 SaveTcg2PpRequestParameter (
252 IN UINT32 PpRequestParameter
253 )
254 {
255 UINT32 ReturnCode;
256 EFI_STATUS Status;
257
258 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (mCurrentPpRequest, PpRequestParameter);
259 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
260 Status = EFI_SUCCESS;
261 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
262 Status = EFI_OUT_OF_RESOURCES;
263 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
264 Status = EFI_UNSUPPORTED;
265 } else {
266 Status = EFI_DEVICE_ERROR;
267 }
268
269 return Status;
270 }
271
272 /**
273 Save Tcg2 PCR Banks request request to variable space.
274
275 @param[in] PCRBankIndex PCR Bank Index.
276 @param[in] Enable Enable or disable this PCR Bank.
277
278 @retval EFI_SUCCESS The operation is finished successfully.
279 @retval Others Other errors as indicated.
280
281 **/
282 EFI_STATUS
283 SaveTcg2PCRBanksRequest (
284 IN UINTN PCRBankIndex,
285 IN BOOLEAN Enable
286 )
287 {
288 UINT32 ReturnCode;
289 EFI_STATUS Status;
290
291 if (Enable) {
292 mTcg2ConfigPrivateDate->PCRBanksDesired |= (0x1 << PCRBankIndex);
293 } else {
294 mTcg2ConfigPrivateDate->PCRBanksDesired &= ~(0x1 << PCRBankIndex);
295 }
296
297 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS, mTcg2ConfigPrivateDate->PCRBanksDesired);
298 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
299 Status = EFI_SUCCESS;
300 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
301 Status = EFI_OUT_OF_RESOURCES;
302 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
303 Status = EFI_UNSUPPORTED;
304 } else {
305 Status = EFI_DEVICE_ERROR;
306 }
307
308 return Status;
309 }
310
311 /**
312 This function processes the results of changes in configuration.
313
314 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
315 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
316 format.
317 @param[out] Progress A pointer to a string filled in with the offset of
318 the most recent '&' before the first failing
319 name/value pair (or the beginning of the string if
320 the failure is in the first name/value pair) or
321 the terminating NULL if all was successful.
322
323 @retval EFI_SUCCESS The Results is processed successfully.
324 @retval EFI_INVALID_PARAMETER Configuration is NULL.
325 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
326 driver.
327
328 **/
329 EFI_STATUS
330 EFIAPI
331 Tcg2RouteConfig (
332 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
333 IN CONST EFI_STRING Configuration,
334 OUT EFI_STRING *Progress
335 )
336 {
337 if (Configuration == NULL || Progress == NULL) {
338 return EFI_INVALID_PARAMETER;
339 }
340
341 *Progress = Configuration;
342
343 return EFI_NOT_FOUND;
344 }
345
346 /**
347 Get HID string of TPM2 ACPI device object
348
349 @param[in] Hid Points to HID String Buffer.
350 @param[in] Size HID String size in bytes. Must >= TPM_HID_ACPI_SIZE
351
352 @return HID String get status.
353
354 **/
355 EFI_STATUS
356 GetTpm2HID(
357 CHAR8 *Hid,
358 UINTN Size
359 )
360 {
361 EFI_STATUS Status;
362 UINT32 ManufacturerID;
363 UINT32 FirmwareVersion1;
364 UINT32 FirmwareVersion2;
365 BOOLEAN PnpHID;
366
367 PnpHID = TRUE;
368
369 ZeroMem(Hid, Size);
370
371 //
372 // Get Manufacturer ID
373 //
374 Status = Tpm2GetCapabilityManufactureID(&ManufacturerID);
375 if (!EFI_ERROR(Status)) {
376 DEBUG((DEBUG_INFO, "TPM_PT_MANUFACTURER 0x%08x\n", ManufacturerID));
377 //
378 // ManufacturerID defined in TCG Vendor ID Registry
379 // may tailed with 0x00 or 0x20
380 //
381 if ((ManufacturerID >> 24) == 0x00 || ((ManufacturerID >> 24) == 0x20)) {
382 //
383 // HID containing PNP ID "NNN####"
384 // NNN is uppercase letter for Vendor ID specified by manufacturer
385 //
386 CopyMem(Hid, &ManufacturerID, 3);
387 } else {
388 //
389 // HID containing ACP ID "NNNN####"
390 // NNNN is uppercase letter for Vendor ID specified by manufacturer
391 //
392 CopyMem(Hid, &ManufacturerID, 4);
393 PnpHID = FALSE;
394 }
395 } else {
396 DEBUG ((DEBUG_ERROR, "Get TPM_PT_MANUFACTURER failed %x!\n", Status));
397 ASSERT(FALSE);
398 return Status;
399 }
400
401 Status = Tpm2GetCapabilityFirmwareVersion(&FirmwareVersion1, &FirmwareVersion2);
402 if (!EFI_ERROR(Status)) {
403 DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_1 0x%x\n", FirmwareVersion1));
404 DEBUG((DEBUG_INFO, "TPM_PT_FIRMWARE_VERSION_2 0x%x\n", FirmwareVersion2));
405 //
406 // #### is Firmware Version 1
407 //
408 if (PnpHID) {
409 AsciiSPrint(Hid + 3, TPM_HID_PNP_SIZE - 3, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));
410 } else {
411 AsciiSPrint(Hid + 4, TPM_HID_ACPI_SIZE - 4, "%02d%02d", ((FirmwareVersion1 & 0xFFFF0000) >> 16), (FirmwareVersion1 & 0x0000FFFF));
412 }
413
414 } else {
415 DEBUG ((DEBUG_ERROR, "Get TPM_PT_FIRMWARE_VERSION_X failed %x!\n", Status));
416 ASSERT(FALSE);
417 return Status;
418 }
419
420 return EFI_SUCCESS;
421 }
422
423 /**
424 This function processes the results of changes in configuration
425 for TCG2 version information.
426
427 @param[in] Action Specifies the type of action taken by the browser.
428 ASSERT if the Action is not EFI_BROWSER_ACTION_SUBMITTED.
429 @param[in] QuestionId A unique value which is sent to the original
430 exporting driver so that it can identify the type
431 of data to expect.
432 @param[in] Type The type of value for the question.
433 @param[in] Value A pointer to the data being sent to the original
434 exporting driver.
435
436 @retval EFI_SUCCESS The callback successfully handled the action.
437
438 **/
439 EFI_STATUS
440 Tcg2VersionInfoCallback (
441 IN EFI_BROWSER_ACTION Action,
442 IN EFI_QUESTION_ID QuestionId,
443 IN UINT8 Type,
444 IN EFI_IFR_TYPE_VALUE *Value
445 )
446 {
447 EFI_INPUT_KEY Key;
448 UINT64 PcdTcg2PpiVersion;
449 UINT8 PcdTpm2AcpiTableRev;
450
451 ASSERT (Action == EFI_BROWSER_ACTION_SUBMITTED);
452
453 if (QuestionId == KEY_TCG2_PPI_VERSION) {
454 //
455 // Get the PCD value after EFI_BROWSER_ACTION_SUBMITTED,
456 // the SetVariable to TCG2_VERSION_NAME should have been done.
457 // If the PCD value is not equal to the value set to variable,
458 // the PCD is not DynamicHii type and does not map to the setup option.
459 //
460 PcdTcg2PpiVersion = 0;
461 CopyMem (
462 &PcdTcg2PpiVersion,
463 PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer),
464 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer))
465 );
466 if (PcdTcg2PpiVersion != Value->u64) {
467 CreatePopUp (
468 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
469 &Key,
470 L"WARNING: PcdTcgPhysicalPresenceInterfaceVer is not DynamicHii type and does not map to this option!",
471 L"The version configuring by this setup option will not work!",
472 NULL
473 );
474 }
475 } else if (QuestionId == KEY_TPM2_ACPI_REVISION){
476 //
477 // Get the PCD value after EFI_BROWSER_ACTION_SUBMITTED,
478 // the SetVariable to TCG2_VERSION_NAME should have been done.
479 // If the PCD value is not equal to the value set to variable,
480 // the PCD is not DynamicHii type and does not map to the setup option.
481 //
482 PcdTpm2AcpiTableRev = PcdGet8 (PcdTpm2AcpiTableRev);
483
484 if (PcdTpm2AcpiTableRev != Value->u8) {
485 CreatePopUp (
486 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
487 &Key,
488 L"WARNING: PcdTpm2AcpiTableRev is not DynamicHii type and does not map to this option!",
489 L"The Revision configuring by this setup option will not work!",
490 NULL
491 );
492 }
493 }
494
495 return EFI_SUCCESS;
496 }
497
498 /**
499 This function processes the results of changes in configuration.
500
501 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
502 @param[in] Action Specifies the type of action taken by the browser.
503 @param[in] QuestionId A unique value which is sent to the original
504 exporting driver so that it can identify the type
505 of data to expect.
506 @param[in] Type The type of value for the question.
507 @param[in] Value A pointer to the data being sent to the original
508 exporting driver.
509 @param[out] ActionRequest On return, points to the action requested by the
510 callback function.
511
512 @retval EFI_SUCCESS The callback successfully handled the action.
513 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
514 variable and its data.
515 @retval EFI_DEVICE_ERROR The variable could not be saved.
516 @retval EFI_UNSUPPORTED The specified Action is not supported by the
517 callback.
518
519 **/
520 EFI_STATUS
521 EFIAPI
522 Tcg2Callback (
523 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
524 IN EFI_BROWSER_ACTION Action,
525 IN EFI_QUESTION_ID QuestionId,
526 IN UINT8 Type,
527 IN EFI_IFR_TYPE_VALUE *Value,
528 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
529 )
530 {
531 EFI_STATUS Status;
532 EFI_INPUT_KEY Key;
533 CHAR8 HidStr[16];
534 CHAR16 UnHidStr[16];
535 TCG2_CONFIG_PRIVATE_DATA *Private;
536
537 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
538 return EFI_INVALID_PARAMETER;
539 }
540
541 Private = TCG2_CONFIG_PRIVATE_DATA_FROM_THIS (This);
542
543 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
544 //
545 // Update TPM2 HID info
546 //
547 if (QuestionId == KEY_TPM_DEVICE) {
548 Status = GetTpm2HID(HidStr, 16);
549
550 if (EFI_ERROR(Status)) {
551 //
552 // Fail to get TPM2 HID
553 //
554 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_TPM2_ACPI_HID_CONTENT), L"Unknown", NULL);
555 } else {
556 AsciiStrToUnicodeStrS(HidStr, UnHidStr, 16);
557 HiiSetString (Private->HiiHandle, STRING_TOKEN (STR_TPM2_ACPI_HID_CONTENT), UnHidStr, NULL);
558 }
559 }
560 return EFI_SUCCESS;
561 }
562
563 if (Action == EFI_BROWSER_ACTION_CHANGING) {
564 if (QuestionId == KEY_TPM_DEVICE_INTERFACE) {
565 Status = SetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress), Value->u8);
566 if (EFI_ERROR (Status)) {
567 CreatePopUp (
568 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
569 &Key,
570 L"Error: Fail to set PTP interface!",
571 NULL
572 );
573 return EFI_DEVICE_ERROR;
574 }
575 }
576 }
577
578 if (Action == EFI_BROWSER_ACTION_CHANGED) {
579 if (QuestionId == KEY_TPM_DEVICE) {
580 return EFI_SUCCESS;
581 }
582 if (QuestionId == KEY_TPM2_OPERATION) {
583 return SaveTcg2PpRequest (Value->u8);
584 }
585 if (QuestionId == KEY_TPM2_OPERATION_PARAMETER) {
586 return SaveTcg2PpRequestParameter (Value->u32);
587 }
588 if ((QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {
589 return SaveTcg2PCRBanksRequest (QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0, Value->b);
590 }
591 }
592
593 if (Action == EFI_BROWSER_ACTION_SUBMITTED) {
594 if (QuestionId == KEY_TCG2_PPI_VERSION || QuestionId == KEY_TPM2_ACPI_REVISION) {
595 return Tcg2VersionInfoCallback (Action, QuestionId, Type, Value);
596 }
597 }
598
599 return EFI_UNSUPPORTED;
600 }
601
602 /**
603 Append Buffer With TpmAlgHash.
604
605 @param[in] Buffer Buffer to be appended.
606 @param[in] BufferSize Size of buffer.
607 @param[in] TpmAlgHash TpmAlgHash.
608
609 **/
610 VOID
611 AppendBufferWithTpmAlgHash (
612 IN UINT16 *Buffer,
613 IN UINTN BufferSize,
614 IN UINT32 TpmAlgHash
615 )
616 {
617 switch (TpmAlgHash) {
618 case TPM_ALG_SHA1:
619 if (Buffer[0] != 0) {
620 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
621 }
622 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1");
623 break;
624 case TPM_ALG_SHA256:
625 if (Buffer[0] != 0) {
626 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
627 }
628 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256");
629 break;
630 case TPM_ALG_SHA384:
631 if (Buffer[0] != 0) {
632 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
633 }
634 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384");
635 break;
636 case TPM_ALG_SHA512:
637 if (Buffer[0] != 0) {
638 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
639 }
640 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512");
641 break;
642 case TPM_ALG_SM3_256:
643 if (Buffer[0] != 0) {
644 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
645 }
646 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256");
647 break;
648 }
649 }
650
651 /**
652 Fill Buffer With BootHashAlg.
653
654 @param[in] Buffer Buffer to be filled.
655 @param[in] BufferSize Size of buffer.
656 @param[in] BootHashAlg BootHashAlg.
657
658 **/
659 VOID
660 FillBufferWithBootHashAlg (
661 IN UINT16 *Buffer,
662 IN UINTN BufferSize,
663 IN UINT32 BootHashAlg
664 )
665 {
666 Buffer[0] = 0;
667 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
668 if (Buffer[0] != 0) {
669 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
670 }
671 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1");
672 }
673 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
674 if (Buffer[0] != 0) {
675 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
676 }
677 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256");
678 }
679 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
680 if (Buffer[0] != 0) {
681 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
682 }
683 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384");
684 }
685 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
686 if (Buffer[0] != 0) {
687 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
688 }
689 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512");
690 }
691 if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
692 if (Buffer[0] != 0) {
693 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
694 }
695 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256");
696 }
697 }
698
699 /**
700 Set ConfigInfo according to TpmAlgHash.
701
702 @param[in,out] Tcg2ConfigInfo TCG2 config info.
703 @param[in] TpmAlgHash TpmAlgHash.
704
705 **/
706 VOID
707 SetConfigInfo (
708 IN OUT TCG2_CONFIGURATION_INFO *Tcg2ConfigInfo,
709 IN UINT32 TpmAlgHash
710 )
711 {
712 switch (TpmAlgHash) {
713 case TPM_ALG_SHA1:
714 Tcg2ConfigInfo->Sha1Supported = TRUE;
715 break;
716 case TPM_ALG_SHA256:
717 Tcg2ConfigInfo->Sha256Supported = TRUE;
718 break;
719 case TPM_ALG_SHA384:
720 Tcg2ConfigInfo->Sha384Supported = TRUE;
721 break;
722 case TPM_ALG_SHA512:
723 Tcg2ConfigInfo->Sha512Supported = TRUE;
724 break;
725 case TPM_ALG_SM3_256:
726 Tcg2ConfigInfo->Sm3Supported = TRUE;
727 break;
728 }
729 }
730
731 /**
732 Fill Buffer With TCG2EventLogFormat.
733
734 @param[in] Buffer Buffer to be filled.
735 @param[in] BufferSize Size of buffer.
736 @param[in] TCG2EventLogFormat TCG2EventLogFormat.
737
738 **/
739 VOID
740 FillBufferWithTCG2EventLogFormat (
741 IN UINT16 *Buffer,
742 IN UINTN BufferSize,
743 IN UINT32 TCG2EventLogFormat
744 )
745 {
746 Buffer[0] = 0;
747 if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) != 0) {
748 if (Buffer[0] != 0) {
749 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
750 }
751 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_1_2");
752 }
753 if ((TCG2EventLogFormat & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) != 0) {
754 if (Buffer[0] != 0) {
755 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
756 }
757 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"TCG_2");
758 }
759 if ((TCG2EventLogFormat & (~EFI_TCG2_EVENT_LOG_FORMAT_ALL)) != 0) {
760 if (Buffer[0] != 0) {
761 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L", ");
762 }
763 StrCatS (Buffer, BufferSize / sizeof (CHAR16), L"UNKNOWN");
764 }
765 }
766
767 /**
768 This function publish the TCG2 configuration Form for TPM device.
769
770 @param[in, out] PrivateData Points to TCG2 configuration private data.
771
772 @retval EFI_SUCCESS HII Form is installed for this network device.
773 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
774 @retval Others Other errors as indicated.
775
776 **/
777 EFI_STATUS
778 InstallTcg2ConfigForm (
779 IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData
780 )
781 {
782 EFI_STATUS Status;
783 EFI_HII_HANDLE HiiHandle;
784 EFI_HANDLE DriverHandle;
785 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
786 UINTN Index;
787 TPML_PCR_SELECTION Pcrs;
788 CHAR16 TempBuffer[1024];
789 TCG2_CONFIGURATION_INFO Tcg2ConfigInfo;
790 TPM2_PTP_INTERFACE_TYPE TpmDeviceInterfaceDetected;
791
792 DriverHandle = NULL;
793 ConfigAccess = &PrivateData->ConfigAccess;
794 Status = gBS->InstallMultipleProtocolInterfaces (
795 &DriverHandle,
796 &gEfiDevicePathProtocolGuid,
797 &mTcg2HiiVendorDevicePath,
798 &gEfiHiiConfigAccessProtocolGuid,
799 ConfigAccess,
800 NULL
801 );
802 if (EFI_ERROR (Status)) {
803 return Status;
804 }
805
806 PrivateData->DriverHandle = DriverHandle;
807
808 //
809 // Publish the HII package list
810 //
811 HiiHandle = HiiAddPackages (
812 &gTcg2ConfigFormSetGuid,
813 DriverHandle,
814 Tcg2ConfigDxeStrings,
815 Tcg2ConfigBin,
816 NULL
817 );
818 if (HiiHandle == NULL) {
819 gBS->UninstallMultipleProtocolInterfaces (
820 DriverHandle,
821 &gEfiDevicePathProtocolGuid,
822 &mTcg2HiiVendorDevicePath,
823 &gEfiHiiConfigAccessProtocolGuid,
824 ConfigAccess,
825 NULL
826 );
827
828 return EFI_OUT_OF_RESOURCES;
829 }
830
831 PrivateData->HiiHandle = HiiHandle;
832
833 //
834 // Update static data
835 //
836 switch (PrivateData->TpmDeviceDetected) {
837 case TPM_DEVICE_NULL:
838 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Not Found", NULL);
839 break;
840 case TPM_DEVICE_1_2:
841 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);
842 break;
843 case TPM_DEVICE_2_0_DTPM:
844 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"TPM 2.0", NULL);
845 break;
846 default:
847 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_STATE_CONTENT), L"Unknown", NULL);
848 break;
849 }
850
851 ZeroMem (&Tcg2ConfigInfo, sizeof(Tcg2ConfigInfo));
852 Status = Tpm2GetCapabilityPcrs (&Pcrs);
853 if (EFI_ERROR (Status)) {
854 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), L"[Unknown]", NULL);
855 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), L"[Unknown]", NULL);
856 } else {
857 TempBuffer[0] = 0;
858 for (Index = 0; Index < Pcrs.count; Index++) {
859 if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) {
860 AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);
861 }
862 }
863 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_ACTIVE_HASH_ALGO_CONTENT), TempBuffer, NULL);
864
865 TempBuffer[0] = 0;
866 for (Index = 0; Index < Pcrs.count; Index++) {
867 AppendBufferWithTpmAlgHash (TempBuffer, sizeof(TempBuffer), Pcrs.pcrSelections[Index].hash);
868 SetConfigInfo (&Tcg2ConfigInfo, Pcrs.pcrSelections[Index].hash);
869 }
870 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM2_SUPPORTED_HASH_ALGO_CONTENT), TempBuffer, NULL);
871 }
872
873 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PcdGet32 (PcdTcg2HashAlgorithmBitmap));
874 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_BIOS_HASH_ALGO_CONTENT), TempBuffer, NULL);
875
876 //
877 // Tcg2 Capability
878 //
879 FillBufferWithTCG2EventLogFormat (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.SupportedEventLogs);
880 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_SUPPORTED_EVENT_LOG_FORMAT_CONTENT), TempBuffer, NULL);
881
882 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.HashAlgorithmBitmap);
883 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_HASH_ALGO_BITMAP_CONTENT), TempBuffer, NULL);
884
885 UnicodeSPrint (TempBuffer, sizeof (TempBuffer), L"%d", PrivateData->ProtocolCapability.NumberOfPCRBanks);
886 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_NUMBER_OF_PCR_BANKS_CONTENT), TempBuffer, NULL);
887
888 FillBufferWithBootHashAlg (TempBuffer, sizeof(TempBuffer), PrivateData->ProtocolCapability.ActivePcrBanks);
889 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_ACTIVE_PCR_BANKS_CONTENT), TempBuffer, NULL);
890
891 //
892 // Update TPM device interface type
893 //
894 if (PrivateData->TpmDeviceDetected == TPM_DEVICE_2_0_DTPM) {
895 TpmDeviceInterfaceDetected = PcdGet8(PcdActiveTpmInterfaceType);
896 switch (TpmDeviceInterfaceDetected) {
897 case Tpm2PtpInterfaceTis:
898 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"TIS", NULL);
899 break;
900 case Tpm2PtpInterfaceFifo:
901 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP FIFO", NULL);
902 break;
903 case Tpm2PtpInterfaceCrb:
904 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"PTP CRB", NULL);
905 break;
906 default:
907 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_STATE_CONTENT), L"Unknown", NULL);
908 break;
909 }
910
911 Tcg2ConfigInfo.TpmDeviceInterfaceAttempt = TpmDeviceInterfaceDetected;
912 switch (TpmDeviceInterfaceDetected) {
913 case Tpm2PtpInterfaceTis:
914 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE;
915 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE;
916 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"TIS", NULL);
917 break;
918 case Tpm2PtpInterfaceFifo:
919 case Tpm2PtpInterfaceCrb:
920 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = IsPtpFifoSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));
921 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = IsPtpCrbSupported((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));
922 TempBuffer[0] = 0;
923 if (Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported) {
924 if (TempBuffer[0] != 0) {
925 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", ");
926 }
927 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP FIFO");
928 }
929 if (Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported) {
930 if (TempBuffer[0] != 0) {
931 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L", ");
932 }
933 StrCatS (TempBuffer, sizeof(TempBuffer) / sizeof (CHAR16), L"PTP CRB");
934 }
935 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), TempBuffer, NULL);
936 break;
937 default:
938 Tcg2ConfigInfo.TpmDeviceInterfacePtpFifoSupported = FALSE;
939 Tcg2ConfigInfo.TpmDeviceInterfacePtpCrbSupported = FALSE;
940 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_DEVICE_INTERFACE_CAPABILITY_CONTENT), L"Unknown", NULL);
941 break;
942 }
943 }
944
945 //
946 // Set ConfigInfo, to control the check box.
947 //
948 Status = gRT->SetVariable (
949 TCG2_STORAGE_INFO_NAME,
950 &gTcg2ConfigFormSetGuid,
951 EFI_VARIABLE_BOOTSERVICE_ACCESS,
952 sizeof(Tcg2ConfigInfo),
953 &Tcg2ConfigInfo
954 );
955 if (EFI_ERROR (Status)) {
956 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_INFO_NAME\n"));
957 }
958
959 return EFI_SUCCESS;
960 }
961
962 /**
963 This function removes TCG2 configuration Form.
964
965 @param[in, out] PrivateData Points to TCG2 configuration private data.
966
967 **/
968 VOID
969 UninstallTcg2ConfigForm (
970 IN OUT TCG2_CONFIG_PRIVATE_DATA *PrivateData
971 )
972 {
973 //
974 // Uninstall HII package list
975 //
976 if (PrivateData->HiiHandle != NULL) {
977 HiiRemovePackages (PrivateData->HiiHandle);
978 PrivateData->HiiHandle = NULL;
979 }
980
981 //
982 // Uninstall HII Config Access Protocol
983 //
984 if (PrivateData->DriverHandle != NULL) {
985 gBS->UninstallMultipleProtocolInterfaces (
986 PrivateData->DriverHandle,
987 &gEfiDevicePathProtocolGuid,
988 &mTcg2HiiVendorDevicePath,
989 &gEfiHiiConfigAccessProtocolGuid,
990 &PrivateData->ConfigAccess,
991 NULL
992 );
993 PrivateData->DriverHandle = NULL;
994 }
995
996 FreePool (PrivateData);
997 }