Home | History | Annotate | Download | only in TcgConfigDxe
      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
     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   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
    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
    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
    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
    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
    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