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