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