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