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