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