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