2 Execute pending TPM2 requests from OS or BIOS.
4 Caution: This module requires additional review when modified.
5 This driver will have external input - variable.
6 This external input must be validated carefully to avoid security issue.
8 TrEEExecutePendingTpmRequest() will receive untrusted input and do validation.
10 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
11 This program and the accompanying materials
12 are licensed and made available under the terms and conditions of the BSD License
13 which accompanies this distribution. The full text of the license may be found at
14 http://opensource.org/licenses/bsd-license.php
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include <Protocol/TrEEProtocol.h>
24 #include <Protocol/VariableLock.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/UefiRuntimeServicesTableLib.h>
28 #include <Library/UefiDriverEntryPoint.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/UefiLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/PrintLib.h>
33 #include <Library/HiiLib.h>
34 #include <Guid/EventGroup.h>
35 #include <Guid/TrEEPhysicalPresenceData.h>
36 #include <Library/Tpm2CommandLib.h>
37 #include <Library/TrEEPpVendorLib.h>
39 #define CONFIRM_BUFFER_SIZE 4096
41 EFI_HII_HANDLE mTrEEPpStringPackHandle
;
44 Get string by string id from HII Interface.
46 @param[in] Id String ID.
48 @retval CHAR16 * String from ID.
49 @retval NULL If error occurs.
53 TrEEPhysicalPresenceGetStringById (
57 return HiiGetString (mTrEEPpStringPackHandle
, Id
, NULL
);
61 Send ClearControl and Clear command to TPM.
63 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
65 @retval EFI_SUCCESS Operation completed successfully.
66 @retval EFI_TIMEOUT The register can't run into the expected status in time.
67 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
68 @retval EFI_DEVICE_ERROR Unexpected device behavior.
74 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
78 TPMS_AUTH_COMMAND
*AuthSession
;
79 TPMS_AUTH_COMMAND LocalAuthSession
;
81 if (PlatformAuth
== NULL
) {
84 AuthSession
= &LocalAuthSession
;
85 ZeroMem (&LocalAuthSession
, sizeof(LocalAuthSession
));
86 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
87 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
88 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
91 DEBUG ((EFI_D_INFO
, "Tpm2ClearControl ... \n"));
92 Status
= Tpm2ClearControl (TPM_RH_PLATFORM
, AuthSession
, NO
);
93 DEBUG ((EFI_D_INFO
, "Tpm2ClearControl - %r\n", Status
));
94 if (EFI_ERROR (Status
)) {
97 DEBUG ((EFI_D_INFO
, "Tpm2Clear ... \n"));
98 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
99 DEBUG ((EFI_D_INFO
, "Tpm2Clear - %r\n", Status
));
102 ZeroMem (&LocalAuthSession
.hmac
, sizeof(LocalAuthSession
.hmac
));
107 Execute physical presence operation requested by the OS.
109 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
110 @param[in] CommandCode Physical presence operation value.
111 @param[in, out] PpiFlags The physical presence interface flags.
113 @retval TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
114 @retval TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
115 receiving response from TPM.
116 @retval Others Return code from the TPM device after command execution.
119 TrEEExecutePhysicalPresence (
120 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
121 IN UINT32 CommandCode
,
122 IN OUT EFI_TREE_PHYSICAL_PRESENCE_FLAGS
*PpiFlags
127 switch (CommandCode
) {
128 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR
:
129 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2
:
130 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3
:
131 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4
:
132 Status
= TpmCommandClear (PlatformAuth
);
133 if (EFI_ERROR (Status
)) {
134 return TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
136 return TREE_PP_OPERATION_RESPONSE_SUCCESS
;
139 case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE
:
140 PpiFlags
->PPFlags
&= ~TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR
;
141 return TREE_PP_OPERATION_RESPONSE_SUCCESS
;
143 case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE
:
144 PpiFlags
->PPFlags
|= TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR
;
145 return TREE_PP_OPERATION_RESPONSE_SUCCESS
;
148 if (CommandCode
<= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
149 return TREE_PP_OPERATION_RESPONSE_SUCCESS
;
151 return TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
158 Read the specified key for user confirmation.
160 @param[in] CautionKey If true, F12 is used as confirm key;
161 If false, F10 is used as confirm key.
163 @retval TRUE User confirmed the changes by input.
164 @retval FALSE User discarded the changes.
168 IN BOOLEAN CautionKey
177 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
178 if (!EFI_ERROR (Status
)) {
179 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
180 if (Key
.ScanCode
== SCAN_ESC
) {
181 InputKey
= Key
.ScanCode
;
183 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
184 InputKey
= Key
.ScanCode
;
186 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
187 InputKey
= Key
.ScanCode
;
190 } while (InputKey
== 0);
192 if (InputKey
!= SCAN_ESC
) {
200 The constructor function register UNI strings into imageHandle.
202 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
204 @param ImageHandle The firmware allocated handle for the EFI image.
205 @param SystemTable A pointer to the EFI System Table.
207 @retval EFI_SUCCESS The constructor successfully added string package.
208 @retval Other value The constructor can't add string package.
212 TrEEPhysicalPresenceLibConstructor (
213 IN EFI_HANDLE ImageHandle
,
214 IN EFI_SYSTEM_TABLE
*SystemTable
217 mTrEEPpStringPackHandle
= HiiAddPackages (&gEfiTrEEPhysicalPresenceGuid
, ImageHandle
, DxeTrEEPhysicalPresenceLibStrings
, NULL
);
218 ASSERT (mTrEEPpStringPackHandle
!= NULL
);
224 Display the confirm text and get user confirmation.
226 @param[in] TpmPpCommand The requested TPM physical presence command.
228 @retval TRUE The user has confirmed the changes.
229 @retval FALSE The user doesn't confirm the changes.
233 IN UINT32 TpmPpCommand
246 BufSize
= CONFIRM_BUFFER_SIZE
;
247 ConfirmText
= AllocateZeroPool (BufSize
);
248 ASSERT (ConfirmText
!= NULL
);
250 switch (TpmPpCommand
) {
252 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR
:
253 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2
:
254 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3
:
255 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4
:
257 TmpStr2
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
259 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
260 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
263 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
264 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
265 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
268 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
269 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
273 case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE
:
275 TmpStr2
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
277 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR
));
278 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
281 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR
));
282 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
285 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
286 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
287 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
290 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
291 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
294 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
295 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
303 if (TmpStr2
== NULL
) {
304 FreePool (ConfirmText
);
308 TmpStr1
= TrEEPhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
309 BufSize
-= StrSize (ConfirmText
);
310 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
313 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
314 StrnCpyS(DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
320 FreePool (ConfirmText
);
322 if (TrEEReadUserKey (CautionKey
)) {
330 Check if there is a valid physical presence command request. Also updates parameter value
331 to whether the requested physical presence command already confirmed by user
333 @param[in] TcgPpData EFI TrEE Physical Presence request data.
334 @param[in] Flags The physical presence interface flags.
335 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
336 True, it indicates the command doesn't require user confirm, or already confirmed
337 in last boot cycle by user.
338 False, it indicates the command need user confirm from UI.
340 @retval TRUE Physical Presence operation command is valid.
341 @retval FALSE Physical Presence operation command is invalid.
345 TrEEHaveValidTpmRequest (
346 IN EFI_TREE_PHYSICAL_PRESENCE
*TcgPpData
,
347 IN EFI_TREE_PHYSICAL_PRESENCE_FLAGS Flags
,
348 OUT BOOLEAN
*RequestConfirmed
351 BOOLEAN IsRequestValid
;
353 *RequestConfirmed
= FALSE
;
355 switch (TcgPpData
->PPRequest
) {
356 case TREE_PHYSICAL_PRESENCE_NO_ACTION
:
357 *RequestConfirmed
= TRUE
;
359 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR
:
360 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2
:
361 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3
:
362 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4
:
363 if ((Flags
.PPFlags
& TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR
) != 0) {
364 *RequestConfirmed
= TRUE
;
368 case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE
:
369 *RequestConfirmed
= TRUE
;
372 case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE
:
376 if (TcgPpData
->PPRequest
>= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
377 IsRequestValid
= TrEEPpVendorLibHasValidRequest (TcgPpData
->PPRequest
, Flags
.PPFlags
, RequestConfirmed
);
378 if (!IsRequestValid
) {
385 // Wrong Physical Presence command
391 if ((Flags
.PPFlags
& TREE_VENDOR_LIB_FLAG_RESET_TRACK
) != 0) {
393 // It had been confirmed in last boot, it doesn't need confirm again.
395 *RequestConfirmed
= TRUE
;
399 // Physical Presence command is correct
406 Check and execute the requested physical presence command.
408 Caution: This function may receive untrusted input.
409 TcgPpData variable is external input, so this function will validate
410 its data structure to be valid value.
412 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
413 @param[in] TcgPpData Point to the physical presence NV variable.
414 @param[in] Flags The physical presence interface flags.
417 TrEEExecutePendingTpmRequest (
418 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
419 IN EFI_TREE_PHYSICAL_PRESENCE
*TcgPpData
,
420 IN EFI_TREE_PHYSICAL_PRESENCE_FLAGS Flags
425 BOOLEAN RequestConfirmed
;
426 EFI_TREE_PHYSICAL_PRESENCE_FLAGS NewFlags
;
427 BOOLEAN ResetRequired
;
430 if (TcgPpData
->PPRequest
== TREE_PHYSICAL_PRESENCE_NO_ACTION
) {
432 // No operation request
437 if (!TrEEHaveValidTpmRequest(TcgPpData
, Flags
, &RequestConfirmed
)) {
439 // Invalid operation request.
441 if (TcgPpData
->PPRequest
<= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
442 TcgPpData
->PPResponse
= TREE_PP_OPERATION_RESPONSE_SUCCESS
;
444 TcgPpData
->PPResponse
= TREE_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
446 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
447 TcgPpData
->PPRequest
= TREE_PHYSICAL_PRESENCE_NO_ACTION
;
448 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE
);
449 Status
= gRT
->SetVariable (
450 TREE_PHYSICAL_PRESENCE_VARIABLE
,
451 &gEfiTrEEPhysicalPresenceGuid
,
452 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
459 ResetRequired
= FALSE
;
460 if (TcgPpData
->PPRequest
>= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
462 NewPPFlags
= NewFlags
.PPFlags
;
463 TcgPpData
->PPResponse
= TrEEPpVendorLibExecutePendingRequest (PlatformAuth
, TcgPpData
->PPRequest
, &NewPPFlags
, &ResetRequired
);
464 NewFlags
.PPFlags
= (UINT8
)NewPPFlags
;
466 if (!RequestConfirmed
) {
468 // Print confirm text and wait for approval.
470 RequestConfirmed
= TrEEUserConfirm (TcgPpData
->PPRequest
475 // Execute requested physical presence command
477 TcgPpData
->PPResponse
= TREE_PP_OPERATION_RESPONSE_USER_ABORT
;
479 if (RequestConfirmed
) {
480 TcgPpData
->PPResponse
= TrEEExecutePhysicalPresence (PlatformAuth
, TcgPpData
->PPRequest
,
486 // Save the flags if it is updated.
488 if (CompareMem (&Flags
, &NewFlags
, sizeof(EFI_TREE_PHYSICAL_PRESENCE_FLAGS
)) != 0) {
489 Status
= gRT
->SetVariable (
490 TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
491 &gEfiTrEEPhysicalPresenceGuid
,
492 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
493 sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS
),
501 if ((NewFlags
.PPFlags
& TREE_VENDOR_LIB_FLAG_RESET_TRACK
) == 0) {
502 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
503 TcgPpData
->PPRequest
= TREE_PHYSICAL_PRESENCE_NO_ACTION
;
509 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE
);
510 Status
= gRT
->SetVariable (
511 TREE_PHYSICAL_PRESENCE_VARIABLE
,
512 &gEfiTrEEPhysicalPresenceGuid
,
513 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
517 if (EFI_ERROR (Status
)) {
521 if (TcgPpData
->PPResponse
== TREE_PP_OPERATION_RESPONSE_USER_ABORT
) {
526 // Reset system to make new TPM settings in effect
528 switch (TcgPpData
->LastPPRequest
) {
529 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR
:
530 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2
:
531 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3
:
532 case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4
:
535 if (TcgPpData
->LastPPRequest
>= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
542 if (TcgPpData
->PPRequest
!= TREE_PHYSICAL_PRESENCE_NO_ACTION
) {
548 Print (L
"Rebooting system to make TPM2 settings in effect\n");
549 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
554 Check and execute the pending TPM request.
556 The TPM request may come from OS or BIOS. This API will display request information and wait
557 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
558 the TPM request is confirmed, and one or more reset may be required to make TPM request to
561 This API should be invoked after console in and console out are all ready as they are required
562 to display request information and get user input to confirm the request.
564 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
568 TrEEPhysicalPresenceLibProcessRequest (
569 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
574 EFI_TREE_PHYSICAL_PRESENCE TcgPpData
;
575 EFI_TREE_PROTOCOL
*TreeProtocol
;
576 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLockProtocol
;
577 EFI_TREE_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
579 Status
= gBS
->LocateProtocol (&gEfiTrEEProtocolGuid
, NULL
, (VOID
**) &TreeProtocol
);
580 if (EFI_ERROR (Status
)) {
585 // Initialize physical presence flags.
587 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS
);
588 Status
= gRT
->GetVariable (
589 TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
590 &gEfiTrEEPhysicalPresenceGuid
,
595 if (EFI_ERROR (Status
)) {
596 PpiFlags
.PPFlags
= 0;
597 Status
= gRT
->SetVariable (
598 TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
599 &gEfiTrEEPhysicalPresenceGuid
,
600 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
601 sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS
),
604 if (EFI_ERROR (Status
)) {
605 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence flag failed, Status = %r\n", Status
));
609 DEBUG ((EFI_D_INFO
, "[TPM2] PpiFlags = %x\n", PpiFlags
.PPFlags
));
612 // This flags variable controls whether physical presence is required for TPM command.
613 // It should be protected from malicious software. We set it as read-only variable here.
615 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**)&VariableLockProtocol
);
616 if (!EFI_ERROR (Status
)) {
617 Status
= VariableLockProtocol
->RequestToLock (
618 VariableLockProtocol
,
619 TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
620 &gEfiTrEEPhysicalPresenceGuid
622 if (EFI_ERROR (Status
)) {
623 DEBUG ((EFI_D_ERROR
, "[TPM2] Error when lock variable %s, Status = %r\n", TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
, Status
));
624 ASSERT_EFI_ERROR (Status
);
629 // Initialize physical presence variable.
631 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE
);
632 Status
= gRT
->GetVariable (
633 TREE_PHYSICAL_PRESENCE_VARIABLE
,
634 &gEfiTrEEPhysicalPresenceGuid
,
639 if (EFI_ERROR (Status
)) {
640 ZeroMem ((VOID
*)&TcgPpData
, sizeof (TcgPpData
));
641 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE
);
642 Status
= gRT
->SetVariable (
643 TREE_PHYSICAL_PRESENCE_VARIABLE
,
644 &gEfiTrEEPhysicalPresenceGuid
,
645 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
649 if (EFI_ERROR (Status
)) {
650 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence variable failed, Status = %r\n", Status
));
655 DEBUG ((EFI_D_INFO
, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags
.PPFlags
, TcgPpData
.PPRequest
, TcgPpData
.LastPPRequest
));
658 // Execute pending TPM request.
660 TrEEExecutePendingTpmRequest (PlatformAuth
, &TcgPpData
, PpiFlags
);
661 DEBUG ((EFI_D_INFO
, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData
.PPResponse
, TcgPpData
.LastPPRequest
, PpiFlags
.PPFlags
));
666 Check if the pending TPM request needs user input to confirm.
668 The TPM request may come from OS. This API will check if TPM request exists and need user
669 input to confirmation.
671 @retval TRUE TPM needs input to confirm user physical presence.
672 @retval FALSE TPM doesn't need input to confirm user physical presence.
677 TrEEPhysicalPresenceLibNeedUserConfirm(
682 EFI_TREE_PHYSICAL_PRESENCE TcgPpData
;
684 BOOLEAN RequestConfirmed
;
685 EFI_TREE_PROTOCOL
*TreeProtocol
;
686 EFI_TREE_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
688 Status
= gBS
->LocateProtocol (&gEfiTrEEProtocolGuid
, NULL
, (VOID
**) &TreeProtocol
);
689 if (EFI_ERROR (Status
)) {
694 // Check Tpm requests
696 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE
);
697 Status
= gRT
->GetVariable (
698 TREE_PHYSICAL_PRESENCE_VARIABLE
,
699 &gEfiTrEEPhysicalPresenceGuid
,
704 if (EFI_ERROR (Status
)) {
708 DataSize
= sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS
);
709 Status
= gRT
->GetVariable (
710 TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
711 &gEfiTrEEPhysicalPresenceGuid
,
716 if (EFI_ERROR (Status
)) {
720 if (TcgPpData
.PPRequest
== TREE_PHYSICAL_PRESENCE_NO_ACTION
) {
722 // No operation request
727 if (!TrEEHaveValidTpmRequest(&TcgPpData
, PpiFlags
, &RequestConfirmed
)) {
729 // Invalid operation request.
734 if (!RequestConfirmed
) {
736 // Need UI to confirm