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