• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   HII Config Access protocol implementation of TCG configuration module.
3 
4 Copyright (c) 2011 - 2016, 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 "TcgConfigImpl.h"
16 
17 CHAR16                          mTcgStorageName[] = L"TCG_CONFIGURATION";
18 
19 TCG_CONFIG_PRIVATE_DATA         mTcgConfigPrivateDateTemplate = {
20   TCG_CONFIG_PRIVATE_DATA_SIGNATURE,
21   {
22     TcgExtractConfig,
23     TcgRouteConfig,
24     TcgCallback
25   }
26 };
27 
28 HII_VENDOR_DEVICE_PATH          mTcgHiiVendorDevicePath = {
29   {
30     {
31       HARDWARE_DEVICE_PATH,
32       HW_VENDOR_DP,
33       {
34         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
35         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
36       }
37     },
38     TCG_CONFIG_FORM_SET_GUID
39   },
40   {
41     END_DEVICE_PATH_TYPE,
42     END_ENTIRE_DEVICE_PATH_SUBTYPE,
43     {
44       (UINT8) (END_DEVICE_PATH_LENGTH),
45       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
46     }
47   }
48 };
49 
50 /**
51   Get current state of TPM device.
52 
53   @param[in]   TcgProtocol          Point to EFI_TCG_PROTOCOL instance.
54   @param[out]  TpmEnable            Flag to indicate TPM is enabled or not.
55   @param[out]  TpmActivate          Flag to indicate TPM is activated or not.
56 
57   @retval EFI_SUCCESS               State is successfully returned.
58   @retval EFI_DEVICE_ERROR          Failed to get TPM response.
59   @retval Others                    Other errors as indicated.
60 
61 **/
62 EFI_STATUS
GetTpmState(IN EFI_TCG_PROTOCOL * TcgProtocol,OUT BOOLEAN * TpmEnable,OPTIONAL OUT BOOLEAN * TpmActivate OPTIONAL)63 GetTpmState (
64   IN  EFI_TCG_PROTOCOL          *TcgProtocol,
65   OUT BOOLEAN                   *TpmEnable,  OPTIONAL
66   OUT BOOLEAN                   *TpmActivate OPTIONAL
67   )
68 {
69   EFI_STATUS                    Status;
70   TPM_RSP_COMMAND_HDR           *TpmRsp;
71   UINT32                        TpmSendSize;
72   TPM_PERMANENT_FLAGS           *TpmPermanentFlags;
73   UINT8                         CmdBuf[64];
74 
75   ASSERT (TcgProtocol != NULL);
76 
77   //
78   // Get TPM Permanent flags (TpmEnable, TpmActivate)
79   //
80   if ((TpmEnable != NULL) || (TpmActivate != NULL)) {
81     TpmSendSize           = sizeof (TPM_RQU_COMMAND_HDR) + sizeof (UINT32) * 3;
82     *(UINT16*)&CmdBuf[0]  = SwapBytes16 (TPM_TAG_RQU_COMMAND);
83     *(UINT32*)&CmdBuf[2]  = SwapBytes32 (TpmSendSize);
84     *(UINT32*)&CmdBuf[6]  = SwapBytes32 (TPM_ORD_GetCapability);
85 
86     *(UINT32*)&CmdBuf[10] = SwapBytes32 (TPM_CAP_FLAG);
87     *(UINT32*)&CmdBuf[14] = SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT));
88     *(UINT32*)&CmdBuf[18] = SwapBytes32 (TPM_CAP_FLAG_PERMANENT);
89 
90     Status = TcgProtocol->PassThroughToTpm (
91                             TcgProtocol,
92                             TpmSendSize,
93                             CmdBuf,
94                             sizeof (CmdBuf),
95                             CmdBuf
96                             );
97     TpmRsp = (TPM_RSP_COMMAND_HDR *) &CmdBuf[0];
98     if (EFI_ERROR (Status) || (TpmRsp->tag != SwapBytes16 (TPM_TAG_RSP_COMMAND)) || (TpmRsp->returnCode != 0)) {
99       return EFI_DEVICE_ERROR;
100     }
101 
102     TpmPermanentFlags = (TPM_PERMANENT_FLAGS *) &CmdBuf[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];
103 
104     if (TpmEnable != NULL) {
105       *TpmEnable = (BOOLEAN) !TpmPermanentFlags->disable;
106     }
107 
108     if (TpmActivate != NULL) {
109       *TpmActivate = (BOOLEAN) !TpmPermanentFlags->deactivated;
110     }
111   }
112 
113   return EFI_SUCCESS;
114 }
115 
116 /**
117   This function allows a caller to extract the current configuration for one
118   or more named elements from the target driver.
119 
120   @param[in]   This              Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
121   @param[in]   Request           A null-terminated Unicode string in
122                                  <ConfigRequest> format.
123   @param[out]  Progress          On return, points to a character in the Request
124                                  string. Points to the string's null terminator if
125                                  request was successful. Points to the most recent
126                                  '&' before the first failing name/value pair (or
127                                  the beginning of the string if the failure is in
128                                  the first name/value pair) if the request was not
129                                  successful.
130   @param[out]  Results           A null-terminated Unicode string in
131                                  <ConfigAltResp> format which has all values filled
132                                  in for the names in the Request string. String to
133                                  be allocated by the called function.
134 
135   @retval EFI_SUCCESS            The Results is filled with the requested values.
136   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
137   @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
138   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
139                                  driver.
140 
141 **/
142 EFI_STATUS
143 EFIAPI
TcgExtractConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Request,OUT EFI_STRING * Progress,OUT EFI_STRING * Results)144 TcgExtractConfig (
145   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL        *This,
146   IN CONST EFI_STRING                            Request,
147        OUT EFI_STRING                            *Progress,
148        OUT EFI_STRING                            *Results
149   )
150 {
151   EFI_STATUS                 Status;
152   TCG_CONFIG_PRIVATE_DATA    *PrivateData;
153   EFI_STRING                 ConfigRequestHdr;
154   EFI_STRING                 ConfigRequest;
155   BOOLEAN                    AllocatedRequest;
156   UINTN                      Size;
157   BOOLEAN                    TpmEnable;
158   BOOLEAN                    TpmActivate;
159 
160   if (Progress == NULL || Results == NULL) {
161     return EFI_INVALID_PARAMETER;
162   }
163 
164   *Progress = Request;
165   if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTcgConfigFormSetGuid, mTcgStorageName)) {
166     return EFI_NOT_FOUND;
167   }
168 
169   ConfigRequestHdr = NULL;
170   ConfigRequest    = NULL;
171   AllocatedRequest = FALSE;
172   Size             = 0;
173 
174   PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);
175 
176   //
177   // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
178   //
179   PrivateData->Configuration->TpmOperation = PHYSICAL_PRESENCE_ENABLE;
180 
181   //
182   // Get current TPM state.
183   //
184   if (PrivateData->TcgProtocol != NULL) {
185     Status = GetTpmState (PrivateData->TcgProtocol, &TpmEnable, &TpmActivate);
186     if (EFI_ERROR (Status)) {
187       return Status;
188     }
189 
190     PrivateData->Configuration->TpmEnable   = TpmEnable;
191     PrivateData->Configuration->TpmActivate = TpmActivate;
192   }
193 
194   ConfigRequest = Request;
195   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
196     //
197     // Request has no request element, construct full request string.
198     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
199     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
200     //
201     ConfigRequestHdr = HiiConstructConfigHdr (&gTcgConfigFormSetGuid, mTcgStorageName, PrivateData->DriverHandle);
202     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
203     ConfigRequest = AllocateZeroPool (Size);
204     ASSERT (ConfigRequest != NULL);
205     AllocatedRequest = TRUE;
206     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, sizeof (TCG_CONFIGURATION));
207     FreePool (ConfigRequestHdr);
208   }
209 
210   Status = gHiiConfigRouting->BlockToConfig (
211                                 gHiiConfigRouting,
212                                 ConfigRequest,
213                                 (UINT8 *) PrivateData->Configuration,
214                                 sizeof (TCG_CONFIGURATION),
215                                 Results,
216                                 Progress
217                                 );
218   //
219   // Free the allocated config request string.
220   //
221   if (AllocatedRequest) {
222     FreePool (ConfigRequest);
223   }
224   //
225   // Set Progress string to the original request string.
226   //
227   if (Request == NULL) {
228     *Progress = NULL;
229   } else if (StrStr (Request, L"OFFSET") == NULL) {
230     *Progress = Request + StrLen (Request);
231   }
232 
233   return Status;
234 }
235 
236 /**
237   This function processes the results of changes in configuration.
238 
239   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
240   @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>
241                                  format.
242   @param[out] Progress           A pointer to a string filled in with the offset of
243                                  the most recent '&' before the first failing
244                                  name/value pair (or the beginning of the string if
245                                  the failure is in the first name/value pair) or
246                                  the terminating NULL if all was successful.
247 
248   @retval EFI_SUCCESS            The Results is processed successfully.
249   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
250   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
251                                  driver.
252 
253 **/
254 EFI_STATUS
255 EFIAPI
TcgRouteConfig(IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL * This,IN CONST EFI_STRING Configuration,OUT EFI_STRING * Progress)256 TcgRouteConfig (
257   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
258   IN CONST EFI_STRING                          Configuration,
259        OUT EFI_STRING                          *Progress
260   )
261 {
262   EFI_STATUS                       Status;
263   UINTN                            BufferSize;
264   TCG_CONFIGURATION                TcgConfiguration;
265 
266   if (Configuration == NULL || Progress == NULL) {
267     return EFI_INVALID_PARAMETER;
268   }
269 
270   *Progress = Configuration;
271   if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {
272     return EFI_NOT_FOUND;
273   }
274 
275   //
276   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
277   //
278   BufferSize = sizeof (TCG_CONFIGURATION);
279   Status = gHiiConfigRouting->ConfigToBlock (
280                                 gHiiConfigRouting,
281                                 Configuration,
282                                 (UINT8 *) &TcgConfiguration,
283                                 &BufferSize,
284                                 Progress
285                                 );
286   if (EFI_ERROR (Status)) {
287     return Status;
288   }
289 
290   return EFI_SUCCESS;
291 }
292 
293 /**
294   Save TPM request to variable space.
295 
296   @param[in] PpRequest             Physical Presence request command.
297 
298   @retval    EFI_SUCCESS           The operation is finished successfully.
299   @retval    Others                Other errors as indicated.
300 
301 **/
302 EFI_STATUS
SavePpRequest(IN UINT8 PpRequest)303 SavePpRequest (
304   IN UINT8                         PpRequest
305   )
306 {
307   EFI_STATUS                       Status;
308   UINTN                            DataSize;
309   EFI_PHYSICAL_PRESENCE            PpData;
310 
311   //
312   // Save TPM command to variable.
313   //
314   DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
315   Status = gRT->GetVariable (
316                   PHYSICAL_PRESENCE_VARIABLE,
317                   &gEfiPhysicalPresenceGuid,
318                   NULL,
319                   &DataSize,
320                   &PpData
321                   );
322   if (EFI_ERROR (Status)) {
323     return Status;
324   }
325 
326   PpData.PPRequest = PpRequest;
327   Status = gRT->SetVariable (
328                   PHYSICAL_PRESENCE_VARIABLE,
329                   &gEfiPhysicalPresenceGuid,
330                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
331                   DataSize,
332                   &PpData
333                   );
334   if (EFI_ERROR(Status)) {
335     return Status;
336   }
337 
338   return EFI_SUCCESS;
339 }
340 
341 /**
342   This function processes the results of changes in configuration.
343 
344   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
345   @param[in]  Action             Specifies the type of action taken by the browser.
346   @param[in]  QuestionId         A unique value which is sent to the original
347                                  exporting driver so that it can identify the type
348                                  of data to expect.
349   @param[in]  Type               The type of value for the question.
350   @param[in]  Value              A pointer to the data being sent to the original
351                                  exporting driver.
352   @param[out] ActionRequest      On return, points to the action requested by the
353                                  callback function.
354 
355   @retval EFI_SUCCESS            The callback successfully handled the action.
356   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
357                                  variable and its data.
358   @retval EFI_DEVICE_ERROR       The variable could not be saved.
359   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
360                                  callback.
361 
362 **/
363 EFI_STATUS
364 EFIAPI
TcgCallback(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)365 TcgCallback (
366   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
367   IN     EFI_BROWSER_ACTION                    Action,
368   IN     EFI_QUESTION_ID                       QuestionId,
369   IN     UINT8                                 Type,
370   IN     EFI_IFR_TYPE_VALUE                    *Value,
371      OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
372   )
373 {
374   TCG_CONFIG_PRIVATE_DATA    *PrivateData;
375   CHAR16                     State[32];
376 
377   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
378     return EFI_INVALID_PARAMETER;
379   }
380 
381   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
382     if (QuestionId == KEY_TPM_ACTION) {
383 
384       PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);
385       UnicodeSPrint (
386         State,
387         sizeof (State),
388         L"%s, and %s",
389         PrivateData->Configuration->TpmEnable   ? L"Enabled"   : L"Disabled",
390         PrivateData->Configuration->TpmActivate ? L"Activated" : L"Deactivated"
391         );
392       HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM_STATE_CONTENT), State, NULL);
393     }
394     return EFI_SUCCESS;
395   }
396 
397   if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {
398     return EFI_UNSUPPORTED;
399   }
400 
401   SavePpRequest (Value->u8);
402   *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
403 
404   return EFI_SUCCESS;
405 }
406 
407 /**
408   This function publish the TCG configuration Form for TPM device.
409 
410   @param[in, out]  PrivateData   Points to TCG configuration private data.
411 
412   @retval EFI_SUCCESS            HII Form is installed for this network device.
413   @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.
414   @retval Others                 Other errors as indicated.
415 
416 **/
417 EFI_STATUS
InstallTcgConfigForm(IN OUT TCG_CONFIG_PRIVATE_DATA * PrivateData)418 InstallTcgConfigForm (
419   IN OUT TCG_CONFIG_PRIVATE_DATA  *PrivateData
420   )
421 {
422   EFI_STATUS                      Status;
423   EFI_HII_HANDLE                  HiiHandle;
424   EFI_HANDLE                      DriverHandle;
425   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
426 
427   DriverHandle = NULL;
428   ConfigAccess = &PrivateData->ConfigAccess;
429   Status = gBS->InstallMultipleProtocolInterfaces (
430                   &DriverHandle,
431                   &gEfiDevicePathProtocolGuid,
432                   &mTcgHiiVendorDevicePath,
433                   &gEfiHiiConfigAccessProtocolGuid,
434                   ConfigAccess,
435                   NULL
436                   );
437   if (EFI_ERROR (Status)) {
438     return Status;
439   }
440 
441   PrivateData->DriverHandle = DriverHandle;
442 
443   //
444   // Publish the HII package list
445   //
446   HiiHandle = HiiAddPackages (
447                 &gTcgConfigFormSetGuid,
448                 DriverHandle,
449                 TcgConfigDxeStrings,
450                 TcgConfigBin,
451                 NULL
452                 );
453   if (HiiHandle == NULL) {
454     gBS->UninstallMultipleProtocolInterfaces (
455            DriverHandle,
456            &gEfiDevicePathProtocolGuid,
457            &mTcgHiiVendorDevicePath,
458            &gEfiHiiConfigAccessProtocolGuid,
459            ConfigAccess,
460            NULL
461            );
462 
463     return EFI_OUT_OF_RESOURCES;
464   }
465 
466   PrivateData->HiiHandle = HiiHandle;
467 
468   return EFI_SUCCESS;
469 }
470 
471 /**
472   This function removes TCG configuration Form.
473 
474   @param[in, out]  PrivateData   Points to TCG configuration private data.
475 
476 **/
477 VOID
UninstallTcgConfigForm(IN OUT TCG_CONFIG_PRIVATE_DATA * PrivateData)478 UninstallTcgConfigForm (
479   IN OUT TCG_CONFIG_PRIVATE_DATA    *PrivateData
480   )
481 {
482   //
483   // Uninstall HII package list
484   //
485   if (PrivateData->HiiHandle != NULL) {
486     HiiRemovePackages (PrivateData->HiiHandle);
487     PrivateData->HiiHandle = NULL;
488   }
489 
490   //
491   // Uninstall HII Config Access Protocol
492   //
493   if (PrivateData->DriverHandle != NULL) {
494     gBS->UninstallMultipleProtocolInterfaces (
495            PrivateData->DriverHandle,
496            &gEfiDevicePathProtocolGuid,
497            &mTcgHiiVendorDevicePath,
498            &gEfiHiiConfigAccessProtocolGuid,
499            &PrivateData->ConfigAccess,
500            NULL
501            );
502     PrivateData->DriverHandle = NULL;
503   }
504 
505   if (PrivateData->Configuration != NULL) {
506     FreePool(PrivateData->Configuration);
507   }
508   FreePool (PrivateData);
509 }
510