DxeTcg2PhysicalPresenceLib.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. /** @file
  2. Execute pending TPM2 requests from OS or BIOS.
  3. Caution: This module requires additional review when modified.
  4. This driver will have external input - variable.
  5. This external input must be validated carefully to avoid security issue.
  6. Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation.
  7. Copyright (c) 2013 - 2020, Intel Corporation. All rights reserved.<BR>
  8. SPDX-License-Identifier: BSD-2-Clause-Patent
  9. **/
  10. #include <PiDxe.h>
  11. #include <Protocol/Tcg2Protocol.h>
  12. #include <Protocol/VariableLock.h>
  13. #include <Library/DebugLib.h>
  14. #include <Library/BaseMemoryLib.h>
  15. #include <Library/UefiRuntimeServicesTableLib.h>
  16. #include <Library/UefiDriverEntryPoint.h>
  17. #include <Library/UefiBootServicesTableLib.h>
  18. #include <Library/UefiLib.h>
  19. #include <Library/MemoryAllocationLib.h>
  20. #include <Library/PrintLib.h>
  21. #include <Library/HiiLib.h>
  22. #include <Library/HobLib.h>
  23. #include <Guid/EventGroup.h>
  24. #include <Guid/Tcg2PhysicalPresenceData.h>
  25. #include <Library/Tpm2CommandLib.h>
  26. #include <Library/Tcg2PhysicalPresenceLib.h>
  27. #include <Library/Tcg2PpVendorLib.h>
  28. #define CONFIRM_BUFFER_SIZE 4096
  29. EFI_HII_HANDLE mTcg2PpStringPackHandle;
  30. /**
  31. Get string by string id from HII Interface.
  32. @param[in] Id String ID.
  33. @retval CHAR16 * String from ID.
  34. @retval NULL If error occurs.
  35. **/
  36. CHAR16 *
  37. Tcg2PhysicalPresenceGetStringById (
  38. IN EFI_STRING_ID Id
  39. )
  40. {
  41. return HiiGetString (mTcg2PpStringPackHandle, Id, NULL);
  42. }
  43. /**
  44. Send ClearControl and Clear command to TPM.
  45. @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
  46. @retval EFI_SUCCESS Operation completed successfully.
  47. @retval EFI_TIMEOUT The register can't run into the expected status in time.
  48. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
  49. @retval EFI_DEVICE_ERROR Unexpected device behavior.
  50. **/
  51. EFI_STATUS
  52. EFIAPI
  53. Tpm2CommandClear (
  54. IN TPM2B_AUTH *PlatformAuth OPTIONAL
  55. )
  56. {
  57. EFI_STATUS Status;
  58. TPMS_AUTH_COMMAND *AuthSession;
  59. TPMS_AUTH_COMMAND LocalAuthSession;
  60. if (PlatformAuth == NULL) {
  61. AuthSession = NULL;
  62. } else {
  63. AuthSession = &LocalAuthSession;
  64. ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
  65. LocalAuthSession.sessionHandle = TPM_RS_PW;
  66. LocalAuthSession.hmac.size = PlatformAuth->size;
  67. CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
  68. }
  69. DEBUG ((DEBUG_INFO, "Tpm2ClearControl ... \n"));
  70. Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);
  71. DEBUG ((DEBUG_INFO, "Tpm2ClearControl - %r\n", Status));
  72. if (EFI_ERROR (Status)) {
  73. goto Done;
  74. }
  75. DEBUG ((DEBUG_INFO, "Tpm2Clear ... \n"));
  76. Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);
  77. DEBUG ((DEBUG_INFO, "Tpm2Clear - %r\n", Status));
  78. Done:
  79. ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
  80. return Status;
  81. }
  82. /**
  83. Change EPS.
  84. @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
  85. @retval EFI_SUCCESS Operation completed successfully.
  86. **/
  87. EFI_STATUS
  88. Tpm2CommandChangeEps (
  89. IN TPM2B_AUTH *PlatformAuth OPTIONAL
  90. )
  91. {
  92. EFI_STATUS Status;
  93. TPMS_AUTH_COMMAND *AuthSession;
  94. TPMS_AUTH_COMMAND LocalAuthSession;
  95. if (PlatformAuth == NULL) {
  96. AuthSession = NULL;
  97. } else {
  98. AuthSession = &LocalAuthSession;
  99. ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
  100. LocalAuthSession.sessionHandle = TPM_RS_PW;
  101. LocalAuthSession.hmac.size = PlatformAuth->size;
  102. CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
  103. }
  104. Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession);
  105. DEBUG ((DEBUG_INFO, "Tpm2ChangeEPS - %r\n", Status));
  106. ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
  107. return Status;
  108. }
  109. /**
  110. Execute physical presence operation requested by the OS.
  111. @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
  112. @param[in] CommandCode Physical presence operation value.
  113. @param[in] CommandParameter Physical presence operation parameter.
  114. @param[in, out] PpiFlags The physical presence interface flags.
  115. @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
  116. @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
  117. receiving response from TPM.
  118. @retval Others Return code from the TPM device after command execution.
  119. **/
  120. UINT32
  121. Tcg2ExecutePhysicalPresence (
  122. IN TPM2B_AUTH *PlatformAuth OPTIONAL,
  123. IN UINT32 CommandCode,
  124. IN UINT32 CommandParameter,
  125. IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags
  126. )
  127. {
  128. EFI_STATUS Status;
  129. EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
  130. UINT32 ActivePcrBanks;
  131. switch (CommandCode) {
  132. case TCG2_PHYSICAL_PRESENCE_CLEAR:
  133. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
  134. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
  135. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
  136. Status = Tpm2CommandClear (PlatformAuth);
  137. if (EFI_ERROR (Status)) {
  138. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  139. } else {
  140. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  141. }
  142. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
  143. PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;
  144. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  145. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
  146. PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;
  147. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  148. case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
  149. Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
  150. ASSERT_EFI_ERROR (Status);
  151. //
  152. // PP spec requirements:
  153. // Firmware should check that all requested (set) hashing algorithms are supported with respective PCR banks.
  154. // Firmware has to ensure that at least one PCR banks is active.
  155. // If not, an error is returned and no action is taken.
  156. //
  157. if ((CommandParameter == 0) || ((CommandParameter & (~TpmHashAlgorithmBitmap)) != 0)) {
  158. DEBUG ((DEBUG_ERROR, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter));
  159. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  160. }
  161. Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, CommandParameter);
  162. if (EFI_ERROR (Status)) {
  163. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  164. } else {
  165. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  166. }
  167. case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
  168. Status = Tpm2CommandChangeEps (PlatformAuth);
  169. if (EFI_ERROR (Status)) {
  170. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  171. } else {
  172. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  173. }
  174. case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
  175. Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
  176. ASSERT_EFI_ERROR (Status);
  177. Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, TpmHashAlgorithmBitmap);
  178. if (EFI_ERROR (Status)) {
  179. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  180. } else {
  181. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  182. }
  183. case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
  184. PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;
  185. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  186. case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
  187. PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;
  188. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  189. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
  190. PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID;
  191. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  192. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
  193. PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID;
  194. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  195. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
  196. PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID;
  197. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  198. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
  199. PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID;
  200. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  201. default:
  202. if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
  203. return TCG_PP_OPERATION_RESPONSE_SUCCESS;
  204. } else {
  205. return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  206. }
  207. }
  208. }
  209. /**
  210. Read the specified key for user confirmation.
  211. @param[in] CautionKey If true, F12 is used as confirm key;
  212. If false, F10 is used as confirm key.
  213. @retval TRUE User confirmed the changes by input.
  214. @retval FALSE User discarded the changes.
  215. **/
  216. BOOLEAN
  217. Tcg2ReadUserKey (
  218. IN BOOLEAN CautionKey
  219. )
  220. {
  221. EFI_STATUS Status;
  222. EFI_INPUT_KEY Key;
  223. UINT16 InputKey;
  224. InputKey = 0;
  225. do {
  226. Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
  227. if (!EFI_ERROR (Status)) {
  228. Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
  229. if (Key.ScanCode == SCAN_ESC) {
  230. InputKey = Key.ScanCode;
  231. }
  232. if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
  233. InputKey = Key.ScanCode;
  234. }
  235. if ((Key.ScanCode == SCAN_F12) && CautionKey) {
  236. InputKey = Key.ScanCode;
  237. }
  238. }
  239. } while (InputKey == 0);
  240. if (InputKey != SCAN_ESC) {
  241. return TRUE;
  242. }
  243. return FALSE;
  244. }
  245. /**
  246. Fill Buffer With BootHashAlg.
  247. @param[in] Buffer Buffer to be filled.
  248. @param[in] BufferSize Size of buffer.
  249. @param[in] BootHashAlg BootHashAlg.
  250. **/
  251. VOID
  252. Tcg2FillBufferWithBootHashAlg (
  253. IN UINT16 *Buffer,
  254. IN UINTN BufferSize,
  255. IN UINT32 BootHashAlg
  256. )
  257. {
  258. Buffer[0] = 0;
  259. if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
  260. if (Buffer[0] != 0) {
  261. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  262. }
  263. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  264. }
  265. if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
  266. if (Buffer[0] != 0) {
  267. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  268. }
  269. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  270. }
  271. if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
  272. if (Buffer[0] != 0) {
  273. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  274. }
  275. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  276. }
  277. if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
  278. if (Buffer[0] != 0) {
  279. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  280. }
  281. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  282. }
  283. if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
  284. if (Buffer[0] != 0) {
  285. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  286. }
  287. StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
  288. }
  289. }
  290. /**
  291. Display the confirm text and get user confirmation.
  292. @param[in] TpmPpCommand The requested TPM physical presence command.
  293. @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
  294. @retval TRUE The user has confirmed the changes.
  295. @retval FALSE The user doesn't confirm the changes.
  296. **/
  297. BOOLEAN
  298. Tcg2UserConfirm (
  299. IN UINT32 TpmPpCommand,
  300. IN UINT32 TpmPpCommandParameter
  301. )
  302. {
  303. CHAR16 *ConfirmText;
  304. CHAR16 *TmpStr1;
  305. CHAR16 *TmpStr2;
  306. UINTN BufSize;
  307. BOOLEAN CautionKey;
  308. BOOLEAN NoPpiInfo;
  309. UINT16 Index;
  310. CHAR16 DstStr[81];
  311. CHAR16 TempBuffer[1024];
  312. CHAR16 TempBuffer2[1024];
  313. EFI_TCG2_PROTOCOL *Tcg2Protocol;
  314. EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability;
  315. UINT32 CurrentPCRBanks;
  316. EFI_STATUS Status;
  317. TmpStr2 = NULL;
  318. CautionKey = FALSE;
  319. NoPpiInfo = FALSE;
  320. BufSize = CONFIRM_BUFFER_SIZE;
  321. ConfirmText = AllocateZeroPool (BufSize);
  322. ASSERT (ConfirmText != NULL);
  323. mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);
  324. ASSERT (mTcg2PpStringPackHandle != NULL);
  325. switch (TpmPpCommand) {
  326. case TCG2_PHYSICAL_PRESENCE_CLEAR:
  327. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
  328. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
  329. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
  330. CautionKey = TRUE;
  331. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
  332. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
  333. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  334. FreePool (TmpStr1);
  335. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
  336. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  337. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  338. FreePool (TmpStr1);
  339. break;
  340. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
  341. CautionKey = TRUE;
  342. NoPpiInfo = TRUE;
  343. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
  344. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
  345. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  346. FreePool (TmpStr1);
  347. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
  348. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  349. FreePool (TmpStr1);
  350. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
  351. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  352. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  353. FreePool (TmpStr1);
  354. break;
  355. case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
  356. Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
  357. ASSERT_EFI_ERROR (Status);
  358. ProtocolCapability.Size = sizeof (ProtocolCapability);
  359. Status = Tcg2Protocol->GetCapability (
  360. Tcg2Protocol,
  361. &ProtocolCapability
  362. );
  363. ASSERT_EFI_ERROR (Status);
  364. Status = Tcg2Protocol->GetActivePcrBanks (
  365. Tcg2Protocol,
  366. &CurrentPCRBanks
  367. );
  368. ASSERT_EFI_ERROR (Status);
  369. CautionKey = TRUE;
  370. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));
  371. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
  372. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  373. FreePool (TmpStr1);
  374. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));
  375. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  376. FreePool (TmpStr1);
  377. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));
  378. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  379. FreePool (TmpStr1);
  380. Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof (TempBuffer), TpmPpCommandParameter);
  381. Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof (TempBuffer2), CurrentPCRBanks);
  382. TmpStr1 = AllocateZeroPool (BufSize);
  383. ASSERT (TmpStr1 != NULL);
  384. UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer);
  385. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  386. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  387. FreePool (TmpStr1);
  388. break;
  389. case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
  390. CautionKey = TRUE;
  391. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));
  392. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
  393. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  394. FreePool (TmpStr1);
  395. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));
  396. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  397. FreePool (TmpStr1);
  398. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2));
  399. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  400. FreePool (TmpStr1);
  401. break;
  402. case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
  403. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID));
  404. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));
  405. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  406. FreePool (TmpStr1);
  407. break;
  408. case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
  409. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID));
  410. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));
  411. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  412. FreePool (TmpStr1);
  413. break;
  414. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
  415. NoPpiInfo = TRUE;
  416. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_ENABLE_BLOCK_SID));
  417. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR));
  418. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  419. FreePool (TmpStr1);
  420. break;
  421. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
  422. NoPpiInfo = TRUE;
  423. TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_DISABLE_BLOCK_SID));
  424. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR));
  425. UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
  426. FreePool (TmpStr1);
  427. break;
  428. default:
  429. ;
  430. }
  431. if (TmpStr2 == NULL) {
  432. FreePool (ConfirmText);
  433. return FALSE;
  434. }
  435. if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {
  436. if (CautionKey) {
  437. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
  438. } else {
  439. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
  440. }
  441. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  442. FreePool (TmpStr1);
  443. if (NoPpiInfo) {
  444. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
  445. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  446. FreePool (TmpStr1);
  447. }
  448. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
  449. } else {
  450. if (CautionKey) {
  451. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));
  452. } else {
  453. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));
  454. }
  455. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  456. FreePool (TmpStr1);
  457. if (NoPpiInfo) {
  458. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));
  459. StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
  460. FreePool (TmpStr1);
  461. }
  462. TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));
  463. }
  464. BufSize -= StrSize (ConfirmText);
  465. UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
  466. DstStr[80] = L'\0';
  467. for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
  468. StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);
  469. Print (DstStr);
  470. }
  471. FreePool (TmpStr1);
  472. FreePool (TmpStr2);
  473. FreePool (ConfirmText);
  474. HiiRemovePackages (mTcg2PpStringPackHandle);
  475. if (Tcg2ReadUserKey (CautionKey)) {
  476. return TRUE;
  477. }
  478. return FALSE;
  479. }
  480. /**
  481. Check if there is a valid physical presence command request. Also updates parameter value
  482. to whether the requested physical presence command already confirmed by user
  483. @param[in] TcgPpData EFI Tcg2 Physical Presence request data.
  484. @param[in] Flags The physical presence interface flags.
  485. @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
  486. True, it indicates the command doesn't require user confirm, or already confirmed
  487. in last boot cycle by user.
  488. False, it indicates the command need user confirm from UI.
  489. @retval TRUE Physical Presence operation command is valid.
  490. @retval FALSE Physical Presence operation command is invalid.
  491. **/
  492. BOOLEAN
  493. Tcg2HaveValidTpmRequest (
  494. IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,
  495. IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,
  496. OUT BOOLEAN *RequestConfirmed
  497. )
  498. {
  499. EFI_TCG2_PROTOCOL *Tcg2Protocol;
  500. EFI_STATUS Status;
  501. BOOLEAN IsRequestValid;
  502. *RequestConfirmed = FALSE;
  503. if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
  504. //
  505. // Need TCG2 protocol.
  506. //
  507. Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
  508. if (EFI_ERROR (Status)) {
  509. return FALSE;
  510. }
  511. }
  512. switch (TcgPpData->PPRequest) {
  513. case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
  514. *RequestConfirmed = TRUE;
  515. return TRUE;
  516. case TCG2_PHYSICAL_PRESENCE_CLEAR:
  517. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
  518. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
  519. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
  520. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
  521. *RequestConfirmed = TRUE;
  522. }
  523. break;
  524. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
  525. *RequestConfirmed = TRUE;
  526. break;
  527. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
  528. break;
  529. case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
  530. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
  531. *RequestConfirmed = TRUE;
  532. }
  533. break;
  534. case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
  535. if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
  536. *RequestConfirmed = TRUE;
  537. }
  538. break;
  539. case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
  540. *RequestConfirmed = TRUE;
  541. break;
  542. case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
  543. if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
  544. *RequestConfirmed = TRUE;
  545. }
  546. break;
  547. case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
  548. if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
  549. *RequestConfirmed = TRUE;
  550. }
  551. break;
  552. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
  553. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
  554. *RequestConfirmed = TRUE;
  555. break;
  556. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
  557. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
  558. break;
  559. default:
  560. if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  561. IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);
  562. if (!IsRequestValid) {
  563. return FALSE;
  564. } else {
  565. break;
  566. }
  567. } else {
  568. //
  569. // Wrong Physical Presence command
  570. //
  571. return FALSE;
  572. }
  573. }
  574. if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) {
  575. //
  576. // It had been confirmed in last boot, it doesn't need confirm again.
  577. //
  578. *RequestConfirmed = TRUE;
  579. }
  580. //
  581. // Physical Presence command is correct
  582. //
  583. return TRUE;
  584. }
  585. /**
  586. Check and execute the requested physical presence command.
  587. Caution: This function may receive untrusted input.
  588. TcgPpData variable is external input, so this function will validate
  589. its data structure to be valid value.
  590. @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
  591. @param[in, out] TcgPpData Pointer to the physical presence NV variable.
  592. @param[in, out] Flags Pointer to the physical presence interface flags.
  593. **/
  594. VOID
  595. Tcg2ExecutePendingTpmRequest (
  596. IN TPM2B_AUTH *PlatformAuth OPTIONAL,
  597. IN OUT EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,
  598. IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *Flags
  599. )
  600. {
  601. EFI_STATUS Status;
  602. UINTN DataSize;
  603. BOOLEAN RequestConfirmed;
  604. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags;
  605. BOOLEAN ResetRequired;
  606. UINT32 NewPPFlags;
  607. if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
  608. //
  609. // No operation request
  610. //
  611. return;
  612. }
  613. if (!Tcg2HaveValidTpmRequest (TcgPpData, *Flags, &RequestConfirmed)) {
  614. //
  615. // Invalid operation request.
  616. //
  617. if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
  618. TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;
  619. } else {
  620. TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
  621. }
  622. TcgPpData->LastPPRequest = TcgPpData->PPRequest;
  623. TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
  624. TcgPpData->PPRequestParameter = 0;
  625. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  626. Status = gRT->SetVariable (
  627. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  628. &gEfiTcg2PhysicalPresenceGuid,
  629. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  630. DataSize,
  631. TcgPpData
  632. );
  633. return;
  634. }
  635. ResetRequired = FALSE;
  636. if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  637. NewFlags = *Flags;
  638. NewPPFlags = NewFlags.PPFlags;
  639. TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);
  640. NewFlags.PPFlags = NewPPFlags;
  641. } else {
  642. if (!RequestConfirmed) {
  643. //
  644. // Print confirm text and wait for approval.
  645. //
  646. RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);
  647. }
  648. //
  649. // Execute requested physical presence command
  650. //
  651. TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;
  652. NewFlags = *Flags;
  653. if (RequestConfirmed) {
  654. TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (
  655. PlatformAuth,
  656. TcgPpData->PPRequest,
  657. TcgPpData->PPRequestParameter,
  658. &NewFlags
  659. );
  660. }
  661. }
  662. //
  663. // Save the flags if it is updated.
  664. //
  665. if (CompareMem (Flags, &NewFlags, sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {
  666. *Flags = NewFlags;
  667. Status = gRT->SetVariable (
  668. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  669. &gEfiTcg2PhysicalPresenceGuid,
  670. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  671. sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),
  672. &NewFlags
  673. );
  674. }
  675. //
  676. // Clear request
  677. //
  678. if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {
  679. TcgPpData->LastPPRequest = TcgPpData->PPRequest;
  680. TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
  681. TcgPpData->PPRequestParameter = 0;
  682. }
  683. //
  684. // Save changes
  685. //
  686. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  687. Status = gRT->SetVariable (
  688. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  689. &gEfiTcg2PhysicalPresenceGuid,
  690. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  691. DataSize,
  692. TcgPpData
  693. );
  694. if (EFI_ERROR (Status)) {
  695. return;
  696. }
  697. if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {
  698. return;
  699. }
  700. //
  701. // Reset system to make new TPM settings in effect
  702. //
  703. switch (TcgPpData->LastPPRequest) {
  704. case TCG2_PHYSICAL_PRESENCE_CLEAR:
  705. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
  706. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
  707. case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
  708. case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
  709. case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
  710. case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
  711. break;
  712. case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
  713. case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
  714. break;
  715. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
  716. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
  717. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
  718. case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
  719. return;
  720. default:
  721. if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  722. if (ResetRequired) {
  723. break;
  724. } else {
  725. return;
  726. }
  727. }
  728. if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
  729. break;
  730. }
  731. return;
  732. }
  733. Print (L"Rebooting system to make TPM2 settings in effect\n");
  734. gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
  735. ASSERT (FALSE);
  736. }
  737. /**
  738. Check and execute the pending TPM request.
  739. The TPM request may come from OS or BIOS. This API will display request information and wait
  740. for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
  741. the TPM request is confirmed, and one or more reset may be required to make TPM request to
  742. take effect.
  743. This API should be invoked after console in and console out are all ready as they are required
  744. to display request information and get user input to confirm the request.
  745. @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
  746. **/
  747. VOID
  748. EFIAPI
  749. Tcg2PhysicalPresenceLibProcessRequest (
  750. IN TPM2B_AUTH *PlatformAuth OPTIONAL
  751. )
  752. {
  753. EFI_STATUS Status;
  754. UINTN DataSize;
  755. EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;
  756. EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
  757. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
  758. //
  759. // This flags variable controls whether physical presence is required for TPM command.
  760. // It should be protected from malicious software. We set it as read-only variable here.
  761. //
  762. Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
  763. if (!EFI_ERROR (Status)) {
  764. Status = VariableLockProtocol->RequestToLock (
  765. VariableLockProtocol,
  766. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  767. &gEfiTcg2PhysicalPresenceGuid
  768. );
  769. if (EFI_ERROR (Status)) {
  770. DEBUG ((DEBUG_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
  771. ASSERT_EFI_ERROR (Status);
  772. }
  773. }
  774. //
  775. // Check S4 resume
  776. //
  777. if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
  778. DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n"));
  779. return;
  780. }
  781. //
  782. // Initialize physical presence flags.
  783. //
  784. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  785. Status = gRT->GetVariable (
  786. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  787. &gEfiTcg2PhysicalPresenceGuid,
  788. NULL,
  789. &DataSize,
  790. &PpiFlags
  791. );
  792. if (EFI_ERROR (Status)) {
  793. PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
  794. Status = gRT->SetVariable (
  795. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  796. &gEfiTcg2PhysicalPresenceGuid,
  797. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  798. sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),
  799. &PpiFlags
  800. );
  801. if (EFI_ERROR (Status)) {
  802. DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));
  803. return;
  804. }
  805. DEBUG ((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0x%x\n", PpiFlags.PPFlags));
  806. }
  807. //
  808. // Initialize physical presence variable.
  809. //
  810. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  811. Status = gRT->GetVariable (
  812. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  813. &gEfiTcg2PhysicalPresenceGuid,
  814. NULL,
  815. &DataSize,
  816. &TcgPpData
  817. );
  818. if (EFI_ERROR (Status)) {
  819. ZeroMem ((VOID *)&TcgPpData, sizeof (TcgPpData));
  820. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  821. Status = gRT->SetVariable (
  822. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  823. &gEfiTcg2PhysicalPresenceGuid,
  824. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  825. DataSize,
  826. &TcgPpData
  827. );
  828. if (EFI_ERROR (Status)) {
  829. DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));
  830. return;
  831. }
  832. }
  833. DEBUG ((DEBUG_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
  834. //
  835. // Execute pending TPM request.
  836. //
  837. Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags);
  838. DEBUG ((DEBUG_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));
  839. }
  840. /**
  841. Check if the pending TPM request needs user input to confirm.
  842. The TPM request may come from OS. This API will check if TPM request exists and need user
  843. input to confirmation.
  844. @retval TRUE TPM needs input to confirm user physical presence.
  845. @retval FALSE TPM doesn't need input to confirm user physical presence.
  846. **/
  847. BOOLEAN
  848. EFIAPI
  849. Tcg2PhysicalPresenceLibNeedUserConfirm (
  850. VOID
  851. )
  852. {
  853. EFI_STATUS Status;
  854. EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;
  855. UINTN DataSize;
  856. BOOLEAN RequestConfirmed;
  857. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
  858. //
  859. // Check S4 resume
  860. //
  861. if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
  862. DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n"));
  863. return FALSE;
  864. }
  865. //
  866. // Check Tpm requests
  867. //
  868. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  869. Status = gRT->GetVariable (
  870. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  871. &gEfiTcg2PhysicalPresenceGuid,
  872. NULL,
  873. &DataSize,
  874. &TcgPpData
  875. );
  876. if (EFI_ERROR (Status)) {
  877. return FALSE;
  878. }
  879. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  880. Status = gRT->GetVariable (
  881. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  882. &gEfiTcg2PhysicalPresenceGuid,
  883. NULL,
  884. &DataSize,
  885. &PpiFlags
  886. );
  887. if (EFI_ERROR (Status)) {
  888. return FALSE;
  889. }
  890. if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
  891. //
  892. // No operation request
  893. //
  894. return FALSE;
  895. }
  896. if (!Tcg2HaveValidTpmRequest (&TcgPpData, PpiFlags, &RequestConfirmed)) {
  897. //
  898. // Invalid operation request.
  899. //
  900. return FALSE;
  901. }
  902. if (!RequestConfirmed) {
  903. //
  904. // Need UI to confirm
  905. //
  906. return TRUE;
  907. }
  908. return FALSE;
  909. }
  910. /**
  911. The handler for TPM physical presence function:
  912. Return TPM Operation Response to OS Environment.
  913. @param[out] MostRecentRequest Most recent operation request.
  914. @param[out] Response Response to the most recent operation request.
  915. @return Return Code for Return TPM Operation Response to OS Environment.
  916. **/
  917. UINT32
  918. EFIAPI
  919. Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
  920. OUT UINT32 *MostRecentRequest,
  921. OUT UINT32 *Response
  922. )
  923. {
  924. EFI_STATUS Status;
  925. UINTN DataSize;
  926. EFI_TCG2_PHYSICAL_PRESENCE PpData;
  927. DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
  928. //
  929. // Get the Physical Presence variable
  930. //
  931. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  932. Status = gRT->GetVariable (
  933. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  934. &gEfiTcg2PhysicalPresenceGuid,
  935. NULL,
  936. &DataSize,
  937. &PpData
  938. );
  939. if (EFI_ERROR (Status)) {
  940. *MostRecentRequest = 0;
  941. *Response = 0;
  942. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
  943. return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
  944. }
  945. *MostRecentRequest = PpData.LastPPRequest;
  946. *Response = PpData.PPResponse;
  947. return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
  948. }
  949. /**
  950. The handler for TPM physical presence function:
  951. Submit TPM Operation Request to Pre-OS Environment and
  952. Submit TPM Operation Request to Pre-OS Environment 2.
  953. Caution: This function may receive untrusted input.
  954. @param[in] OperationRequest TPM physical presence operation request.
  955. @param[in] RequestParameter TPM physical presence operation request parameter.
  956. @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
  957. Submit TPM Operation Request to Pre-OS Environment 2.
  958. **/
  959. UINT32
  960. EFIAPI
  961. Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
  962. IN UINT32 OperationRequest,
  963. IN UINT32 RequestParameter
  964. )
  965. {
  966. EFI_STATUS Status;
  967. UINTN DataSize;
  968. EFI_TCG2_PHYSICAL_PRESENCE PpData;
  969. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
  970. DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
  971. //
  972. // Get the Physical Presence variable
  973. //
  974. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  975. Status = gRT->GetVariable (
  976. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  977. &gEfiTcg2PhysicalPresenceGuid,
  978. NULL,
  979. &DataSize,
  980. &PpData
  981. );
  982. if (EFI_ERROR (Status)) {
  983. DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
  984. return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
  985. }
  986. if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
  987. (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))
  988. {
  989. return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
  990. }
  991. if ((PpData.PPRequest != OperationRequest) ||
  992. (PpData.PPRequestParameter != RequestParameter))
  993. {
  994. PpData.PPRequest = (UINT8)OperationRequest;
  995. PpData.PPRequestParameter = RequestParameter;
  996. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
  997. Status = gRT->SetVariable (
  998. TCG2_PHYSICAL_PRESENCE_VARIABLE,
  999. &gEfiTcg2PhysicalPresenceGuid,
  1000. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
  1001. DataSize,
  1002. &PpData
  1003. );
  1004. if (EFI_ERROR (Status)) {
  1005. DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
  1006. return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
  1007. }
  1008. }
  1009. if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
  1010. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  1011. Status = gRT->GetVariable (
  1012. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  1013. &gEfiTcg2PhysicalPresenceGuid,
  1014. NULL,
  1015. &DataSize,
  1016. &Flags
  1017. );
  1018. if (EFI_ERROR (Status)) {
  1019. Flags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
  1020. }
  1021. return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
  1022. }
  1023. return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
  1024. }
  1025. /**
  1026. Return TPM2 ManagementFlags set by PP interface.
  1027. @retval ManagementFlags TPM2 Management Flags.
  1028. **/
  1029. UINT32
  1030. EFIAPI
  1031. Tcg2PhysicalPresenceLibGetManagementFlags (
  1032. VOID
  1033. )
  1034. {
  1035. EFI_STATUS Status;
  1036. EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
  1037. UINTN DataSize;
  1038. DEBUG ((DEBUG_INFO, "[TPM2] GetManagementFlags\n"));
  1039. DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
  1040. Status = gRT->GetVariable (
  1041. TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
  1042. &gEfiTcg2PhysicalPresenceGuid,
  1043. NULL,
  1044. &DataSize,
  1045. &PpiFlags
  1046. );
  1047. if (EFI_ERROR (Status)) {
  1048. PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
  1049. }
  1050. return PpiFlags.PPFlags;
  1051. }