]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDriver.c
SecurityPkg Tcg2ConfigDxe: Add setup option to configure PPI version
[mirror_edk2.git] / SecurityPkg / Tcg / Tcg2Config / Tcg2ConfigDriver.c
1 /** @file
2 The module entry point for Tcg2 configuration module.
3
4 Copyright (c) 2015 - 2017, 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 Initialize TCG2 version information.
65
66 This function will initialize efi varstore configuration data for
67 TCG2_VERSION_NAME variable, check the value of related PCD with
68 the variable value and set string for the version state content
69 according to the PCD value.
70
71 @param[in] PrivateData Points to TCG2 configuration private data.
72
73 **/
74 VOID
75 InitializeTcg2VersionInfo (
76 IN TCG2_CONFIG_PRIVATE_DATA *PrivateData
77 )
78 {
79 EFI_STATUS Status;
80 EFI_STRING ConfigRequestHdr;
81 BOOLEAN ActionFlag;
82 TCG2_VERSION Tcg2Version;
83 UINTN DataSize;
84 UINT64 PcdTcg2PpiVersion;
85
86 //
87 // Get the PCD value before initializing efi varstore configuration data.
88 //
89 PcdTcg2PpiVersion = 0;
90 CopyMem (
91 &PcdTcg2PpiVersion,
92 PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer),
93 AsciiStrSize (PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer))
94 );
95
96 //
97 // Initialize efi varstore configuration data.
98 //
99 ZeroMem (&Tcg2Version, sizeof (Tcg2Version));
100 ConfigRequestHdr = HiiConstructConfigHdr (
101 &gTcg2ConfigFormSetGuid,
102 TCG2_VERSION_NAME,
103 PrivateData->DriverHandle
104 );
105 ASSERT (ConfigRequestHdr != NULL);
106 DataSize = sizeof (Tcg2Version);
107 Status = gRT->GetVariable (
108 TCG2_VERSION_NAME,
109 &gTcg2ConfigFormSetGuid,
110 NULL,
111 &DataSize,
112 &Tcg2Version
113 );
114 if (!EFI_ERROR (Status)) {
115 //
116 // EFI variable does exist and validate current setting.
117 //
118 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
119 if (!ActionFlag) {
120 //
121 // Current configuration is invalid, reset to defaults.
122 //
123 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
124 ASSERT (ActionFlag);
125 //
126 // Get the default values from variable.
127 //
128 DataSize = sizeof (Tcg2Version);
129 Status = gRT->GetVariable (
130 TCG2_VERSION_NAME,
131 &gTcg2ConfigFormSetGuid,
132 NULL,
133 &DataSize,
134 &Tcg2Version
135 );
136 ASSERT_EFI_ERROR (Status);
137 }
138 } else {
139 //
140 // EFI variable doesn't exist.
141 //
142
143 //
144 // Store zero data Buffer Storage to EFI variable.
145 //
146 Status = gRT->SetVariable (
147 TCG2_VERSION_NAME,
148 &gTcg2ConfigFormSetGuid,
149 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
150 sizeof (Tcg2Version),
151 &Tcg2Version
152 );
153 if (EFI_ERROR (Status)) {
154 DEBUG ((DEBUG_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_VERSION_NAME\n"));
155 return;
156 } else {
157 //
158 // Build this variable based on default values stored in IFR.
159 //
160 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
161 ASSERT (ActionFlag);
162 //
163 // Get the default values from variable.
164 //
165 DataSize = sizeof (Tcg2Version);
166 Status = gRT->GetVariable (
167 TCG2_VERSION_NAME,
168 &gTcg2ConfigFormSetGuid,
169 NULL,
170 &DataSize,
171 &Tcg2Version
172 );
173 ASSERT_EFI_ERROR (Status);
174 if (PcdTcg2PpiVersion != Tcg2Version.PpiVersion) {
175 DEBUG ((DEBUG_WARN, "WARNING: PcdTcgPhysicalPresenceInterfaceVer default value is not same with the default value in VFR\n"));
176 DEBUG ((DEBUG_WARN, "WARNING: The default value in VFR has be chosen\n"));
177 }
178 }
179 }
180 FreePool (ConfigRequestHdr);
181
182 //
183 // Get the PCD value again.
184 // If the PCD value is not equal to the value in variable,
185 // the PCD is not DynamicHii type and maps to the setup option.
186 //
187 PcdTcg2PpiVersion = 0;
188 CopyMem (
189 &PcdTcg2PpiVersion,
190 PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer),
191 AsciiStrSize (PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer))
192 );
193 if (PcdTcg2PpiVersion != Tcg2Version.PpiVersion) {
194 DEBUG ((DEBUG_WARN, "WARNING: PcdTcgPhysicalPresenceInterfaceVer is not DynamicHii type and maps to TCG2_VERSION.PpiVersion\n"));
195 DEBUG ((DEBUG_WARN, "WARNING: The TCG2 PPI version configuring from setup page will not work\n"));
196 }
197
198 switch (PcdTcg2PpiVersion) {
199 case TCG2_PPI_VERSION_1_2:
200 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_PPI_VERSION_STATE_CONTENT), L"1.2", NULL);
201 break;
202 case TCG2_PPI_VERSION_1_3:
203 HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TCG2_PPI_VERSION_STATE_CONTENT), L"1.3", NULL);
204 break;
205 default:
206 ASSERT (FALSE);
207 break;
208 }
209 }
210
211 /**
212 The entry point for Tcg2 configuration driver.
213
214 @param[in] ImageHandle The image handle of the driver.
215 @param[in] SystemTable The system table.
216
217 @retval EFI_ALREADY_STARTED The driver already exists in system.
218 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources.
219 @retval EFI_SUCCES All the related protocols are installed on the driver.
220 @retval Others Fail to install protocols as indicated.
221
222 **/
223 EFI_STATUS
224 EFIAPI
225 Tcg2ConfigDriverEntryPoint (
226 IN EFI_HANDLE ImageHandle,
227 IN EFI_SYSTEM_TABLE *SystemTable
228 )
229 {
230 EFI_STATUS Status;
231 TCG2_CONFIG_PRIVATE_DATA *PrivateData;
232 TCG2_CONFIGURATION Tcg2Configuration;
233 TCG2_DEVICE_DETECTION Tcg2DeviceDetection;
234 UINTN Index;
235 UINTN DataSize;
236 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
237 UINT32 CurrentActivePCRBanks;
238
239 Status = gBS->OpenProtocol (
240 ImageHandle,
241 &gEfiCallerIdGuid,
242 NULL,
243 ImageHandle,
244 ImageHandle,
245 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
246 );
247 if (!EFI_ERROR (Status)) {
248 return EFI_ALREADY_STARTED;
249 }
250
251 //
252 // Create a private data structure.
253 //
254 PrivateData = AllocateCopyPool (sizeof (TCG2_CONFIG_PRIVATE_DATA), &mTcg2ConfigPrivateDateTemplate);
255 ASSERT (PrivateData != NULL);
256 mTcg2ConfigPrivateDate = PrivateData;
257 //
258 // Install private GUID.
259 //
260 Status = gBS->InstallMultipleProtocolInterfaces (
261 &ImageHandle,
262 &gEfiCallerIdGuid,
263 PrivateData,
264 NULL
265 );
266 ASSERT_EFI_ERROR (Status);
267
268 Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **) &PrivateData->Tcg2Protocol);
269 ASSERT_EFI_ERROR (Status);
270
271 PrivateData->ProtocolCapability.Size = sizeof(PrivateData->ProtocolCapability);
272 Status = PrivateData->Tcg2Protocol->GetCapability (
273 PrivateData->Tcg2Protocol,
274 &PrivateData->ProtocolCapability
275 );
276 ASSERT_EFI_ERROR (Status);
277
278 DataSize = sizeof(Tcg2Configuration);
279 Status = gRT->GetVariable (
280 TCG2_STORAGE_NAME,
281 &gTcg2ConfigFormSetGuid,
282 NULL,
283 &DataSize,
284 &Tcg2Configuration
285 );
286 if (EFI_ERROR (Status)) {
287 //
288 // Variable not ready, set default value
289 //
290 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
291 }
292
293 //
294 // Validation
295 //
296 if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {
297 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
298 }
299
300 //
301 // Set value for Tcg2CurrentActivePCRBanks
302 // Search Tcg2ConfigBin[] and update default value there
303 //
304 Status = PrivateData->Tcg2Protocol->GetActivePcrBanks (PrivateData->Tcg2Protocol, &CurrentActivePCRBanks);
305 ASSERT_EFI_ERROR (Status);
306 PrivateData->PCRBanksDesired = CurrentActivePCRBanks;
307 UpdateDefaultPCRBanks (Tcg2ConfigBin + sizeof(UINT32), ReadUnaligned32((UINT32 *)Tcg2ConfigBin) - sizeof(UINT32), CurrentActivePCRBanks);
308
309 //
310 // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
311 //
312 Tcg2DeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;
313 for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
314 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
315 Tcg2DeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;
316 break;
317 }
318 }
319
320 PrivateData->TpmDeviceDetected = Tcg2DeviceDetection.TpmDeviceDetected;
321 Tcg2Configuration.TpmDevice = Tcg2DeviceDetection.TpmDeviceDetected;
322
323 //
324 // Save to variable so platform driver can get it.
325 //
326 Status = gRT->SetVariable (
327 TCG2_DEVICE_DETECTION_NAME,
328 &gTcg2ConfigFormSetGuid,
329 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
330 sizeof(Tcg2DeviceDetection),
331 &Tcg2DeviceDetection
332 );
333 if (EFI_ERROR (Status)) {
334 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_DEVICE_DETECTION_NAME\n"));
335 Status = gRT->SetVariable (
336 TCG2_DEVICE_DETECTION_NAME,
337 &gTcg2ConfigFormSetGuid,
338 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
339 0,
340 NULL
341 );
342 ASSERT_EFI_ERROR (Status);
343 }
344
345 //
346 // Save to variable so platform driver can get it.
347 //
348 Status = gRT->SetVariable (
349 TCG2_STORAGE_NAME,
350 &gTcg2ConfigFormSetGuid,
351 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
352 sizeof(Tcg2Configuration),
353 &Tcg2Configuration
354 );
355 if (EFI_ERROR (Status)) {
356 DEBUG ((EFI_D_ERROR, "Tcg2ConfigDriver: Fail to set TCG2_STORAGE_NAME\n"));
357 }
358
359 //
360 // We should lock Tcg2DeviceDetection, because it contains information needed at S3.
361 //
362 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
363 if (!EFI_ERROR (Status)) {
364 Status = VariableLockProtocol->RequestToLock (
365 VariableLockProtocol,
366 TCG2_DEVICE_DETECTION_NAME,
367 &gTcg2ConfigFormSetGuid
368 );
369 ASSERT_EFI_ERROR (Status);
370 }
371
372 //
373 // Install Tcg2 configuration form
374 //
375 Status = InstallTcg2ConfigForm (PrivateData);
376 if (EFI_ERROR (Status)) {
377 goto ErrorExit;
378 }
379
380 InitializeTcg2VersionInfo (PrivateData);
381
382 return EFI_SUCCESS;
383
384 ErrorExit:
385 if (PrivateData != NULL) {
386 UninstallTcg2ConfigForm (PrivateData);
387 }
388
389 return Status;
390 }
391
392 /**
393 Unload the Tcg2 configuration form.
394
395 @param[in] ImageHandle The driver's image handle.
396
397 @retval EFI_SUCCESS The Tcg2 configuration form is unloaded.
398 @retval Others Failed to unload the form.
399
400 **/
401 EFI_STATUS
402 EFIAPI
403 Tcg2ConfigDriverUnload (
404 IN EFI_HANDLE ImageHandle
405 )
406 {
407 EFI_STATUS Status;
408 TCG2_CONFIG_PRIVATE_DATA *PrivateData;
409
410 Status = gBS->HandleProtocol (
411 ImageHandle,
412 &gEfiCallerIdGuid,
413 (VOID **) &PrivateData
414 );
415 if (EFI_ERROR (Status)) {
416 return Status;
417 }
418
419 ASSERT (PrivateData->Signature == TCG2_CONFIG_PRIVATE_DATA_SIGNATURE);
420
421 gBS->UninstallMultipleProtocolInterfaces (
422 &ImageHandle,
423 &gEfiCallerIdGuid,
424 PrivateData,
425 NULL
426 );
427
428 UninstallTcg2ConfigForm (PrivateData);
429
430 return EFI_SUCCESS;
431 }