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