1 /** @file
2   The module entry point for Tcg2 configuration module.
3 
4 Copyright (c) 2015, 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
UpdateDefaultPCRBanks(IN VOID * HiiPackage,IN UINTN HiiPackageSize,IN UINT32 PCRBanks)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
Tcg2ConfigDriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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   // Save to variable so platform driver can get it.
163   //
164   Status = gRT->SetVariable (
165                   TCG2_STORAGE_NAME,
166                   &gTcg2ConfigFormSetGuid,
167                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
168                   sizeof(Tcg2Configuration),
169                   &Tcg2Configuration
170                   );
171   if (EFI_ERROR (Status)) {
172     DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n"));
173   }
174 
175   //
176   // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
177   //
178   Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;
179   for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
180     if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
181       Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;
182       break;
183     }
184   }
185 
186   PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected;
187 
188   //
189   // Save to variable so platform driver can get it.
190   //
191   Status = gRT->SetVariable (
192                   TCG2_DEVICE_DETECTION_NAME,
193                   &gTcg2ConfigFormSetGuid,
194                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
195                   sizeof(Tcg2DeviceDetection),
196                   &Tcg2DeviceDetection
197                   );
198   if (EFI_ERROR (Status)) {
199     DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n"));
200     Status = gRT->SetVariable (
201                     TCG2_DEVICE_DETECTION_NAME,
202                     &gTcg2ConfigFormSetGuid,
203                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
204                     0,
205                     NULL
206                     );
207     ASSERT_EFI_ERROR (Status);
208   }
209 
210   //
211   // We should lock Tcg2DeviceDetection, because it contains information needed at S3.
212   //
213   Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
214   if (!EFI_ERROR (Status)) {
215     Status = VariableLockProtocol->RequestToLock (
216                                      VariableLockProtocol,
217                                      TCG2_DEVICE_DETECTION_NAME,
218                                      &gTcg2ConfigFormSetGuid
219                                      );
220     ASSERT_EFI_ERROR (Status);
221   }
222 
223   //
224   // Install Tcg2 configuration form
225   //
226   Status = InstallTcg2ConfigForm (PrivateData);
227   if (EFI_ERROR (Status)) {
228     goto ErrorExit;
229   }
230 
231   return EFI_SUCCESS;
232 
233 ErrorExit:
234   if (PrivateData != NULL) {
235     UninstallTcg2ConfigForm (PrivateData);
236   }
237 
238   return Status;
239 }
240 
241 /**
242   Unload the Tcg2 configuration form.
243 
244   @param[in]  ImageHandle         The driver's image handle.
245 
246   @retval     EFI_SUCCESS         The Tcg2 configuration form is unloaded.
247   @retval     Others              Failed to unload the form.
248 
249 **/
250 EFI_STATUS
251 EFIAPI
Tcg2ConfigDriverUnload(IN EFI_HANDLE ImageHandle)252 Tcg2ConfigDriverUnload (
253   IN EFI_HANDLE  ImageHandle
254   )
255 {
256   EFI_STATUS                  Status;
257   TCG2_CONFIG_PRIVATE_DATA    *PrivateData;
258 
259   Status = gBS->HandleProtocol (
260                   ImageHandle,
261                   &gEfiCallerIdGuid,
262                   (VOID **) &PrivateData
263                   );
264   if (EFI_ERROR (Status)) {
265     return Status;
266   }
267 
268   ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE);
269 
270   gBS->UninstallMultipleProtocolInterfaces (
271          &ImageHandle,
272          &gEfiCallerIdGuid,
273          PrivateData,
274          NULL
275          );
276 
277   UninstallTcg2ConfigForm (PrivateData);
278 
279   return EFI_SUCCESS;
280 }
281