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