Home | History | Annotate | Download | only in TcgConfigDxe
      1 /** @file
      2   HII Config Access protocol implementation of TCG configuration module.
      3 
      4 Copyright (c) 2011 - 2014, 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
     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
    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   UINTN                      BufferSize;
    153   TCG_CONFIGURATION          Configuration;
    154   TCG_CONFIG_PRIVATE_DATA    *PrivateData;
    155   EFI_STRING                 ConfigRequestHdr;
    156   EFI_STRING                 ConfigRequest;
    157   BOOLEAN                    AllocatedRequest;
    158   UINTN                      Size;
    159   BOOLEAN                    TpmEnable;
    160   BOOLEAN                    TpmActivate;
    161   CHAR16                     State[32];
    162 
    163   if (Progress == NULL || Results == NULL) {
    164     return EFI_INVALID_PARAMETER;
    165   }
    166 
    167   *Progress = Request;
    168   if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTcgConfigFormSetGuid, mTcgStorageName)) {
    169     return EFI_NOT_FOUND;
    170   }
    171 
    172   ConfigRequestHdr = NULL;
    173   ConfigRequest    = NULL;
    174   AllocatedRequest = FALSE;
    175   Size             = 0;
    176 
    177   PrivateData = TCG_CONFIG_PRIVATE_DATA_FROM_THIS (This);
    178 
    179   //
    180   // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
    181   //
    182   ZeroMem (&Configuration, sizeof (TCG_CONFIGURATION));
    183 
    184   Configuration.TpmOperation    = PHYSICAL_PRESENCE_ENABLE;
    185 
    186   //
    187   // Display current TPM state.
    188   //
    189   if (PrivateData->TcgProtocol != NULL) {
    190     Status = GetTpmState (PrivateData->TcgProtocol, &TpmEnable, &TpmActivate);
    191     if (EFI_ERROR (Status)) {
    192       return Status;
    193     }
    194 
    195     UnicodeSPrint (
    196       State,
    197       sizeof (State),
    198       L"%s, and %s",
    199       TpmEnable   ? L"Enabled"   : L"Disabled",
    200       TpmActivate ? L"Activated" : L"Deactivated"
    201       );
    202     Configuration.TpmEnable   = TpmEnable;
    203     Configuration.TpmActivate = TpmActivate;
    204 
    205     HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TPM_STATE_CONTENT), State, NULL);
    206   }
    207 
    208   BufferSize = sizeof (Configuration);
    209   ConfigRequest = Request;
    210   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    211     //
    212     // Request has no request element, construct full request string.
    213     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    214     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
    215     //
    216     ConfigRequestHdr = HiiConstructConfigHdr (&gTcgConfigFormSetGuid, mTcgStorageName, PrivateData->DriverHandle);
    217     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    218     ConfigRequest = AllocateZeroPool (Size);
    219     ASSERT (ConfigRequest != NULL);
    220     AllocatedRequest = TRUE;
    221     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
    222     FreePool (ConfigRequestHdr);
    223   }
    224 
    225   Status = gHiiConfigRouting->BlockToConfig (
    226                                 gHiiConfigRouting,
    227                                 ConfigRequest,
    228                                 (UINT8 *) &Configuration,
    229                                 BufferSize,
    230                                 Results,
    231                                 Progress
    232                                 );
    233   //
    234   // Free the allocated config request string.
    235   //
    236   if (AllocatedRequest) {
    237     FreePool (ConfigRequest);
    238   }
    239   //
    240   // Set Progress string to the original request string.
    241   //
    242   if (Request == NULL) {
    243     *Progress = NULL;
    244   } else if (StrStr (Request, L"OFFSET") == NULL) {
    245     *Progress = Request + StrLen (Request);
    246   }
    247 
    248   return Status;
    249 }
    250 
    251 /**
    252   This function processes the results of changes in configuration.
    253 
    254   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    255   @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>
    256                                  format.
    257   @param[out] Progress           A pointer to a string filled in with the offset of
    258                                  the most recent '&' before the first failing
    259                                  name/value pair (or the beginning of the string if
    260                                  the failure is in the first name/value pair) or
    261                                  the terminating NULL if all was successful.
    262 
    263   @retval EFI_SUCCESS            The Results is processed successfully.
    264   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
    265   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
    266                                  driver.
    267 
    268 **/
    269 EFI_STATUS
    270 EFIAPI
    271 TcgRouteConfig (
    272   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
    273   IN CONST EFI_STRING                          Configuration,
    274        OUT EFI_STRING                          *Progress
    275   )
    276 {
    277   EFI_STATUS                       Status;
    278   UINTN                            BufferSize;
    279   TCG_CONFIGURATION                TcgConfiguration;
    280 
    281   if (Configuration == NULL || Progress == NULL) {
    282     return EFI_INVALID_PARAMETER;
    283   }
    284 
    285   *Progress = Configuration;
    286   if (!HiiIsConfigHdrMatch (Configuration, &gTcgConfigFormSetGuid, mTcgStorageName)) {
    287     return EFI_NOT_FOUND;
    288   }
    289 
    290   //
    291   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
    292   //
    293   BufferSize = sizeof (TCG_CONFIGURATION);
    294   Status = gHiiConfigRouting->ConfigToBlock (
    295                                 gHiiConfigRouting,
    296                                 Configuration,
    297                                 (UINT8 *) &TcgConfiguration,
    298                                 &BufferSize,
    299                                 Progress
    300                                 );
    301   if (EFI_ERROR (Status)) {
    302     return Status;
    303   }
    304 
    305   return EFI_SUCCESS;
    306 }
    307 
    308 /**
    309   Save TPM request to variable space.
    310 
    311   @param[in] PpRequest             Physical Presence request command.
    312 
    313   @retval    EFI_SUCCESS           The operation is finished successfully.
    314   @retval    Others                Other errors as indicated.
    315 
    316 **/
    317 EFI_STATUS
    318 SavePpRequest (
    319   IN UINT8                         PpRequest
    320   )
    321 {
    322   EFI_STATUS                       Status;
    323   UINTN                            DataSize;
    324   EFI_PHYSICAL_PRESENCE            PpData;
    325 
    326   //
    327   // Save TPM command to variable.
    328   //
    329   DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
    330   Status = gRT->GetVariable (
    331                   PHYSICAL_PRESENCE_VARIABLE,
    332                   &gEfiPhysicalPresenceGuid,
    333                   NULL,
    334                   &DataSize,
    335                   &PpData
    336                   );
    337   if (EFI_ERROR (Status)) {
    338     return Status;
    339   }
    340 
    341   PpData.PPRequest = PpRequest;
    342   Status = gRT->SetVariable (
    343                   PHYSICAL_PRESENCE_VARIABLE,
    344                   &gEfiPhysicalPresenceGuid,
    345                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    346                   DataSize,
    347                   &PpData
    348                   );
    349   if (EFI_ERROR(Status)) {
    350     return Status;
    351   }
    352 
    353   return EFI_SUCCESS;
    354 }
    355 
    356 /**
    357   This function processes the results of changes in configuration.
    358 
    359   @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    360   @param[in]  Action             Specifies the type of action taken by the browser.
    361   @param[in]  QuestionId         A unique value which is sent to the original
    362                                  exporting driver so that it can identify the type
    363                                  of data to expect.
    364   @param[in]  Type               The type of value for the question.
    365   @param[in]  Value              A pointer to the data being sent to the original
    366                                  exporting driver.
    367   @param[out] ActionRequest      On return, points to the action requested by the
    368                                  callback function.
    369 
    370   @retval EFI_SUCCESS            The callback successfully handled the action.
    371   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
    372                                  variable and its data.
    373   @retval EFI_DEVICE_ERROR       The variable could not be saved.
    374   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
    375                                  callback.
    376 
    377 **/
    378 EFI_STATUS
    379 EFIAPI
    380 TcgCallback (
    381   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL      *This,
    382   IN     EFI_BROWSER_ACTION                    Action,
    383   IN     EFI_QUESTION_ID                       QuestionId,
    384   IN     UINT8                                 Type,
    385   IN     EFI_IFR_TYPE_VALUE                    *Value,
    386      OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
    387   )
    388 {
    389   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
    390     return EFI_INVALID_PARAMETER;
    391   }
    392 
    393   if ((Action != EFI_BROWSER_ACTION_CHANGED) || (QuestionId != KEY_TPM_ACTION)) {
    394     return EFI_UNSUPPORTED;
    395   }
    396 
    397   SavePpRequest (Value->u8);
    398   *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
    399 
    400   return EFI_SUCCESS;
    401 }
    402 
    403 /**
    404   This function publish the TCG configuration Form for TPM device.
    405 
    406   @param[in, out]  PrivateData   Points to TCG configuration private data.
    407 
    408   @retval EFI_SUCCESS            HII Form is installed for this network device.
    409   @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.
    410   @retval Others                 Other errors as indicated.
    411 
    412 **/
    413 EFI_STATUS
    414 InstallTcgConfigForm (
    415   IN OUT TCG_CONFIG_PRIVATE_DATA  *PrivateData
    416   )
    417 {
    418   EFI_STATUS                      Status;
    419   EFI_HII_HANDLE                  HiiHandle;
    420   EFI_HANDLE                      DriverHandle;
    421   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
    422 
    423   DriverHandle = NULL;
    424   ConfigAccess = &PrivateData->ConfigAccess;
    425   Status = gBS->InstallMultipleProtocolInterfaces (
    426                   &DriverHandle,
    427                   &gEfiDevicePathProtocolGuid,
    428                   &mTcgHiiVendorDevicePath,
    429                   &gEfiHiiConfigAccessProtocolGuid,
    430                   ConfigAccess,
    431                   NULL
    432                   );
    433   if (EFI_ERROR (Status)) {
    434     return Status;
    435   }
    436 
    437   PrivateData->DriverHandle = DriverHandle;
    438 
    439   //
    440   // Publish the HII package list
    441   //
    442   HiiHandle = HiiAddPackages (
    443                 &gTcgConfigFormSetGuid,
    444                 DriverHandle,
    445                 TcgConfigDxeStrings,
    446                 TcgConfigBin,
    447                 NULL
    448                 );
    449   if (HiiHandle == NULL) {
    450     gBS->UninstallMultipleProtocolInterfaces (
    451            DriverHandle,
    452            &gEfiDevicePathProtocolGuid,
    453            &mTcgHiiVendorDevicePath,
    454            &gEfiHiiConfigAccessProtocolGuid,
    455            ConfigAccess,
    456            NULL
    457            );
    458 
    459     return EFI_OUT_OF_RESOURCES;
    460   }
    461 
    462   PrivateData->HiiHandle = HiiHandle;
    463 
    464   return EFI_SUCCESS;
    465 }
    466 
    467 /**
    468   This function removes TCG configuration Form.
    469 
    470   @param[in, out]  PrivateData   Points to TCG configuration private data.
    471 
    472 **/
    473 VOID
    474 UninstallTcgConfigForm (
    475   IN OUT TCG_CONFIG_PRIVATE_DATA    *PrivateData
    476   )
    477 {
    478   //
    479   // Uninstall HII package list
    480   //
    481   if (PrivateData->HiiHandle != NULL) {
    482     HiiRemovePackages (PrivateData->HiiHandle);
    483     PrivateData->HiiHandle = NULL;
    484   }
    485 
    486   //
    487   // Uninstall HII Config Access Protocol
    488   //
    489   if (PrivateData->DriverHandle != NULL) {
    490     gBS->UninstallMultipleProtocolInterfaces (
    491            PrivateData->DriverHandle,
    492            &gEfiDevicePathProtocolGuid,
    493            &mTcgHiiVendorDevicePath,
    494            &gEfiHiiConfigAccessProtocolGuid,
    495            &PrivateData->ConfigAccess,
    496            NULL
    497            );
    498     PrivateData->DriverHandle = NULL;
    499   }
    500 
    501   FreePool (PrivateData);
    502 }
    503