Tcg2ConfigDriver.c 15 KB

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