]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
Fix TPM may be locked twice issue in normal boot.
[mirror_edk2.git] / SecurityPkg / Library / DxeTcgPhysicalPresenceLib / DxeTcgPhysicalPresenceLib.c
CommitLineData
0c18794e 1/** @file\r
607599bf 2\r
3 Execute pending TPM requests from OS or BIOS and Lock TPM.\r
4\r
dc204d5a
JY
5 Caution: This module requires additional review when modified.\r
6 This driver will have external input - variable.\r
7 This external input must be validated carefully to avoid security issue.\r
8\r
9 ExecutePendingTpmRequest() will receive untrusted input and do validation.\r
10\r
03ecb576 11Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
0c18794e 12This program and the accompanying materials \r
13are licensed and made available under the terms and conditions of the BSD License \r
14which accompanies this distribution. The full text of the license may be found at \r
15http://opensource.org/licenses/bsd-license.php\r
16\r
17THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
18WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
19\r
20**/\r
21\r
607599bf 22#include <PiDxe.h>\r
23\r
24#include <Protocol/TcgService.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/UefiRuntimeServicesTableLib.h>\r
28#include <Library/UefiDriverEntryPoint.h>\r
29#include <Library/UefiBootServicesTableLib.h>\r
30#include <Library/UefiLib.h>\r
31#include <Library/MemoryAllocationLib.h>\r
32#include <Library/PrintLib.h>\r
33#include <Library/HiiLib.h>\r
34#include <Guid/EventGroup.h>\r
35#include <Guid/PhysicalPresenceData.h>\r
36\r
37#define TPM_PP_USER_ABORT ((TPM_RESULT)(-0x10))\r
38#define TPM_PP_BIOS_FAILURE ((TPM_RESULT)(-0x0f))\r
39#define CONFIRM_BUFFER_SIZE 4096\r
0c18794e 40\r
41EFI_HII_HANDLE mPpStringPackHandle;\r
42\r
607599bf 43/**\r
44 Get string by string id from HII Interface.\r
45\r
46 @param[in] Id String ID.\r
47\r
48 @retval CHAR16 * String from ID.\r
49 @retval NULL If error occurs.\r
50\r
51**/\r
52CHAR16 *\r
53PhysicalPresenceGetStringById (\r
54 IN EFI_STRING_ID Id\r
55 )\r
56{\r
57 return HiiGetString (mPpStringPackHandle, Id, NULL);\r
58}\r
59\r
0c18794e 60/**\r
61 Get TPM physical presence permanent flags.\r
62\r
607599bf 63 @param[in] TcgProtocol EFI TCG Protocol instance. \r
64 @param[out] LifetimeLock physicalPresenceLifetimeLock permanent flag. \r
65 @param[out] CmdEnable physicalPresenceCMDEnable permanent flag.\r
0c18794e 66 \r
67 @retval EFI_SUCCESS Flags were returns successfully.\r
68 @retval other Failed to locate EFI TCG Protocol.\r
69\r
70**/\r
71EFI_STATUS\r
72GetTpmCapability (\r
607599bf 73 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
0c18794e 74 OUT BOOLEAN *LifetimeLock,\r
75 OUT BOOLEAN *CmdEnable\r
76 )\r
77{\r
78 EFI_STATUS Status;\r
0c18794e 79 TPM_RQU_COMMAND_HDR *TpmRqu;\r
80 TPM_RSP_COMMAND_HDR *TpmRsp;\r
81 UINT32 *SendBufPtr;\r
82 UINT8 SendBuffer[sizeof (*TpmRqu) + sizeof (UINT32) * 3];\r
83 TPM_PERMANENT_FLAGS *TpmPermanentFlags;\r
84 UINT8 RecvBuffer[40];\r
85 \r
0c18794e 86 //\r
87 // Fill request header\r
88 //\r
89 TpmRsp = (TPM_RSP_COMMAND_HDR*)RecvBuffer;\r
90 TpmRqu = (TPM_RQU_COMMAND_HDR*)SendBuffer;\r
91 \r
607599bf 92 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
93 TpmRqu->paramSize = SwapBytes32 (sizeof (SendBuffer));\r
94 TpmRqu->ordinal = SwapBytes32 (TPM_ORD_GetCapability);\r
0c18794e 95\r
96 //\r
97 // Set request parameter\r
98 //\r
99 SendBufPtr = (UINT32*)(TpmRqu + 1);\r
607599bf 100 WriteUnaligned32 (SendBufPtr++, SwapBytes32 (TPM_CAP_FLAG));\r
101 WriteUnaligned32 (SendBufPtr++, SwapBytes32 (sizeof (TPM_CAP_FLAG_PERMANENT)));\r
102 WriteUnaligned32 (SendBufPtr, SwapBytes32 (TPM_CAP_FLAG_PERMANENT)); \r
0c18794e 103 \r
104 Status = TcgProtocol->PassThroughToTpm (\r
105 TcgProtocol,\r
106 sizeof (SendBuffer),\r
107 (UINT8*)TpmRqu,\r
108 sizeof (RecvBuffer),\r
109 (UINT8*)&RecvBuffer\r
110 );\r
111 ASSERT_EFI_ERROR (Status);\r
607599bf 112 ASSERT (TpmRsp->tag == SwapBytes16 (TPM_TAG_RSP_COMMAND));\r
0c18794e 113 ASSERT (TpmRsp->returnCode == 0);\r
114 \r
115 TpmPermanentFlags = (TPM_PERMANENT_FLAGS *)&RecvBuffer[sizeof (TPM_RSP_COMMAND_HDR) + sizeof (UINT32)];\r
116 \r
117 if (LifetimeLock != NULL) {\r
118 *LifetimeLock = TpmPermanentFlags->physicalPresenceLifetimeLock;\r
119 }\r
120\r
121 if (CmdEnable != NULL) {\r
122 *CmdEnable = TpmPermanentFlags->physicalPresenceCMDEnable;\r
123 }\r
124\r
125 return Status;\r
126}\r
127\r
128/**\r
129 Issue TSC_PhysicalPresence command to TPM.\r
130\r
607599bf 131 @param[in] TcgProtocol EFI TCG Protocol instance. \r
0c18794e 132 @param[in] PhysicalPresence The state to set the TPM's Physical Presence flags. \r
133 \r
134 @retval EFI_SUCCESS TPM executed the command successfully.\r
135 @retval EFI_SECURITY_VIOLATION TPM returned error when executing the command.\r
136 @retval other Failed to locate EFI TCG Protocol.\r
137\r
138**/\r
139EFI_STATUS\r
140TpmPhysicalPresence (\r
607599bf 141 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
0c18794e 142 IN TPM_PHYSICAL_PRESENCE PhysicalPresence\r
143 )\r
144{\r
145 EFI_STATUS Status;\r
0c18794e 146 TPM_RQU_COMMAND_HDR *TpmRqu;\r
147 TPM_PHYSICAL_PRESENCE *TpmPp;\r
148 TPM_RSP_COMMAND_HDR TpmRsp;\r
149 UINT8 Buffer[sizeof (*TpmRqu) + sizeof (*TpmPp)];\r
150\r
0c18794e 151 TpmRqu = (TPM_RQU_COMMAND_HDR*)Buffer;\r
152 TpmPp = (TPM_PHYSICAL_PRESENCE*)(TpmRqu + 1);\r
153\r
607599bf 154 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
155 TpmRqu->paramSize = SwapBytes32 (sizeof (Buffer));\r
156 TpmRqu->ordinal = SwapBytes32 (TSC_ORD_PhysicalPresence);\r
157 WriteUnaligned16 (TpmPp, (TPM_PHYSICAL_PRESENCE) SwapBytes16 (PhysicalPresence)); \r
0c18794e 158\r
159 Status = TcgProtocol->PassThroughToTpm (\r
160 TcgProtocol,\r
161 sizeof (Buffer),\r
162 (UINT8*)TpmRqu,\r
163 sizeof (TpmRsp),\r
164 (UINT8*)&TpmRsp\r
165 );\r
166 ASSERT_EFI_ERROR (Status);\r
607599bf 167 ASSERT (TpmRsp.tag == SwapBytes16 (TPM_TAG_RSP_COMMAND));\r
0c18794e 168 if (TpmRsp.returnCode != 0) {\r
169 //\r
170 // If it fails, some requirements may be needed for this command.\r
171 //\r
172 return EFI_SECURITY_VIOLATION;\r
173 }\r
607599bf 174 \r
0c18794e 175 return Status;\r
176}\r
177\r
178/**\r
179 Issue a TPM command for which no additional output data will be returned.\r
180\r
181 @param[in] TcgProtocol EFI TCG Protocol instance. \r
182 @param[in] Ordinal TPM command code. \r
183 @param[in] AdditionalParameterSize Additional parameter size. \r
184 @param[in] AdditionalParameters Pointer to the Additional paramaters. \r
185 \r
186 @retval TPM_PP_BIOS_FAILURE Error occurred during sending command to TPM or \r
187 receiving response from TPM.\r
188 @retval Others Return code from the TPM device after command execution.\r
189\r
190**/\r
191TPM_RESULT\r
192TpmCommandNoReturnData (\r
193 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
194 IN TPM_COMMAND_CODE Ordinal,\r
195 IN UINTN AdditionalParameterSize,\r
196 IN VOID *AdditionalParameters\r
197 )\r
198{\r
199 EFI_STATUS Status;\r
200 TPM_RQU_COMMAND_HDR *TpmRqu;\r
201 TPM_RSP_COMMAND_HDR TpmRsp;\r
202 UINT32 Size;\r
203\r
607599bf 204 TpmRqu = (TPM_RQU_COMMAND_HDR*) AllocatePool (sizeof (*TpmRqu) + AdditionalParameterSize);\r
0c18794e 205 if (TpmRqu == NULL) {\r
206 return TPM_PP_BIOS_FAILURE;\r
207 }\r
208\r
607599bf 209 TpmRqu->tag = SwapBytes16 (TPM_TAG_RQU_COMMAND);\r
0c18794e 210 Size = (UINT32)(sizeof (*TpmRqu) + AdditionalParameterSize);\r
607599bf 211 TpmRqu->paramSize = SwapBytes32 (Size);\r
212 TpmRqu->ordinal = SwapBytes32 (Ordinal);\r
213 CopyMem (TpmRqu + 1, AdditionalParameters, AdditionalParameterSize);\r
0c18794e 214\r
215 Status = TcgProtocol->PassThroughToTpm (\r
216 TcgProtocol,\r
217 Size,\r
218 (UINT8*)TpmRqu,\r
219 (UINT32)sizeof (TpmRsp),\r
220 (UINT8*)&TpmRsp\r
221 );\r
222 FreePool (TpmRqu);\r
607599bf 223 if (EFI_ERROR (Status) || (TpmRsp.tag != SwapBytes16 (TPM_TAG_RSP_COMMAND))) {\r
0c18794e 224 return TPM_PP_BIOS_FAILURE;\r
225 }\r
607599bf 226 return SwapBytes32 (TpmRsp.returnCode);\r
0c18794e 227}\r
228\r
229/**\r
230 Execute physical presence operation requested by the OS.\r
231\r
607599bf 232 @param[in] TcgProtocol EFI TCG Protocol instance.\r
233 @param[in] CommandCode Physical presence operation value.\r
234 @param[in, out] PpiFlags The physical presence interface flags.\r
0c18794e 235 \r
236 @retval TPM_PP_BIOS_FAILURE Unknown physical presence operation.\r
237 @retval TPM_PP_BIOS_FAILURE Error occurred during sending command to TPM or \r
238 receiving response from TPM.\r
239 @retval Others Return code from the TPM device after command execution.\r
240\r
241**/\r
242TPM_RESULT\r
243ExecutePhysicalPresence (\r
244 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
245 IN UINT8 CommandCode,\r
246 IN OUT UINT8 *PpiFlags\r
247 )\r
248{\r
249 BOOLEAN BoolVal;\r
250 TPM_RESULT TpmResponse;\r
251 UINT32 InData[5];\r
252\r
253 switch (CommandCode) {\r
607599bf 254 case PHYSICAL_PRESENCE_ENABLE:\r
0c18794e 255 return TpmCommandNoReturnData (\r
256 TcgProtocol,\r
257 TPM_ORD_PhysicalEnable,\r
258 0,\r
259 NULL\r
260 );\r
261\r
607599bf 262 case PHYSICAL_PRESENCE_DISABLE:\r
0c18794e 263 return TpmCommandNoReturnData (\r
264 TcgProtocol,\r
265 TPM_ORD_PhysicalDisable,\r
266 0,\r
267 NULL\r
268 );\r
269\r
607599bf 270 case PHYSICAL_PRESENCE_ACTIVATE:\r
0c18794e 271 BoolVal = FALSE;\r
272 return TpmCommandNoReturnData (\r
273 TcgProtocol,\r
274 TPM_ORD_PhysicalSetDeactivated,\r
275 sizeof (BoolVal),\r
276 &BoolVal\r
277 );\r
278\r
607599bf 279 case PHYSICAL_PRESENCE_DEACTIVATE:\r
0c18794e 280 BoolVal = TRUE;\r
281 return TpmCommandNoReturnData (\r
282 TcgProtocol,\r
283 TPM_ORD_PhysicalSetDeactivated,\r
284 sizeof (BoolVal),\r
285 &BoolVal\r
286 );\r
287\r
607599bf 288 case PHYSICAL_PRESENCE_CLEAR:\r
0c18794e 289 return TpmCommandNoReturnData (\r
290 TcgProtocol,\r
291 TPM_ORD_ForceClear,\r
292 0,\r
293 NULL\r
294 );\r
295\r
607599bf 296 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:\r
297 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE, PpiFlags);\r
0c18794e 298 if (TpmResponse == 0) {\r
607599bf 299 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ACTIVATE, PpiFlags);\r
0c18794e 300 }\r
301 return TpmResponse;\r
302\r
607599bf 303 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:\r
304 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE, PpiFlags);\r
0c18794e 305 if (TpmResponse == 0) {\r
607599bf 306 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DISABLE, PpiFlags);\r
0c18794e 307 }\r
308 return TpmResponse;\r
309\r
607599bf 310 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:\r
0c18794e 311 BoolVal = TRUE;\r
312 return TpmCommandNoReturnData (\r
313 TcgProtocol,\r
314 TPM_ORD_SetOwnerInstall,\r
315 sizeof (BoolVal),\r
316 &BoolVal\r
317 );\r
318\r
607599bf 319 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:\r
0c18794e 320 BoolVal = FALSE;\r
321 return TpmCommandNoReturnData (\r
322 TcgProtocol,\r
323 TPM_ORD_SetOwnerInstall,\r
324 sizeof (BoolVal),\r
325 &BoolVal\r
326 );\r
327\r
607599bf 328 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:\r
0c18794e 329 //\r
607599bf 330 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE\r
331 // PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE will be executed after reboot\r
0c18794e 332 //\r
333 if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {\r
607599bf 334 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);\r
0c18794e 335 *PpiFlags |= FLAG_RESET_TRACK;\r
336 } else {\r
607599bf 337 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE, PpiFlags);\r
0c18794e 338 *PpiFlags &= ~FLAG_RESET_TRACK;\r
339 }\r
340 return TpmResponse;\r
341\r
607599bf 342 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:\r
343 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE, PpiFlags);\r
0c18794e 344 if (TpmResponse == 0) {\r
607599bf 345 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_DEACTIVATE_DISABLE, PpiFlags);\r
0c18794e 346 }\r
347 return TpmResponse;\r
348\r
607599bf 349 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
350 InData[0] = SwapBytes32 (TPM_SET_STCLEAR_DATA); // CapabilityArea\r
351 InData[1] = SwapBytes32 (sizeof(UINT32)); // SubCapSize\r
352 InData[2] = SwapBytes32 (TPM_SD_DEFERREDPHYSICALPRESENCE); // SubCap\r
353 InData[3] = SwapBytes32 (sizeof(UINT32)); // SetValueSize\r
354 InData[4] = SwapBytes32 (1); // UnownedFieldUpgrade; bit0\r
0c18794e 355 return TpmCommandNoReturnData (\r
356 TcgProtocol,\r
357 TPM_ORD_SetCapability,\r
358 sizeof (UINT32) * 5,\r
359 InData\r
360 );\r
361\r
607599bf 362 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:\r
0c18794e 363 //\r
364 // TPM_SetOperatorAuth\r
365 // This command requires UI to prompt user for Auth data\r
366 // Here it is NOT implemented\r
367 //\r
368 return TPM_PP_BIOS_FAILURE;\r
369\r
607599bf 370 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:\r
371 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);\r
0c18794e 372 if (TpmResponse == 0) {\r
607599bf 373 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);\r
0c18794e 374 }\r
375 return TpmResponse;\r
376\r
607599bf 377 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:\r
0c18794e 378 *PpiFlags &= ~FLAG_NO_PPI_PROVISION;\r
379 return 0;\r
380\r
607599bf 381 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:\r
0c18794e 382 *PpiFlags |= FLAG_NO_PPI_PROVISION;\r
383 return 0;\r
384\r
607599bf 385 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
0c18794e 386 *PpiFlags &= ~FLAG_NO_PPI_CLEAR;\r
387 return 0;\r
388\r
607599bf 389 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
0c18794e 390 *PpiFlags |= FLAG_NO_PPI_CLEAR;\r
391 return 0;\r
392\r
607599bf 393 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:\r
0c18794e 394 *PpiFlags &= ~FLAG_NO_PPI_MAINTENANCE;\r
395 return 0;\r
396\r
607599bf 397 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:\r
0c18794e 398 *PpiFlags |= FLAG_NO_PPI_MAINTENANCE;\r
399 return 0;\r
400 \r
607599bf 401 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:\r
1f728ac7 402 //\r
403 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR\r
404 // PHYSICAL_PRESENCE_CLEAR will be executed after reboot.\r
405 //\r
406 if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {\r
407 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);\r
408 *PpiFlags |= FLAG_RESET_TRACK;\r
409 } else {\r
607599bf 410 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);\r
1f728ac7 411 *PpiFlags &= ~FLAG_RESET_TRACK;\r
0c18794e 412 }\r
413 return TpmResponse;\r
414\r
607599bf 415 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
0c18794e 416 //\r
607599bf 417 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE\r
1f728ac7 418 // PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE will be executed after reboot.\r
0c18794e 419 //\r
420 if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {\r
607599bf 421 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);\r
0c18794e 422 *PpiFlags |= FLAG_RESET_TRACK;\r
423 } else {\r
607599bf 424 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags);\r
0c18794e 425 *PpiFlags &= ~FLAG_RESET_TRACK;\r
426 } \r
427 return TpmResponse;\r
428\r
429 default:\r
430 ;\r
431 }\r
432 return TPM_PP_BIOS_FAILURE;\r
433}\r
434\r
435\r
436/**\r
437 Read the specified key for user confirmation.\r
438\r
439 @param[in] CautionKey If true, F12 is used as confirm key;\r
440 If false, F10 is used as confirm key.\r
441\r
442 @retval TRUE User confirmed the changes by input.\r
48211402 443 @retval FALSE User discarded the changes or device error.\r
0c18794e 444\r
445**/\r
446BOOLEAN\r
447ReadUserKey (\r
448 IN BOOLEAN CautionKey\r
449 )\r
450{\r
451 EFI_STATUS Status;\r
452 EFI_INPUT_KEY Key;\r
453 UINT16 InputKey;\r
48211402 454 UINTN Index;\r
455\r
0c18794e 456 InputKey = 0; \r
457 do {\r
48211402 458 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
459 if (Status == EFI_NOT_READY) {\r
460 gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);\r
461 continue;\r
462 }\r
463\r
464 if (Status == EFI_DEVICE_ERROR) {\r
465 return FALSE;\r
466 }\r
467\r
468 if (Key.ScanCode == SCAN_ESC) {\r
469 InputKey = Key.ScanCode;\r
470 }\r
471 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {\r
472 InputKey = Key.ScanCode;\r
473 }\r
474 if ((Key.ScanCode == SCAN_F12) && CautionKey) {\r
475 InputKey = Key.ScanCode;\r
476 }\r
0c18794e 477 } while (InputKey == 0);\r
478\r
0c18794e 479 if (InputKey != SCAN_ESC) {\r
480 return TRUE;\r
481 }\r
482 \r
483 return FALSE;\r
484}\r
485\r
607599bf 486/**\r
487 The constructor function register UNI strings into imageHandle.\r
488 \r
489 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
490\r
491 @param ImageHandle The firmware allocated handle for the EFI image.\r
492 @param SystemTable A pointer to the EFI System Table.\r
493 \r
494 @retval EFI_SUCCESS The constructor successfully added string package.\r
495 @retval Other value The constructor can't add string package.\r
496\r
497**/\r
498EFI_STATUS\r
499EFIAPI\r
500TcgPhysicalPresenceLibConstructor (\r
501 IN EFI_HANDLE ImageHandle,\r
502 IN EFI_SYSTEM_TABLE *SystemTable\r
503 )\r
504{\r
6f0b8648 505 mPpStringPackHandle = HiiAddPackages (&gEfiPhysicalPresenceGuid, ImageHandle, DxeTcgPhysicalPresenceLibStrings, NULL);\r
607599bf 506 ASSERT (mPpStringPackHandle != NULL);\r
507\r
508 return EFI_SUCCESS;\r
509}\r
510\r
0c18794e 511/**\r
512 Display the confirm text and get user confirmation.\r
513\r
514 @param[in] TpmPpCommand The requested TPM physical presence command.\r
515\r
607599bf 516 @retval TRUE The user has confirmed the changes.\r
517 @retval FALSE The user doesn't confirm the changes.\r
0c18794e 518**/\r
519BOOLEAN\r
520UserConfirm (\r
521 IN UINT8 TpmPpCommand\r
522 )\r
523{\r
524 CHAR16 *ConfirmText;\r
525 CHAR16 *TmpStr1;\r
526 CHAR16 *TmpStr2; \r
527 UINTN BufSize;\r
528 BOOLEAN CautionKey;\r
529 UINT16 Index;\r
530 CHAR16 DstStr[81];\r
531 \r
532 TmpStr2 = NULL;\r
533 CautionKey = FALSE;\r
534 BufSize = CONFIRM_BUFFER_SIZE;\r
535 ConfirmText = AllocateZeroPool (BufSize);\r
536 ASSERT (ConfirmText != NULL);\r
537\r
0c18794e 538 switch (TpmPpCommand) {\r
607599bf 539 case PHYSICAL_PRESENCE_ENABLE:\r
540 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE));\r
0c18794e 541 \r
607599bf 542 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 543 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
544 FreePool (TmpStr1);\r
545\r
607599bf 546 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 547 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
548 FreePool (TmpStr1);\r
549 break;\r
550\r
607599bf 551 case PHYSICAL_PRESENCE_DISABLE:\r
552 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE));\r
0c18794e 553 \r
607599bf 554 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 555 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
556 FreePool (TmpStr1);\r
557\r
607599bf 558 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));\r
0c18794e 559 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
560 FreePool (TmpStr1);\r
561\r
607599bf 562 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 563 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
564 FreePool (TmpStr1);\r
565 break;\r
566 \r
607599bf 567 case PHYSICAL_PRESENCE_ACTIVATE:\r
568 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE));\r
0c18794e 569 \r
607599bf 570 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 571 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
572 FreePool (TmpStr1);\r
573\r
607599bf 574 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 575 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
576 FreePool (TmpStr1);\r
577 break;\r
578\r
607599bf 579 case PHYSICAL_PRESENCE_DEACTIVATE:\r
580 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE));\r
0c18794e 581\r
607599bf 582 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 583 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
584 FreePool (TmpStr1);\r
585\r
607599bf 586 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));\r
0c18794e 587 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
588 FreePool (TmpStr1);\r
589\r
607599bf 590 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 591 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
592 FreePool (TmpStr1); \r
593 break;\r
594\r
607599bf 595 case PHYSICAL_PRESENCE_CLEAR:\r
0c18794e 596 CautionKey = TRUE;\r
607599bf 597 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
0c18794e 598\r
607599bf 599 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 600 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
601 FreePool (TmpStr1);\r
602\r
607599bf 603 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
0c18794e 604 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
605 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
606 FreePool (TmpStr1); \r
607\r
607599bf 608 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 609 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
610 FreePool (TmpStr1);\r
611 break;\r
612\r
607599bf 613 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:\r
614 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE));\r
0c18794e 615\r
607599bf 616 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 617 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
618 FreePool (TmpStr1);\r
619\r
607599bf 620 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));\r
0c18794e 621 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
622 FreePool (TmpStr1);\r
623\r
607599bf 624 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 625 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
626 FreePool (TmpStr1);\r
627 break;\r
628\r
607599bf 629 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:\r
630 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE));\r
0c18794e 631 \r
607599bf 632 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); \r
0c18794e 633 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
634 FreePool (TmpStr1);\r
635\r
607599bf 636 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));\r
0c18794e 637 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
638 FreePool (TmpStr1);\r
639 \r
607599bf 640 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));\r
0c18794e 641 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
642 FreePool (TmpStr1);\r
643\r
607599bf 644 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 645 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
646 FreePool (TmpStr1);\r
647 break;\r
648\r
607599bf 649 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:\r
650 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP));\r
0c18794e 651 \r
607599bf 652 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); \r
0c18794e 653 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
654 FreePool (TmpStr1);\r
655\r
607599bf 656 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 657 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
658 FreePool (TmpStr1);\r
659 break;\r
660\r
607599bf 661 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:\r
662 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP));\r
0c18794e 663 \r
607599bf 664 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); \r
0c18794e 665 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
666 FreePool (TmpStr1);\r
667\r
607599bf 668 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 669 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
670 FreePool (TmpStr1);\r
671 break;\r
672\r
607599bf 673 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:\r
674 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON));\r
0c18794e 675\r
607599bf 676 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 677 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
678 FreePool (TmpStr1);\r
679\r
607599bf 680 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));\r
0c18794e 681 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
682 FreePool (TmpStr1);\r
683\r
607599bf 684 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 685 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
686 FreePool (TmpStr1);\r
687 break;\r
688\r
607599bf 689 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:\r
690 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF));\r
0c18794e 691 \r
607599bf 692 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR)); \r
0c18794e 693 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
694 FreePool (TmpStr1);\r
695\r
607599bf 696 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));\r
0c18794e 697 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
698 FreePool (TmpStr1);\r
699 \r
607599bf 700 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));\r
0c18794e 701 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
702 FreePool (TmpStr1);\r
703\r
607599bf 704 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 705 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
706 FreePool (TmpStr1);\r
707 break;\r
708\r
607599bf 709 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
0c18794e 710 CautionKey = TRUE;\r
607599bf 711 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE));\r
0c18794e 712 \r
607599bf 713 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR)); \r
0c18794e 714 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
715 FreePool (TmpStr1);\r
716 \r
607599bf 717 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));\r
0c18794e 718 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
719 FreePool (TmpStr1);\r
720\r
607599bf 721 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 722 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
723 FreePool (TmpStr1);\r
724 break;\r
725\r
607599bf 726 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:\r
0c18794e 727 //\r
728 // TPM_SetOperatorAuth\r
729 // This command requires UI to prompt user for Auth data\r
730 // Here it is NOT implemented\r
731 //\r
732 break;\r
733\r
607599bf 734 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:\r
0c18794e 735 CautionKey = TRUE;\r
607599bf 736 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON));\r
0c18794e 737\r
607599bf 738 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 739 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
740 FreePool (TmpStr1);\r
741\r
607599bf 742 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));\r
0c18794e 743 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
744 FreePool (TmpStr1);\r
745\r
607599bf 746 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
0c18794e 747 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
748 FreePool (TmpStr1);\r
749\r
607599bf 750 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));\r
0c18794e 751 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
752 FreePool (TmpStr1);\r
753\r
607599bf 754 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 755 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
756 FreePool (TmpStr1);\r
757 break;\r
758\r
607599bf 759 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:\r
760 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION));\r
0c18794e 761\r
607599bf 762 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
0c18794e 763 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
764 FreePool (TmpStr1);\r
765\r
607599bf 766 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));\r
0c18794e 767 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
768 FreePool (TmpStr1);\r
769\r
607599bf 770 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
0c18794e 771 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
772 FreePool (TmpStr1);\r
773 break;\r
774\r
607599bf 775 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
0c18794e 776 CautionKey = TRUE;\r
607599bf 777 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));\r
0c18794e 778\r
607599bf 779 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
0c18794e 780 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
781 FreePool (TmpStr1);\r
782\r
607599bf 783 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));\r
0c18794e 784 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
785 FreePool (TmpStr1);\r
786\r
607599bf 787 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
0c18794e 788 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
789 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
790 FreePool (TmpStr1); \r
791\r
607599bf 792 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 793 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
794 FreePool (TmpStr1);\r
795\r
607599bf 796 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
0c18794e 797 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
798 FreePool (TmpStr1);\r
799 break;\r
800\r
607599bf 801 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:\r
0c18794e 802 CautionKey = TRUE;\r
607599bf 803 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN));\r
0c18794e 804\r
607599bf 805 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));\r
0c18794e 806 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
807 FreePool (TmpStr1);\r
808\r
607599bf 809 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));\r
0c18794e 810 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
811 FreePool (TmpStr1);\r
812\r
607599bf 813 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 814 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
815 FreePool (TmpStr1);\r
816\r
607599bf 817 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));\r
0c18794e 818 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
819 FreePool (TmpStr1);\r
820 break;\r
821\r
607599bf 822 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:\r
0c18794e 823 CautionKey = TRUE;\r
607599bf 824 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR));\r
0c18794e 825\r
607599bf 826 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 827 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
828 FreePool (TmpStr1);\r
829\r
607599bf 830 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
0c18794e 831 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
832 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
833 FreePool (TmpStr1);\r
834\r
607599bf 835 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 836 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
837 FreePool (TmpStr1);\r
838 break;\r
839\r
607599bf 840 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
0c18794e 841 CautionKey = TRUE;\r
607599bf 842 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE));\r
0c18794e 843\r
607599bf 844 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));\r
0c18794e 845 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);\r
846 FreePool (TmpStr1);\r
847\r
607599bf 848 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));\r
0c18794e 849 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
850 FreePool (TmpStr1);\r
851\r
607599bf 852 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));\r
0c18794e 853 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
854 FreePool (TmpStr1);\r
855\r
607599bf 856 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));\r
0c18794e 857 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
858 FreePool (TmpStr1);\r
859\r
607599bf 860 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));\r
0c18794e 861 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);\r
862 FreePool (TmpStr1);\r
863 break;\r
864\r
865 default:\r
866 ;\r
867 }\r
868\r
869 if (TmpStr2 == NULL) {\r
870 FreePool (ConfirmText);\r
871 return FALSE;\r
872 }\r
873\r
607599bf 874 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));\r
0c18794e 875 BufSize -= StrSize (ConfirmText);\r
876 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);\r
877\r
878 DstStr[80] = L'\0';\r
879 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {\r
880 StrnCpy(DstStr, ConfirmText + Index, 80); \r
881 Print (DstStr); \r
882 }\r
883 \r
884 FreePool (TmpStr1);\r
885 FreePool (TmpStr2);\r
886 FreePool (ConfirmText);\r
887\r
888 if (ReadUserKey (CautionKey)) {\r
889 return TRUE;\r
890 }\r
891\r
892 return FALSE; \r
893}\r
894\r
895/**\r
48211402 896 Check if there is a valid physical presence command request. Also updates parameter value \r
897 to whether the requested physical presence command already confirmed by user\r
898 \r
8c3883b6 899 @param[in] TcgPpData EFI TCG Physical Presence request data. \r
48211402 900 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.\r
901 True, it indicates the command doesn't require user confirm, or already confirmed \r
902 in last boot cycle by user.\r
903 False, it indicates the command need user confirm from UI.\r
904\r
905 @retval TRUE Physical Presence operation command is valid.\r
906 @retval FALSE Physical Presence operation command is invalid.\r
0c18794e 907\r
908**/\r
48211402 909BOOLEAN\r
910HaveValidTpmRequest (\r
911 IN EFI_PHYSICAL_PRESENCE *TcgPpData,\r
912 OUT BOOLEAN *RequestConfirmed\r
0c18794e 913 )\r
914{\r
0c18794e 915 UINT8 Flags;\r
48211402 916 \r
917 Flags = TcgPpData->Flags;\r
918 *RequestConfirmed = FALSE;\r
0c18794e 919\r
0c18794e 920 switch (TcgPpData->PPRequest) {\r
607599bf 921 case PHYSICAL_PRESENCE_NO_ACTION:\r
48211402 922 *RequestConfirmed = TRUE;\r
923 return TRUE;\r
607599bf 924 case PHYSICAL_PRESENCE_ENABLE:\r
925 case PHYSICAL_PRESENCE_DISABLE:\r
926 case PHYSICAL_PRESENCE_ACTIVATE:\r
927 case PHYSICAL_PRESENCE_DEACTIVATE:\r
928 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:\r
929 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:\r
930 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:\r
931 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:\r
932 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:\r
933 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:\r
934 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:\r
0c18794e 935 if ((Flags & FLAG_NO_PPI_PROVISION) != 0) {\r
48211402 936 *RequestConfirmed = TRUE;\r
0c18794e 937 }\r
938 break;\r
939\r
607599bf 940 case PHYSICAL_PRESENCE_CLEAR:\r
941 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:\r
0c18794e 942 if ((Flags & FLAG_NO_PPI_CLEAR) != 0) {\r
48211402 943 *RequestConfirmed = TRUE;\r
0c18794e 944 }\r
945 break;\r
946\r
607599bf 947 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
0c18794e 948 if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) {\r
48211402 949 *RequestConfirmed = TRUE;\r
0c18794e 950 }\r
951 break;\r
952\r
607599bf 953 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:\r
954 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
0c18794e 955 if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) {\r
48211402 956 *RequestConfirmed = TRUE;\r
0c18794e 957 }\r
48211402 958 break;\r
0c18794e 959\r
607599bf 960 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:\r
961 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
962 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:\r
48211402 963 *RequestConfirmed = TRUE;\r
0c18794e 964 break;\r
48211402 965\r
477be7c4 966 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:\r
967 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
968 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:\r
969 break;\r
48211402 970\r
568e7b27 971 default:\r
972 //\r
48211402 973 // Wrong Physical Presence command\r
568e7b27 974 //\r
48211402 975 return FALSE;\r
0c18794e 976 }\r
977\r
978 if ((Flags & FLAG_RESET_TRACK) != 0) {\r
979 //\r
980 // It had been confirmed in last boot, it doesn't need confirm again.\r
981 //\r
48211402 982 *RequestConfirmed = TRUE;\r
983 }\r
984\r
985 //\r
986 // Physical Presence command is correct\r
987 //\r
988 return TRUE;\r
989}\r
990\r
991\r
992/**\r
993 Check and execute the requested physical presence command.\r
994\r
995 Caution: This function may receive untrusted input.\r
996 TcgPpData variable is external input, so this function will validate\r
997 its data structure to be valid value.\r
998\r
999 @param[in] TcgProtocol EFI TCG Protocol instance. \r
1000 @param[in] TcgPpData Point to the physical presence NV variable.\r
1001\r
1002**/\r
1003VOID\r
1004ExecutePendingTpmRequest (\r
1005 IN EFI_TCG_PROTOCOL *TcgProtocol,\r
1006 IN EFI_PHYSICAL_PRESENCE *TcgPpData\r
1007 )\r
1008{\r
1009 EFI_STATUS Status;\r
1010 UINTN DataSize;\r
1011 BOOLEAN RequestConfirmed;\r
1012\r
48211402 1013 if (!HaveValidTpmRequest(TcgPpData, &RequestConfirmed)) {\r
1014 //\r
1015 // Invalid operation request.\r
1016 //\r
1017 TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE;\r
1018 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
1019 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;\r
1020 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
1021 Status = gRT->SetVariable (\r
1022 PHYSICAL_PRESENCE_VARIABLE,\r
1023 &gEfiPhysicalPresenceGuid,\r
1024 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1025 DataSize,\r
1026 TcgPpData\r
1027 );\r
1028 return;\r
0c18794e 1029 }\r
1030\r
1031 if (!RequestConfirmed) {\r
1032 //\r
1033 // Print confirm text and wait for approval. \r
1034 //\r
1035 RequestConfirmed = UserConfirm (TcgPpData->PPRequest);\r
1036 }\r
1037\r
1038 //\r
607599bf 1039 // Execute requested physical presence command\r
0c18794e 1040 //\r
1041 TcgPpData->PPResponse = TPM_PP_USER_ABORT;\r
1042 if (RequestConfirmed) {\r
0c18794e 1043 TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags);\r
1044 }\r
1045\r
1046 //\r
1047 // Clear request\r
1048 //\r
1049 if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {\r
1050 TcgPpData->LastPPRequest = TcgPpData->PPRequest;\r
568e7b27 1051 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION; \r
0c18794e 1052 }\r
1053\r
1054 //\r
1055 // Save changes\r
1056 //\r
1057 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
1058 Status = gRT->SetVariable (\r
1059 PHYSICAL_PRESENCE_VARIABLE,\r
1060 &gEfiPhysicalPresenceGuid,\r
1061 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1062 DataSize,\r
1063 TcgPpData\r
1064 );\r
1065 if (EFI_ERROR (Status)) {\r
1066 return;\r
1067 }\r
1068\r
1069 if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) {\r
1070 return;\r
1071 }\r
1072\r
1073 //\r
1074 // Reset system to make new TPM settings in effect\r
1075 //\r
1076 switch (TcgPpData->LastPPRequest) {\r
607599bf 1077 case PHYSICAL_PRESENCE_ACTIVATE:\r
1078 case PHYSICAL_PRESENCE_DEACTIVATE:\r
1079 case PHYSICAL_PRESENCE_CLEAR:\r
1080 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:\r
1081 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:\r
1082 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:\r
1083 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:\r
1084 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
1085 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:\r
1086 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:\r
1087 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE: \r
0c18794e 1088 break;\r
1089 default:\r
568e7b27 1090 if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) {\r
0c18794e 1091 break;\r
1092 }\r
1093 return;\r
1094 }\r
1095\r
1096 Print (L"Rebooting system to make TPM settings in effect\n");\r
1097 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
1098 ASSERT (FALSE); \r
1099}\r
1100\r
1101/**\r
607599bf 1102 Check and execute the pending TPM request and Lock TPM.\r
0c18794e 1103\r
607599bf 1104 The TPM request may come from OS or BIOS. This API will display request information and wait \r
1105 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after\r
1106 the TPM request is confirmed, and one or more reset may be required to make TPM request to \r
1107 take effect. At last, it will lock TPM to prevent TPM state change by malware.\r
1108 \r
1109 This API should be invoked after console in and console out are all ready as they are required\r
1110 to display request information and get user input to confirm the request. This API should also \r
1111 be invoked as early as possible as TPM is locked in this function.\r
1112 \r
0c18794e 1113**/\r
1114VOID\r
1115EFIAPI\r
607599bf 1116TcgPhysicalPresenceLibProcessRequest (\r
1117 VOID\r
0c18794e 1118 )\r
1119{\r
1120 EFI_STATUS Status;\r
1121 BOOLEAN LifetimeLock;\r
1122 BOOLEAN CmdEnable;\r
1123 UINTN DataSize;\r
1124 EFI_PHYSICAL_PRESENCE TcgPpData;\r
607599bf 1125 EFI_TCG_PROTOCOL *TcgProtocol;\r
1126 \r
1127 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
1128 if (EFI_ERROR (Status)) {\r
1129 return ;\r
1130 }\r
0c18794e 1131 \r
1132 //\r
607599bf 1133 // Initialize physical presence variable.\r
0c18794e 1134 //\r
1135 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
1136 Status = gRT->GetVariable (\r
1137 PHYSICAL_PRESENCE_VARIABLE,\r
1138 &gEfiPhysicalPresenceGuid,\r
1139 NULL,\r
1140 &DataSize,\r
1141 &TcgPpData\r
1142 );\r
607599bf 1143 if (EFI_ERROR (Status)) {\r
1144 if (Status == EFI_NOT_FOUND) {\r
1145 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));\r
1146 TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;\r
1147 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
1148 Status = gRT->SetVariable (\r
1149 PHYSICAL_PRESENCE_VARIABLE,\r
1150 &gEfiPhysicalPresenceGuid,\r
1151 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1152 DataSize,\r
1153 &TcgPpData\r
1154 );\r
1155 }\r
1156 ASSERT_EFI_ERROR (Status);\r
1157 }\r
1158\r
0c18794e 1159 DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest));\r
607599bf 1160\r
03ecb576 1161 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {\r
1162 //\r
1163 // No operation request\r
1164 //\r
1165 return;\r
1166 }\r
1167\r
607599bf 1168 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);\r
0c18794e 1169 if (EFI_ERROR (Status)) {\r
1170 return ;\r
1171 }\r
607599bf 1172 \r
0c18794e 1173 if (!CmdEnable) {\r
1174 if (LifetimeLock) {\r
1175 //\r
1176 // physicalPresenceCMDEnable is locked, can't execute physical presence command.\r
1177 //\r
1178 return ;\r
1179 }\r
607599bf 1180 Status = TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD_ENABLE);\r
0c18794e 1181 if (EFI_ERROR (Status)) {\r
1182 return ;\r
1183 }\r
1184 }\r
607599bf 1185 \r
0c18794e 1186 //\r
1187 // Set operator physical presence flags\r
1188 //\r
607599bf 1189 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESENT);\r
1190\r
0c18794e 1191 //\r
1192 // Execute pending TPM request.\r
1193 // \r
607599bf 1194 ExecutePendingTpmRequest (TcgProtocol, &TcgPpData);\r
0c18794e 1195 DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));\r
1196\r
1197 //\r
1198 // Lock physical presence.\r
1199 //\r
607599bf 1200 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK);\r
0c18794e 1201}\r
1202\r
48211402 1203/**\r
1204 Check if the pending TPM request needs user input to confirm.\r
1205\r
1206 The TPM request may come from OS. This API will check if TPM request exists and need user\r
1207 input to confirmation.\r
1208 \r
1209 @retval TRUE TPM needs input to confirm user physical presence.\r
1210 @retval FALSE TPM doesn't need input to confirm user physical presence.\r
1211\r
1212**/\r
1213BOOLEAN\r
1214EFIAPI\r
1215TcgPhysicalPresenceLibNeedUserConfirm(\r
1216 VOID\r
1217 )\r
1218{\r
1219 EFI_STATUS Status;\r
1220 EFI_PHYSICAL_PRESENCE TcgPpData;\r
1221 UINTN DataSize;\r
1222 BOOLEAN RequestConfirmed;\r
1223 BOOLEAN LifetimeLock;\r
1224 BOOLEAN CmdEnable;\r
1225 EFI_TCG_PROTOCOL *TcgProtocol;\r
1226\r
1227 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);\r
1228 if (EFI_ERROR (Status)) {\r
1229 return FALSE;\r
1230 }\r
1231\r
1232 //\r
1233 // Check Tpm requests\r
1234 //\r
1235 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
1236 Status = gRT->GetVariable (\r
1237 PHYSICAL_PRESENCE_VARIABLE,\r
1238 &gEfiPhysicalPresenceGuid,\r
1239 NULL,\r
1240 &DataSize,\r
1241 &TcgPpData\r
1242 );\r
1243 if (EFI_ERROR (Status)) {\r
1244 return FALSE;\r
1245 }\r
1246\r
1247 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {\r
1248 //\r
1249 // No operation request\r
1250 //\r
1251 return FALSE;\r
1252 }\r
1253\r
1254 if (!HaveValidTpmRequest(&TcgPpData, &RequestConfirmed)) {\r
1255 //\r
1256 // Invalid operation request.\r
1257 //\r
1258 return FALSE;\r
1259 }\r
1260\r
1261 //\r
1262 // Check Tpm Capability\r
1263 //\r
1264 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);\r
1265 if (EFI_ERROR (Status)) {\r
1266 return FALSE;\r
1267 }\r
1268\r
1269 if (!CmdEnable) {\r
1270 if (LifetimeLock) {\r
1271 //\r
1272 // physicalPresenceCMDEnable is locked, can't execute physical presence command.\r
1273 //\r
1274 return FALSE;\r
1275 }\r
1276 }\r
1277\r
1278 if (!RequestConfirmed) {\r
1279 //\r
1280 // Need UI to confirm\r
1281 //\r
1282 return TRUE;\r
1283 }\r
1284\r
1285 return FALSE;\r
1286}\r
1287\r