Home | History | Annotate | Download | only in Tcg2Config
      1 /** @file
      2   The module entry point for Tcg2 configuration module.
      3 
      4 Copyright (c) 2015 - 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 "Tcg2ConfigImpl.h"
     16 
     17 extern TPM_INSTANCE_ID  mTpmInstanceId[TPM_DEVICE_MAX + 1];
     18 
     19 /**
     20   Update default PCR banks data.
     21 
     22   @param[in]  HiiPackage        HII Package.
     23   @param[in]  HiiPackageSize    HII Package size.
     24   @param[in]  PCRBanks          PCR Banks data.
     25 
     26 **/
     27 VOID
     28 UpdateDefaultPCRBanks (
     29   IN VOID                           *HiiPackage,
     30   IN UINTN                          HiiPackageSize,
     31   IN UINT32                         PCRBanks
     32   )
     33 {
     34   EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;
     35   EFI_IFR_OP_HEADER             *IfrOpCodeHeader;
     36   EFI_IFR_CHECKBOX              *IfrCheckBox;
     37   EFI_IFR_DEFAULT               *IfrDefault;
     38 
     39   HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiPackage;
     40 
     41   switch (HiiPackageHeader->Type) {
     42   case EFI_HII_PACKAGE_FORMS:
     43     IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)(HiiPackageHeader + 1);
     44     while ((UINTN)IfrOpCodeHeader < (UINTN)HiiPackageHeader + HiiPackageHeader->Length) {
     45       switch (IfrOpCodeHeader->OpCode) {
     46       case EFI_IFR_CHECKBOX_OP:
     47         IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpCodeHeader;
     48         if ((IfrCheckBox->Question.QuestionId >= KEY_TPM2_PCR_BANKS_REQUEST_0) && (IfrCheckBox->Question.QuestionId <= KEY_TPM2_PCR_BANKS_REQUEST_4)) {
     49           IfrDefault = (EFI_IFR_DEFAULT *)(IfrCheckBox + 1);
     50           ASSERT (IfrDefault->Header.OpCode == EFI_IFR_DEFAULT_OP);
     51           ASSERT (IfrDefault->Type == EFI_IFR_TYPE_BOOLEAN);
     52           IfrDefault->Value.b = (BOOLEAN)((PCRBanks >> (IfrCheckBox->Question.QuestionId - KEY_TPM2_PCR_BANKS_REQUEST_0)) & 0x1);
     53         }
     54         break;
     55       }
     56       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *)((UINTN)IfrOpCodeHeader + IfrOpCodeHeader->Length);
     57     }
     58     break;
     59   }
     60   return ;
     61 }
     62 
     63 /**
     64   The entry point for Tcg2 configuration driver.
     65 
     66   @param[in]  ImageHandle        The image handle of the driver.
     67   @param[in]  SystemTable        The system table.
     68 
     69   @retval EFI_ALREADY_STARTED    The driver already exists in system.
     70   @retval EFI_OUT_OF_RESOURCES   Fail to execute entry point due to lack of resources.
     71   @retval EFI_SUCCES             All the related protocols are installed on the driver.
     72   @retval Others                 Fail to install protocols as indicated.
     73 
     74 **/
     75 EFI_STATUS
     76 EFIAPI
     77 Tcg2ConfigDriverEntryPoint (
     78   IN EFI_HANDLE          ImageHandle,
     79   IN EFI_SYSTEM_TABLE    *SystemTable
     80   )
     81 {
     82   EFI_STATUS                    Status;
     83   TCG2_CONFIG_PRIVATE_DATA      *PrivateData;
     84   TCG2_CONFIGURATION            Tcg2Configuration;
     85   TCG2_DEVICE_DETECTION         Tcg2DeviceDetection;
     86   UINTN                         Index;
     87   UINTN                         DataSize;
     88   EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLockProtocol;
     89   UINT32                        CurrentActivePCRBanks;
     90 
     91   Status = gBS->OpenProtocol (
     92                   ImageHandle,
     93                   &gEfiCallerIdGuid,
     94                   NULL,
     95                   ImageHandle,
     96                   ImageHandle,
     97                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
     98                   );
     99   if (!EFI_ERROR (Status)) {
    100     return EFI_ALREADY_STARTED;
    101   }
    102 
    103   //
    104   // Create a private data structure.
    105   //
    106   PrivateData = AllocateCopyPool (sizeof (TCG2_CONFIG_PRIVATE_DATA), &mTcg2ConfigPrivateDateTemplate);
    107   ASSERT (PrivateData != NULL);
    108   mTcg2ConfigPrivateDate = PrivateData;
    109   //
    110   // Install private GUID.
    111   //
    112   Status = gBS->InstallMultipleProtocolInterfaces (
    113                   &ImageHandle,
    114                   &gEfiCallerIdGuid,
    115                   PrivateData,
    116                   NULL
    117                   );
    118   ASSERT_EFI_ERROR (Status);
    119 
    120   Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &PrivateData->Tcg2Protocol);
    121   ASSERT_EFI_ERROR (Status);
    122 
    123   PrivateData->ProtocolCapability.Size = sizeof(PrivateData->ProtocolCapability);
    124   Status = PrivateData->Tcg2Protocol->GetCapability (
    125                                         PrivateData->Tcg2Protocol,
    126                                         &PrivateData->ProtocolCapability
    127                                         );
    128   ASSERT_EFI_ERROR (Status);
    129 
    130   DataSize = sizeof(Tcg2Configuration);
    131   Status = gRT->GetVariable (
    132                   TCG2_STORAGE_NAME,
    133                   &gTcg2ConfigFormSetGuid,
    134                   NULL,
    135                   &DataSize,
    136                   &Tcg2Configuration
    137                   );
    138   if (EFI_ERROR (Status)) {
    139     //
    140     // Variable not ready, set default value
    141     //
    142     Tcg2Configuration.TpmDevice           = TPM_DEVICE_DEFAULT;
    143   }
    144 
    145   //
    146   // Validation
    147   //
    148   if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {
    149     Tcg2Configuration.TpmDevice   = TPM_DEVICE_DEFAULT;
    150   }
    151 
    152   //
    153   // Set value for Tcg2CurrentActivePCRBanks
    154   // Search Tcg2ConfigBin[] and update default value there
    155   //
    156   Status = PrivateData->Tcg2Protocol->GetActivePcrBanks (PrivateData->Tcg2Protocol, &CurrentActivePCRBanks);
    157   ASSERT_EFI_ERROR (Status);
    158   PrivateData->PCRBanksDesired = CurrentActivePCRBanks;
    159   UpdateDefaultPCRBanks (Tcg2ConfigBin + sizeof(UINT32), ReadUnaligned32((UINT32 *)Tcg2ConfigBin) - sizeof(UINT32), CurrentActivePCRBanks);
    160 
    161   //
    162   // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
    163   //
    164   Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;
    165   for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
    166     if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
    167       Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;
    168       break;
    169     }
    170   }
    171 
    172   PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected;
    173   Tcg2Configuration.TpmDevice = Tcg2DeviceDetection.TpmDeviceDetected;
    174 
    175   //
    176   // Save to variable so platform driver can get it.
    177   //
    178   Status = gRT->SetVariable (
    179                   TCG2_DEVICE_DETECTION_NAME,
    180                   &gTcg2ConfigFormSetGuid,
    181                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
    182                   sizeof(Tcg2DeviceDetection),
    183                   &Tcg2DeviceDetection
    184                   );
    185   if (EFI_ERROR (Status)) {
    186     DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n"));
    187     Status = gRT->SetVariable (
    188                     TCG2_DEVICE_DETECTION_NAME,
    189                     &gTcg2ConfigFormSetGuid,
    190                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
    191                     0,
    192                     NULL
    193                     );
    194     ASSERT_EFI_ERROR (Status);
    195   }
    196 
    197   //
    198   // Save to variable so platform driver can get it.
    199   //
    200   Status = gRT->SetVariable (
    201                   TCG2_STORAGE_NAME,
    202                   &gTcg2ConfigFormSetGuid,
    203                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
    204                   sizeof(Tcg2Configuration),
    205                   &Tcg2Configuration
    206                   );
    207   if (EFI_ERROR (Status)) {
    208     DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n"));
    209   }
    210 
    211   //
    212   // We should lock Tcg2DeviceDetection, because it contains information needed at S3.
    213   //
    214   Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
    215   if (!EFI_ERROR (Status)) {
    216     Status = VariableLockProtocol->RequestToLock (
    217                                      VariableLockProtocol,
    218                                      TCG2_DEVICE_DETECTION_NAME,
    219                                      &gTcg2ConfigFormSetGuid
    220                                      );
    221     ASSERT_EFI_ERROR (Status);
    222   }
    223 
    224   //
    225   // Install Tcg2 configuration form
    226   //
    227   Status = InstallTcg2ConfigForm (PrivateData);
    228   if (EFI_ERROR (Status)) {
    229     goto ErrorExit;
    230   }
    231 
    232   return EFI_SUCCESS;
    233 
    234 ErrorExit:
    235   if (PrivateData != NULL) {
    236     UninstallTcg2ConfigForm (PrivateData);
    237   }
    238 
    239   return Status;
    240 }
    241 
    242 /**
    243   Unload the Tcg2 configuration form.
    244 
    245   @param[in]  ImageHandle         The driver's image handle.
    246 
    247   @retval     EFI_SUCCESS         The Tcg2 configuration form is unloaded.
    248   @retval     Others              Failed to unload the form.
    249 
    250 **/
    251 EFI_STATUS
    252 EFIAPI
    253 Tcg2ConfigDriverUnload (
    254   IN EFI_HANDLE  ImageHandle
    255   )
    256 {
    257   EFI_STATUS                  Status;
    258   TCG2_CONFIG_PRIVATE_DATA    *PrivateData;
    259 
    260   Status = gBS->HandleProtocol (
    261                   ImageHandle,
    262                   &gEfiCallerIdGuid,
    263                   (VOID **) &PrivateData
    264                   );
    265   if (EFI_ERROR (Status)) {
    266     return Status;
    267   }
    268 
    269   ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE);
    270 
    271   gBS->UninstallMultipleProtocolInterfaces (
    272          &ImageHandle,
    273          &gEfiCallerIdGuid,
    274          PrivateData,
    275          NULL
    276          );
    277 
    278   UninstallTcg2ConfigForm (PrivateData);
    279 
    280   return EFI_SUCCESS;
    281 }
    282