]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
Fix TCG PPI request EnableActivateClear failure.
[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 //
397 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR
398 // PHYSICAL_PRESENCE_CLEAR will be executed after reboot.
399 //
400 if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {
401 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
402 *PpiFlags |= FLAG_RESET_TRACK;
403 } else {
404 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);
405 *PpiFlags &= ~FLAG_RESET_TRACK;
406 }
407 return TpmResponse;
408
409 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
410 //
411 // PHYSICAL_PRESENCE_ENABLE_ACTIVATE + PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE
412 // PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE will be executed after reboot.
413 //
414 if ((*PpiFlags & FLAG_RESET_TRACK) == 0) {
415 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
416 *PpiFlags |= FLAG_RESET_TRACK;
417 } else {
418 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags);
419 *PpiFlags &= ~FLAG_RESET_TRACK;
420 }
421 return TpmResponse;
422
423 default:
424 ;
425 }
426 return TPM_PP_BIOS_FAILURE;
427 }
428
429
430 /**
431 Read the specified key for user confirmation.
432
433 @param[in] CautionKey If true, F12 is used as confirm key;
434 If false, F10 is used as confirm key.
435
436 @retval TRUE User confirmed the changes by input.
437 @retval FALSE User discarded the changes.
438
439 **/
440 BOOLEAN
441 ReadUserKey (
442 IN BOOLEAN CautionKey
443 )
444 {
445 EFI_STATUS Status;
446 EFI_INPUT_KEY Key;
447 UINT16 InputKey;
448
449 InputKey = 0;
450 do {
451 Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
452 if (!EFI_ERROR (Status)) {
453 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
454 if (Key.ScanCode == SCAN_ESC) {
455 InputKey = Key.ScanCode;
456 }
457 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
458 InputKey = Key.ScanCode;
459 }
460 if ((Key.ScanCode == SCAN_F12) && CautionKey) {
461 InputKey = Key.ScanCode;
462 }
463 }
464 } while (InputKey == 0);
465
466 if (InputKey != SCAN_ESC) {
467 return TRUE;
468 }
469
470 return FALSE;
471 }
472
473 /**
474 The constructor function register UNI strings into imageHandle.
475
476 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
477
478 @param ImageHandle The firmware allocated handle for the EFI image.
479 @param SystemTable A pointer to the EFI System Table.
480
481 @retval EFI_SUCCESS The constructor successfully added string package.
482 @retval Other value The constructor can't add string package.
483
484 **/
485 EFI_STATUS
486 EFIAPI
487 TcgPhysicalPresenceLibConstructor (
488 IN EFI_HANDLE ImageHandle,
489 IN EFI_SYSTEM_TABLE *SystemTable
490 )
491 {
492 mPpStringPackHandle = HiiAddPackages (&gEfiPhysicalPresenceGuid, ImageHandle, DxeTcgPhysicalPresenceLibStrings, NULL);
493 ASSERT (mPpStringPackHandle != NULL);
494
495 return EFI_SUCCESS;
496 }
497
498 /**
499 Display the confirm text and get user confirmation.
500
501 @param[in] TpmPpCommand The requested TPM physical presence command.
502
503 @retval TRUE The user has confirmed the changes.
504 @retval FALSE The user doesn't confirm the changes.
505 **/
506 BOOLEAN
507 UserConfirm (
508 IN UINT8 TpmPpCommand
509 )
510 {
511 CHAR16 *ConfirmText;
512 CHAR16 *TmpStr1;
513 CHAR16 *TmpStr2;
514 UINTN BufSize;
515 BOOLEAN CautionKey;
516 UINT16 Index;
517 CHAR16 DstStr[81];
518
519 TmpStr2 = NULL;
520 CautionKey = FALSE;
521 BufSize = CONFIRM_BUFFER_SIZE;
522 ConfirmText = AllocateZeroPool (BufSize);
523 ASSERT (ConfirmText != NULL);
524
525 switch (TpmPpCommand) {
526 case PHYSICAL_PRESENCE_ENABLE:
527 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE));
528
529 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
530 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
531 FreePool (TmpStr1);
532
533 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
534 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
535 FreePool (TmpStr1);
536 break;
537
538 case PHYSICAL_PRESENCE_DISABLE:
539 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE));
540
541 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
542 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
543 FreePool (TmpStr1);
544
545 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
546 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
547 FreePool (TmpStr1);
548
549 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
550 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
551 FreePool (TmpStr1);
552 break;
553
554 case PHYSICAL_PRESENCE_ACTIVATE:
555 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE));
556
557 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
558 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
559 FreePool (TmpStr1);
560
561 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
562 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
563 FreePool (TmpStr1);
564 break;
565
566 case PHYSICAL_PRESENCE_DEACTIVATE:
567 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE));
568
569 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
570 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
571 FreePool (TmpStr1);
572
573 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
574 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
575 FreePool (TmpStr1);
576
577 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
578 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
579 FreePool (TmpStr1);
580 break;
581
582 case PHYSICAL_PRESENCE_CLEAR:
583 CautionKey = TRUE;
584 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
585
586 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
587 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
588 FreePool (TmpStr1);
589
590 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
591 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
592 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
593 FreePool (TmpStr1);
594
595 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
596 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
597 FreePool (TmpStr1);
598 break;
599
600 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
601 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE));
602
603 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
604 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
605 FreePool (TmpStr1);
606
607 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
608 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
609 FreePool (TmpStr1);
610
611 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
612 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
613 FreePool (TmpStr1);
614 break;
615
616 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
617 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE));
618
619 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
620 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
621 FreePool (TmpStr1);
622
623 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
624 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
625 FreePool (TmpStr1);
626
627 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
628 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
629 FreePool (TmpStr1);
630
631 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
632 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
633 FreePool (TmpStr1);
634 break;
635
636 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
637 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP));
638
639 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
640 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
641 FreePool (TmpStr1);
642
643 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
644 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
645 FreePool (TmpStr1);
646 break;
647
648 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
649 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP));
650
651 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
652 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
653 FreePool (TmpStr1);
654
655 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
656 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
657 FreePool (TmpStr1);
658 break;
659
660 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
661 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON));
662
663 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
664 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
665 FreePool (TmpStr1);
666
667 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
668 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
669 FreePool (TmpStr1);
670
671 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
672 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
673 FreePool (TmpStr1);
674 break;
675
676 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
677 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF));
678
679 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
680 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
681 FreePool (TmpStr1);
682
683 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
684 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
685 FreePool (TmpStr1);
686
687 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
688 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
689 FreePool (TmpStr1);
690
691 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
692 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
693 FreePool (TmpStr1);
694 break;
695
696 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
697 CautionKey = TRUE;
698 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE));
699
700 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR));
701 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
702 FreePool (TmpStr1);
703
704 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
705 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
706 FreePool (TmpStr1);
707
708 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
709 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
710 FreePool (TmpStr1);
711 break;
712
713 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
714 //
715 // TPM_SetOperatorAuth
716 // This command requires UI to prompt user for Auth data
717 // Here it is NOT implemented
718 //
719 break;
720
721 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
722 CautionKey = TRUE;
723 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON));
724
725 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
726 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
727 FreePool (TmpStr1);
728
729 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
730 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
731 FreePool (TmpStr1);
732
733 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
734 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
735 FreePool (TmpStr1);
736
737 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
738 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
739 FreePool (TmpStr1);
740
741 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
742 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
743 FreePool (TmpStr1);
744 break;
745
746 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
747 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION));
748
749 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
750 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
751 FreePool (TmpStr1);
752
753 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
754 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
755 FreePool (TmpStr1);
756
757 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
758 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
759 FreePool (TmpStr1);
760 break;
761
762 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
763 CautionKey = TRUE;
764 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
765
766 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
767 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
768 FreePool (TmpStr1);
769
770 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
771 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
772 FreePool (TmpStr1);
773
774 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
775 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
776 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
777 FreePool (TmpStr1);
778
779 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
780 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
781 FreePool (TmpStr1);
782
783 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
784 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
785 FreePool (TmpStr1);
786 break;
787
788 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
789 CautionKey = TRUE;
790 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN));
791
792 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
793 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
794 FreePool (TmpStr1);
795
796 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
797 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
798 FreePool (TmpStr1);
799
800 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
801 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
802 FreePool (TmpStr1);
803
804 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
805 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
806 FreePool (TmpStr1);
807 break;
808
809 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
810 CautionKey = TRUE;
811 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR));
812
813 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
814 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
815 FreePool (TmpStr1);
816
817 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
818 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
819 StrnCat (ConfirmText, L" \n\n", (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
820 FreePool (TmpStr1);
821
822 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
823 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
824 FreePool (TmpStr1);
825 break;
826
827 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
828 CautionKey = TRUE;
829 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE));
830
831 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
832 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
833 FreePool (TmpStr1);
834
835 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
836 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
837 FreePool (TmpStr1);
838
839 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
840 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
841 FreePool (TmpStr1);
842
843 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
844 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
845 FreePool (TmpStr1);
846
847 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
848 StrnCat (ConfirmText, TmpStr1, (BufSize / sizeof (CHAR16 *)) - StrLen (ConfirmText) - 1);
849 FreePool (TmpStr1);
850 break;
851
852 default:
853 ;
854 }
855
856 if (TmpStr2 == NULL) {
857 FreePool (ConfirmText);
858 return FALSE;
859 }
860
861 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
862 BufSize -= StrSize (ConfirmText);
863 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
864
865 DstStr[80] = L'\0';
866 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
867 StrnCpy(DstStr, ConfirmText + Index, 80);
868 Print (DstStr);
869 }
870
871 FreePool (TmpStr1);
872 FreePool (TmpStr2);
873 FreePool (ConfirmText);
874
875 if (ReadUserKey (CautionKey)) {
876 return TRUE;
877 }
878
879 return FALSE;
880 }
881
882 /**
883 Check and execute the requested physical presence command.
884
885 @param[in] TcgProtocol EFI TCG Protocol instance.
886 @param[in] TcgPpData Point to the physical presence NV variable.
887
888 **/
889 VOID
890 ExecutePendingTpmRequest (
891 IN EFI_TCG_PROTOCOL *TcgProtocol,
892 IN EFI_PHYSICAL_PRESENCE *TcgPpData
893 )
894 {
895 EFI_STATUS Status;
896 UINTN DataSize;
897 UINT8 Flags;
898 BOOLEAN RequestConfirmed;
899
900 Flags = TcgPpData->Flags;
901 RequestConfirmed = FALSE;
902 switch (TcgPpData->PPRequest) {
903 case PHYSICAL_PRESENCE_NO_ACTION:
904 return;
905 case PHYSICAL_PRESENCE_ENABLE:
906 case PHYSICAL_PRESENCE_DISABLE:
907 case PHYSICAL_PRESENCE_ACTIVATE:
908 case PHYSICAL_PRESENCE_DEACTIVATE:
909 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
910 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
911 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
912 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
913 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
914 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
915 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
916 if ((Flags & FLAG_NO_PPI_PROVISION) != 0) {
917 RequestConfirmed = TRUE;
918 }
919 break;
920
921 case PHYSICAL_PRESENCE_CLEAR:
922 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
923 if ((Flags & FLAG_NO_PPI_CLEAR) != 0) {
924 RequestConfirmed = TRUE;
925 }
926 break;
927
928 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
929 if ((Flags & FLAG_NO_PPI_MAINTENANCE) != 0) {
930 RequestConfirmed = TRUE;
931 }
932 break;
933
934 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
935 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
936 if ((Flags & FLAG_NO_PPI_CLEAR) != 0 && (Flags & FLAG_NO_PPI_PROVISION) != 0) {
937 RequestConfirmed = TRUE;
938 }
939 break;
940
941 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:
942 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
943 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
944 RequestConfirmed = TRUE;
945 break;
946
947 default:
948 //
949 // Invalid operation request.
950 //
951 TcgPpData->PPResponse = TPM_PP_BIOS_FAILURE;
952 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
953 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
954 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
955 Status = gRT->SetVariable (
956 PHYSICAL_PRESENCE_VARIABLE,
957 &gEfiPhysicalPresenceGuid,
958 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
959 DataSize,
960 TcgPpData
961 );
962 return;
963 }
964
965 if ((Flags & FLAG_RESET_TRACK) != 0) {
966 //
967 // It had been confirmed in last boot, it doesn't need confirm again.
968 //
969 RequestConfirmed = TRUE;
970 }
971
972 if (!RequestConfirmed) {
973 //
974 // Print confirm text and wait for approval.
975 //
976 RequestConfirmed = UserConfirm (TcgPpData->PPRequest);
977 }
978
979 //
980 // Execute requested physical presence command
981 //
982 TcgPpData->PPResponse = TPM_PP_USER_ABORT;
983 if (RequestConfirmed) {
984 TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &TcgPpData->Flags);
985 }
986
987 //
988 // Clear request
989 //
990 if ((TcgPpData->Flags & FLAG_RESET_TRACK) == 0) {
991 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
992 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
993 }
994
995 //
996 // Save changes
997 //
998 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
999 Status = gRT->SetVariable (
1000 PHYSICAL_PRESENCE_VARIABLE,
1001 &gEfiPhysicalPresenceGuid,
1002 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1003 DataSize,
1004 TcgPpData
1005 );
1006 if (EFI_ERROR (Status)) {
1007 return;
1008 }
1009
1010 if (TcgPpData->PPResponse == TPM_PP_USER_ABORT) {
1011 return;
1012 }
1013
1014 //
1015 // Reset system to make new TPM settings in effect
1016 //
1017 switch (TcgPpData->LastPPRequest) {
1018 case PHYSICAL_PRESENCE_ACTIVATE:
1019 case PHYSICAL_PRESENCE_DEACTIVATE:
1020 case PHYSICAL_PRESENCE_CLEAR:
1021 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
1022 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
1023 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
1024 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
1025 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
1026 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
1027 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
1028 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
1029 break;
1030 default:
1031 if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) {
1032 break;
1033 }
1034 return;
1035 }
1036
1037 Print (L"Rebooting system to make TPM settings in effect\n");
1038 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1039 ASSERT (FALSE);
1040 }
1041
1042 /**
1043 Check and execute the pending TPM request and Lock TPM.
1044
1045 The TPM request may come from OS or BIOS. This API will display request information and wait
1046 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
1047 the TPM request is confirmed, and one or more reset may be required to make TPM request to
1048 take effect. At last, it will lock TPM to prevent TPM state change by malware.
1049
1050 This API should be invoked after console in and console out are all ready as they are required
1051 to display request information and get user input to confirm the request. This API should also
1052 be invoked as early as possible as TPM is locked in this function.
1053
1054 **/
1055 VOID
1056 EFIAPI
1057 TcgPhysicalPresenceLibProcessRequest (
1058 VOID
1059 )
1060 {
1061 EFI_STATUS Status;
1062 BOOLEAN LifetimeLock;
1063 BOOLEAN CmdEnable;
1064 UINTN DataSize;
1065 EFI_PHYSICAL_PRESENCE TcgPpData;
1066 EFI_TCG_PROTOCOL *TcgProtocol;
1067
1068 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
1069 if (EFI_ERROR (Status)) {
1070 return ;
1071 }
1072
1073 //
1074 // Initialize physical presence variable.
1075 //
1076 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1077 Status = gRT->GetVariable (
1078 PHYSICAL_PRESENCE_VARIABLE,
1079 &gEfiPhysicalPresenceGuid,
1080 NULL,
1081 &DataSize,
1082 &TcgPpData
1083 );
1084 if (EFI_ERROR (Status)) {
1085 if (Status == EFI_NOT_FOUND) {
1086 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
1087 TcgPpData.Flags |= FLAG_NO_PPI_PROVISION;
1088 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1089 Status = gRT->SetVariable (
1090 PHYSICAL_PRESENCE_VARIABLE,
1091 &gEfiPhysicalPresenceGuid,
1092 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1093 DataSize,
1094 &TcgPpData
1095 );
1096 }
1097 ASSERT_EFI_ERROR (Status);
1098 }
1099
1100 DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", TcgPpData.Flags, TcgPpData.PPRequest));
1101
1102 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);
1103 if (EFI_ERROR (Status)) {
1104 return ;
1105 }
1106
1107 if (!CmdEnable) {
1108 if (LifetimeLock) {
1109 //
1110 // physicalPresenceCMDEnable is locked, can't execute physical presence command.
1111 //
1112 return ;
1113 }
1114 Status = TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
1115 if (EFI_ERROR (Status)) {
1116 return ;
1117 }
1118 }
1119
1120 //
1121 // Set operator physical presence flags
1122 //
1123 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESENT);
1124
1125 //
1126 // Execute pending TPM request.
1127 //
1128 ExecutePendingTpmRequest (TcgProtocol, &TcgPpData);
1129 DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
1130
1131 //
1132 // Lock physical presence.
1133 //
1134 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK);
1135 }
1136