]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
SecurityPkg: Replace BSD License with BSD+Patent License
[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 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 TCG_PP_OPERATION_RESPONSE_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 UINT32
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 TCG_PP_OPERATION_RESPONSE_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 TCG_PP_OPERATION_RESPONSE_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 TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
231 @retval TCG_PP_OPERATION_RESPONSE_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 UINT32
237 ExecutePhysicalPresence (
238 IN EFI_TCG_PROTOCOL *TcgProtocol,
239 IN UINT32 CommandCode,
240 IN OUT EFI_PHYSICAL_PRESENCE_FLAGS *PpiFlags
241 )
242 {
243 BOOLEAN BoolVal;
244 UINT32 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->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
328 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
329 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
330 } else {
331 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE, PpiFlags);
332 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_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 TCG_PP_OPERATION_RESPONSE_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->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
373 return 0;
374
375 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
376 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
377 return 0;
378
379 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
380 PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;
381 return 0;
382
383 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
384 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR;
385 return 0;
386
387 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
388 PpiFlags->PPFlags &= ~TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE;
389 return 0;
390
391 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
392 PpiFlags->PPFlags |= TCG_BIOS_TPM_MANAGEMENT_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->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
401 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
402 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
403 } else {
404 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR, PpiFlags);
405 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_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->PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
415 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_ENABLE_ACTIVATE, PpiFlags);
416 PpiFlags->PPFlags |= TCG_VENDOR_LIB_FLAG_RESET_TRACK;
417 } else {
418 TpmResponse = ExecutePhysicalPresence (TcgProtocol, PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE, PpiFlags);
419 PpiFlags->PPFlags &= ~TCG_VENDOR_LIB_FLAG_RESET_TRACK;
420 }
421 return TpmResponse;
422
423 default:
424 ;
425 }
426 return TCG_PP_OPERATION_RESPONSE_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 or device error.
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 UINTN Index;
449
450 InputKey = 0;
451 do {
452 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
453 if (Status == EFI_NOT_READY) {
454 gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
455 continue;
456 }
457
458 if (Status == EFI_DEVICE_ERROR) {
459 return FALSE;
460 }
461
462 if (Key.ScanCode == SCAN_ESC) {
463 InputKey = Key.ScanCode;
464 }
465 if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
466 InputKey = Key.ScanCode;
467 }
468 if ((Key.ScanCode == SCAN_F12) && CautionKey) {
469 InputKey = Key.ScanCode;
470 }
471 } while (InputKey == 0);
472
473 if (InputKey != SCAN_ESC) {
474 return TRUE;
475 }
476
477 return FALSE;
478 }
479
480 /**
481 The constructor function register UNI strings into imageHandle.
482
483 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
484
485 @param ImageHandle The firmware allocated handle for the EFI image.
486 @param SystemTable A pointer to the EFI System Table.
487
488 @retval EFI_SUCCESS The constructor successfully added string package.
489 @retval Other value The constructor can't add string package.
490
491 **/
492 EFI_STATUS
493 EFIAPI
494 TcgPhysicalPresenceLibConstructor (
495 IN EFI_HANDLE ImageHandle,
496 IN EFI_SYSTEM_TABLE *SystemTable
497 )
498 {
499 mPpStringPackHandle = HiiAddPackages (&gEfiPhysicalPresenceGuid, ImageHandle, DxeTcgPhysicalPresenceLibStrings, NULL);
500 ASSERT (mPpStringPackHandle != NULL);
501
502 return EFI_SUCCESS;
503 }
504
505 /**
506 Display the confirm text and get user confirmation.
507
508 @param[in] TpmPpCommand The requested TPM physical presence command.
509
510 @retval TRUE The user has confirmed the changes.
511 @retval FALSE The user doesn't confirm the changes.
512 **/
513 BOOLEAN
514 UserConfirm (
515 IN UINT32 TpmPpCommand
516 )
517 {
518 CHAR16 *ConfirmText;
519 CHAR16 *TmpStr1;
520 CHAR16 *TmpStr2;
521 UINTN BufSize;
522 BOOLEAN CautionKey;
523 UINT16 Index;
524 CHAR16 DstStr[81];
525
526 TmpStr2 = NULL;
527 CautionKey = FALSE;
528 BufSize = CONFIRM_BUFFER_SIZE;
529 ConfirmText = AllocateZeroPool (BufSize);
530 ASSERT (ConfirmText != NULL);
531
532 switch (TpmPpCommand) {
533 case PHYSICAL_PRESENCE_ENABLE:
534 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE));
535
536 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
537 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
538 FreePool (TmpStr1);
539
540 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
541 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
542 FreePool (TmpStr1);
543 break;
544
545 case PHYSICAL_PRESENCE_DISABLE:
546 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISABLE));
547
548 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
549 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
550 FreePool (TmpStr1);
551
552 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
553 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
554 FreePool (TmpStr1);
555
556 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
557 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
558 FreePool (TmpStr1);
559 break;
560
561 case PHYSICAL_PRESENCE_ACTIVATE:
562 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACTIVATE));
563
564 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
565 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
566 FreePool (TmpStr1);
567
568 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
569 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
570 FreePool (TmpStr1);
571 break;
572
573 case PHYSICAL_PRESENCE_DEACTIVATE:
574 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE));
575
576 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
577 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
578 FreePool (TmpStr1);
579
580 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
581 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
582 FreePool (TmpStr1);
583
584 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
585 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
586 FreePool (TmpStr1);
587 break;
588
589 case PHYSICAL_PRESENCE_CLEAR:
590 CautionKey = TRUE;
591 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
592
593 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
594 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
595 FreePool (TmpStr1);
596
597 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
598 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
599 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
600 FreePool (TmpStr1);
601
602 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
603 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
604 FreePool (TmpStr1);
605 break;
606
607 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
608 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE));
609
610 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
611 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
612 FreePool (TmpStr1);
613
614 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
615 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
616 FreePool (TmpStr1);
617
618 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
619 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
620 FreePool (TmpStr1);
621 break;
622
623 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
624 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DEACTIVATE_DISABLE));
625
626 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
627 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
628 FreePool (TmpStr1);
629
630 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
631 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
632 FreePool (TmpStr1);
633
634 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
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_SET_OWNER_INSTALL_TRUE:
644 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ALLOW_TAKE_OWNERSHIP));
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_ACCEPT_KEY));
651 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
652 FreePool (TmpStr1);
653 break;
654
655 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
656 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_DISALLOW_TAKE_OWNERSHIP));
657
658 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
659 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
660 FreePool (TmpStr1);
661
662 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
663 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
664 FreePool (TmpStr1);
665 break;
666
667 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
668 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_ON));
669
670 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
671 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
672 FreePool (TmpStr1);
673
674 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
675 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
676 FreePool (TmpStr1);
677
678 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
679 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
680 FreePool (TmpStr1);
681 break;
682
683 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
684 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_TURN_OFF));
685
686 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
687 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
688 FreePool (TmpStr1);
689
690 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_OFF));
691 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
692 FreePool (TmpStr1);
693
694 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING));
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_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
704 CautionKey = TRUE;
705 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UNOWNED_FIELD_UPGRADE));
706
707 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_UPGRADE_HEAD_STR));
708 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
709 FreePool (TmpStr1);
710
711 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
712 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
713 FreePool (TmpStr1);
714
715 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
716 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
717 FreePool (TmpStr1);
718 break;
719
720 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
721 //
722 // TPM_SetOperatorAuth
723 // This command requires UI to prompt user for Auth data
724 // Here it is NOT implemented
725 //
726 break;
727
728 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
729 CautionKey = TRUE;
730 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR_TURN_ON));
731
732 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
733 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
734 FreePool (TmpStr1);
735
736 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
737 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
738 FreePool (TmpStr1);
739
740 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
741 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
742 FreePool (TmpStr1);
743
744 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
745 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
746 FreePool (TmpStr1);
747
748 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
749 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
750 FreePool (TmpStr1);
751 break;
752
753 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
754 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_PROVISION));
755
756 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
757 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
758 FreePool (TmpStr1);
759
760 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
761 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
762 FreePool (TmpStr1);
763
764 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
765 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
766 FreePool (TmpStr1);
767 break;
768
769 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
770 CautionKey = TRUE;
771 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
772
773 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
774 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
775 FreePool (TmpStr1);
776
777 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
778 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
779 FreePool (TmpStr1);
780
781 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
782 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
783 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
784 FreePool (TmpStr1);
785
786 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
787 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
788 FreePool (TmpStr1);
789
790 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
791 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
792 FreePool (TmpStr1);
793 break;
794
795 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
796 CautionKey = TRUE;
797 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_MAINTAIN));
798
799 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
800 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
801 FreePool (TmpStr1);
802
803 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_MAINTAIN));
804 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
805 FreePool (TmpStr1);
806
807 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
808 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
809 FreePool (TmpStr1);
810
811 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
812 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
813 FreePool (TmpStr1);
814 break;
815
816 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
817 CautionKey = TRUE;
818 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR));
819
820 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
821 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
822 FreePool (TmpStr1);
823
824 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
825 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
826 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
827 FreePool (TmpStr1);
828
829 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
830 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
831 FreePool (TmpStr1);
832 break;
833
834 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
835 CautionKey = TRUE;
836 TmpStr2 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE));
837
838 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
839 UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
840 FreePool (TmpStr1);
841
842 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_ON));
843 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
844 FreePool (TmpStr1);
845
846 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
847 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
848 FreePool (TmpStr1);
849
850 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR_CONT));
851 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
852 FreePool (TmpStr1);
853
854 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
855 StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
856 FreePool (TmpStr1);
857 break;
858
859 default:
860 ;
861 }
862
863 if (TmpStr2 == NULL) {
864 FreePool (ConfirmText);
865 return FALSE;
866 }
867
868 TmpStr1 = PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
869 BufSize -= StrSize (ConfirmText);
870 UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
871
872 DstStr[80] = L'\0';
873 for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
874 StrnCpyS(DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);
875 Print (DstStr);
876 }
877
878 FreePool (TmpStr1);
879 FreePool (TmpStr2);
880 FreePool (ConfirmText);
881
882 if (ReadUserKey (CautionKey)) {
883 return TRUE;
884 }
885
886 return FALSE;
887 }
888
889 /**
890 Check if there is a valid physical presence command request. Also updates parameter value
891 to whether the requested physical presence command already confirmed by user
892
893 @param[in] TcgPpData EFI TCG Physical Presence request data.
894 @param[in] Flags The physical presence interface flags.
895 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
896 True, it indicates the command doesn't require user confirm, or already confirmed
897 in last boot cycle by user.
898 False, it indicates the command need user confirm from UI.
899
900 @retval TRUE Physical Presence operation command is valid.
901 @retval FALSE Physical Presence operation command is invalid.
902
903 **/
904 BOOLEAN
905 HaveValidTpmRequest (
906 IN EFI_PHYSICAL_PRESENCE *TcgPpData,
907 IN EFI_PHYSICAL_PRESENCE_FLAGS Flags,
908 OUT BOOLEAN *RequestConfirmed
909 )
910 {
911 BOOLEAN IsRequestValid;
912
913 *RequestConfirmed = FALSE;
914
915 switch (TcgPpData->PPRequest) {
916 case PHYSICAL_PRESENCE_NO_ACTION:
917 *RequestConfirmed = TRUE;
918 return TRUE;
919 case PHYSICAL_PRESENCE_ENABLE:
920 case PHYSICAL_PRESENCE_DISABLE:
921 case PHYSICAL_PRESENCE_ACTIVATE:
922 case PHYSICAL_PRESENCE_DEACTIVATE:
923 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
924 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
925 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:
926 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:
927 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
928 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
929 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:
930 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {
931 *RequestConfirmed = TRUE;
932 }
933 break;
934
935 case PHYSICAL_PRESENCE_CLEAR:
936 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
937 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {
938 *RequestConfirmed = TRUE;
939 }
940 break;
941
942 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
943 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != 0) {
944 *RequestConfirmed = TRUE;
945 }
946 break;
947
948 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
949 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
950 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0 && (Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {
951 *RequestConfirmed = TRUE;
952 }
953 break;
954
955 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:
956 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:
957 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:
958 *RequestConfirmed = TRUE;
959 break;
960
961 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_TRUE:
962 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:
963 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_TRUE:
964 break;
965
966 default:
967 if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
968 IsRequestValid = TcgPpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);
969 if (!IsRequestValid) {
970 return FALSE;
971 } else {
972 break;
973 }
974 } else {
975 //
976 // Wrong Physical Presence command
977 //
978 return FALSE;
979 }
980 }
981
982 if ((Flags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) != 0) {
983 //
984 // It had been confirmed in last boot, it doesn't need confirm again.
985 //
986 *RequestConfirmed = TRUE;
987 }
988
989 //
990 // Physical Presence command is correct
991 //
992 return TRUE;
993 }
994
995
996 /**
997 Check and execute the requested physical presence command.
998
999 Caution: This function may receive untrusted input.
1000 TcgPpData variable is external input, so this function will validate
1001 its data structure to be valid value.
1002
1003 @param[in] TcgProtocol EFI TCG Protocol instance.
1004 @param[in] TcgPpData Point to the physical presence NV variable.
1005 @param[in] Flags The physical presence interface flags.
1006
1007 **/
1008 VOID
1009 ExecutePendingTpmRequest (
1010 IN EFI_TCG_PROTOCOL *TcgProtocol,
1011 IN EFI_PHYSICAL_PRESENCE *TcgPpData,
1012 IN EFI_PHYSICAL_PRESENCE_FLAGS Flags
1013 )
1014 {
1015 EFI_STATUS Status;
1016 UINTN DataSize;
1017 BOOLEAN RequestConfirmed;
1018 EFI_PHYSICAL_PRESENCE_FLAGS NewFlags;
1019 BOOLEAN ResetRequired;
1020 UINT32 NewPPFlags;
1021
1022 if (!HaveValidTpmRequest(TcgPpData, Flags, &RequestConfirmed)) {
1023 //
1024 // Invalid operation request.
1025 //
1026 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
1027 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
1028 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
1029 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1030 Status = gRT->SetVariable (
1031 PHYSICAL_PRESENCE_VARIABLE,
1032 &gEfiPhysicalPresenceGuid,
1033 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1034 DataSize,
1035 TcgPpData
1036 );
1037 return;
1038 }
1039
1040 ResetRequired = FALSE;
1041 if (TcgPpData->PPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
1042 NewFlags = Flags;
1043 NewPPFlags = NewFlags.PPFlags;
1044 TcgPpData->PPResponse = TcgPpVendorLibExecutePendingRequest (TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);
1045 NewFlags.PPFlags = (UINT8)NewPPFlags;
1046 } else {
1047 if (!RequestConfirmed) {
1048 //
1049 // Print confirm text and wait for approval.
1050 //
1051 RequestConfirmed = UserConfirm (TcgPpData->PPRequest);
1052 }
1053
1054 //
1055 // Execute requested physical presence command
1056 //
1057 TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;
1058 NewFlags = Flags;
1059 if (RequestConfirmed) {
1060 TcgPpData->PPResponse = ExecutePhysicalPresence (TcgProtocol, TcgPpData->PPRequest, &NewFlags);
1061 }
1062 }
1063
1064 //
1065 // Save the flags if it is updated.
1066 //
1067 if (CompareMem (&Flags, &NewFlags, sizeof(EFI_PHYSICAL_PRESENCE_FLAGS)) != 0) {
1068 Status = gRT->SetVariable (
1069 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1070 &gEfiPhysicalPresenceGuid,
1071 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1072 sizeof (EFI_PHYSICAL_PRESENCE_FLAGS),
1073 &NewFlags
1074 );
1075 if (EFI_ERROR (Status)) {
1076 return;
1077 }
1078 }
1079
1080 //
1081 // Clear request
1082 //
1083 if ((NewFlags.PPFlags & TCG_VENDOR_LIB_FLAG_RESET_TRACK) == 0) {
1084 TcgPpData->LastPPRequest = TcgPpData->PPRequest;
1085 TcgPpData->PPRequest = PHYSICAL_PRESENCE_NO_ACTION;
1086 }
1087
1088 //
1089 // Save changes
1090 //
1091 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1092 Status = gRT->SetVariable (
1093 PHYSICAL_PRESENCE_VARIABLE,
1094 &gEfiPhysicalPresenceGuid,
1095 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1096 DataSize,
1097 TcgPpData
1098 );
1099 if (EFI_ERROR (Status)) {
1100 return;
1101 }
1102
1103 if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {
1104 return;
1105 }
1106
1107 //
1108 // Reset system to make new TPM settings in effect
1109 //
1110 switch (TcgPpData->LastPPRequest) {
1111 case PHYSICAL_PRESENCE_ACTIVATE:
1112 case PHYSICAL_PRESENCE_DEACTIVATE:
1113 case PHYSICAL_PRESENCE_CLEAR:
1114 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:
1115 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:
1116 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:
1117 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:
1118 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:
1119 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:
1120 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:
1121 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:
1122 break;
1123 default:
1124 if (TcgPpData->LastPPRequest >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
1125 if (ResetRequired) {
1126 break;
1127 } else {
1128 return ;
1129 }
1130 }
1131 if (TcgPpData->PPRequest != PHYSICAL_PRESENCE_NO_ACTION) {
1132 break;
1133 }
1134 return;
1135 }
1136
1137 Print (L"Rebooting system to make TPM settings in effect\n");
1138 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1139 ASSERT (FALSE);
1140 }
1141
1142 /**
1143 Check and execute the pending TPM request and Lock TPM.
1144
1145 The TPM request may come from OS or BIOS. This API will display request information and wait
1146 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
1147 the TPM request is confirmed, and one or more reset may be required to make TPM request to
1148 take effect. At last, it will lock TPM to prevent TPM state change by malware.
1149
1150 This API should be invoked after console in and console out are all ready as they are required
1151 to display request information and get user input to confirm the request. This API should also
1152 be invoked as early as possible as TPM is locked in this function.
1153
1154 **/
1155 VOID
1156 EFIAPI
1157 TcgPhysicalPresenceLibProcessRequest (
1158 VOID
1159 )
1160 {
1161 EFI_STATUS Status;
1162 BOOLEAN LifetimeLock;
1163 BOOLEAN CmdEnable;
1164 UINTN DataSize;
1165 EFI_PHYSICAL_PRESENCE TcgPpData;
1166 EFI_TCG_PROTOCOL *TcgProtocol;
1167 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
1168 EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1169
1170 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
1171 if (EFI_ERROR (Status)) {
1172 return ;
1173 }
1174
1175 //
1176 // Initialize physical presence flags.
1177 //
1178 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
1179 Status = gRT->GetVariable (
1180 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1181 &gEfiPhysicalPresenceGuid,
1182 NULL,
1183 &DataSize,
1184 &PpiFlags
1185 );
1186 if (EFI_ERROR (Status)) {
1187 PpiFlags.PPFlags = TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;
1188 Status = gRT->SetVariable (
1189 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1190 &gEfiPhysicalPresenceGuid,
1191 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1192 sizeof (EFI_PHYSICAL_PRESENCE_FLAGS),
1193 &PpiFlags
1194 );
1195 if (EFI_ERROR (Status)) {
1196 DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence flag failed, Status = %r\n", Status));
1197 return ;
1198 }
1199 }
1200 DEBUG ((EFI_D_INFO, "[TPM] PpiFlags = %x\n", PpiFlags.PPFlags));
1201
1202 //
1203 // This flags variable controls whether physical presence is required for TPM command.
1204 // It should be protected from malicious software. We set it as read-only variable here.
1205 //
1206 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
1207 if (!EFI_ERROR (Status)) {
1208 Status = VariableLockProtocol->RequestToLock (
1209 VariableLockProtocol,
1210 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1211 &gEfiPhysicalPresenceGuid
1212 );
1213 if (EFI_ERROR (Status)) {
1214 DEBUG ((EFI_D_ERROR, "[TPM] Error when lock variable %s, Status = %r\n", PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
1215 ASSERT_EFI_ERROR (Status);
1216 }
1217 }
1218
1219 //
1220 // Initialize physical presence variable.
1221 //
1222 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1223 Status = gRT->GetVariable (
1224 PHYSICAL_PRESENCE_VARIABLE,
1225 &gEfiPhysicalPresenceGuid,
1226 NULL,
1227 &DataSize,
1228 &TcgPpData
1229 );
1230 if (EFI_ERROR (Status)) {
1231 ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
1232 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1233 Status = gRT->SetVariable (
1234 PHYSICAL_PRESENCE_VARIABLE,
1235 &gEfiPhysicalPresenceGuid,
1236 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1237 DataSize,
1238 &TcgPpData
1239 );
1240 if (EFI_ERROR (Status)) {
1241 DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence variable failed, Status = %r\n", Status));
1242 return;
1243 }
1244 }
1245
1246 DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags.PPFlags, TcgPpData.PPRequest));
1247
1248 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
1249 //
1250 // No operation request
1251 //
1252 return;
1253 }
1254
1255 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);
1256 if (EFI_ERROR (Status)) {
1257 return ;
1258 }
1259
1260 if (!CmdEnable) {
1261 if (LifetimeLock) {
1262 //
1263 // physicalPresenceCMDEnable is locked, can't execute physical presence command.
1264 //
1265 return ;
1266 }
1267 Status = TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_CMD_ENABLE);
1268 if (EFI_ERROR (Status)) {
1269 return ;
1270 }
1271 }
1272
1273 //
1274 // Set operator physical presence flags
1275 //
1276 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_PRESENT);
1277
1278 //
1279 // Execute pending TPM request.
1280 //
1281 ExecutePendingTpmRequest (TcgProtocol, &TcgPpData, PpiFlags);
1282 DEBUG ((EFI_D_INFO, "[TPM] PPResponse = %x\n", TcgPpData.PPResponse));
1283
1284 //
1285 // Lock physical presence.
1286 //
1287 TpmPhysicalPresence (TcgProtocol, TPM_PHYSICAL_PRESENCE_NOTPRESENT | TPM_PHYSICAL_PRESENCE_LOCK);
1288 }
1289
1290 /**
1291 Check if the pending TPM request needs user input to confirm.
1292
1293 The TPM request may come from OS. This API will check if TPM request exists and need user
1294 input to confirmation.
1295
1296 @retval TRUE TPM needs input to confirm user physical presence.
1297 @retval FALSE TPM doesn't need input to confirm user physical presence.
1298
1299 **/
1300 BOOLEAN
1301 EFIAPI
1302 TcgPhysicalPresenceLibNeedUserConfirm(
1303 VOID
1304 )
1305 {
1306 EFI_STATUS Status;
1307 EFI_PHYSICAL_PRESENCE TcgPpData;
1308 UINTN DataSize;
1309 BOOLEAN RequestConfirmed;
1310 BOOLEAN LifetimeLock;
1311 BOOLEAN CmdEnable;
1312 EFI_TCG_PROTOCOL *TcgProtocol;
1313 EFI_PHYSICAL_PRESENCE_FLAGS PpiFlags;
1314
1315 Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol);
1316 if (EFI_ERROR (Status)) {
1317 return FALSE;
1318 }
1319
1320 //
1321 // Check Tpm requests
1322 //
1323 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
1324 Status = gRT->GetVariable (
1325 PHYSICAL_PRESENCE_VARIABLE,
1326 &gEfiPhysicalPresenceGuid,
1327 NULL,
1328 &DataSize,
1329 &TcgPpData
1330 );
1331 if (EFI_ERROR (Status)) {
1332 return FALSE;
1333 }
1334
1335 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);
1336 Status = gRT->GetVariable (
1337 PHYSICAL_PRESENCE_FLAGS_VARIABLE,
1338 &gEfiPhysicalPresenceGuid,
1339 NULL,
1340 &DataSize,
1341 &PpiFlags
1342 );
1343 if (EFI_ERROR (Status)) {
1344 return FALSE;
1345 }
1346
1347 if (TcgPpData.PPRequest == PHYSICAL_PRESENCE_NO_ACTION) {
1348 //
1349 // No operation request
1350 //
1351 return FALSE;
1352 }
1353
1354 if (!HaveValidTpmRequest(&TcgPpData, PpiFlags, &RequestConfirmed)) {
1355 //
1356 // Invalid operation request.
1357 //
1358 return FALSE;
1359 }
1360
1361 //
1362 // Check Tpm Capability
1363 //
1364 Status = GetTpmCapability (TcgProtocol, &LifetimeLock, &CmdEnable);
1365 if (EFI_ERROR (Status)) {
1366 return FALSE;
1367 }
1368
1369 if (!CmdEnable) {
1370 if (LifetimeLock) {
1371 //
1372 // physicalPresenceCMDEnable is locked, can't execute physical presence command.
1373 //
1374 return FALSE;
1375 }
1376 }
1377
1378 if (!RequestConfirmed) {
1379 //
1380 // Need UI to confirm
1381 //
1382 return TRUE;
1383 }
1384
1385 return FALSE;
1386 }
1387