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