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