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 Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation.
10 Copyright (c) 2013 - 2016, 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/Tcg2Protocol.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 <Library/HobLib.h>
35 #include <Guid/EventGroup.h>
36 #include <Guid/Tcg2PhysicalPresenceData.h>
37 #include <Library/Tpm2CommandLib.h>
38 #include <Library/Tcg2PhysicalPresenceLib.h>
39 #include <Library/Tcg2PpVendorLib.h>
41 #define CONFIRM_BUFFER_SIZE 4096
43 EFI_HII_HANDLE mTcg2PpStringPackHandle
;
46 Get string by string id from HII Interface.
48 @param[in] Id String ID.
50 @retval CHAR16 * String from ID.
51 @retval NULL If error occurs.
55 Tcg2PhysicalPresenceGetStringById (
59 return HiiGetString (mTcg2PpStringPackHandle
, Id
, NULL
);
63 Send ClearControl and Clear command to TPM.
65 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
67 @retval EFI_SUCCESS Operation completed successfully.
68 @retval EFI_TIMEOUT The register can't run into the expected status in time.
69 @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
70 @retval EFI_DEVICE_ERROR Unexpected device behavior.
76 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
80 TPMS_AUTH_COMMAND
*AuthSession
;
81 TPMS_AUTH_COMMAND LocalAuthSession
;
83 if (PlatformAuth
== NULL
) {
86 AuthSession
= &LocalAuthSession
;
87 ZeroMem (&LocalAuthSession
, sizeof(LocalAuthSession
));
88 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
89 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
90 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
93 DEBUG ((EFI_D_INFO
, "Tpm2ClearControl ... \n"));
94 Status
= Tpm2ClearControl (TPM_RH_PLATFORM
, AuthSession
, NO
);
95 DEBUG ((EFI_D_INFO
, "Tpm2ClearControl - %r\n", Status
));
96 if (EFI_ERROR (Status
)) {
99 DEBUG ((EFI_D_INFO
, "Tpm2Clear ... \n"));
100 Status
= Tpm2Clear (TPM_RH_PLATFORM
, AuthSession
);
101 DEBUG ((EFI_D_INFO
, "Tpm2Clear - %r\n", Status
));
104 ZeroMem (&LocalAuthSession
.hmac
, sizeof(LocalAuthSession
.hmac
));
111 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
113 @retval EFI_SUCCESS Operation completed successfully.
116 Tpm2CommandChangeEps (
117 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
121 TPMS_AUTH_COMMAND
*AuthSession
;
122 TPMS_AUTH_COMMAND LocalAuthSession
;
124 if (PlatformAuth
== NULL
) {
127 AuthSession
= &LocalAuthSession
;
128 ZeroMem (&LocalAuthSession
, sizeof(LocalAuthSession
));
129 LocalAuthSession
.sessionHandle
= TPM_RS_PW
;
130 LocalAuthSession
.hmac
.size
= PlatformAuth
->size
;
131 CopyMem (LocalAuthSession
.hmac
.buffer
, PlatformAuth
->buffer
, PlatformAuth
->size
);
134 Status
= Tpm2ChangeEPS (TPM_RH_PLATFORM
, AuthSession
);
135 DEBUG ((EFI_D_INFO
, "Tpm2ChangeEPS - %r\n", Status
));
137 ZeroMem(&LocalAuthSession
.hmac
, sizeof(LocalAuthSession
.hmac
));
142 Execute physical presence operation requested by the OS.
144 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
145 @param[in] CommandCode Physical presence operation value.
146 @param[in] CommandParameter Physical presence operation parameter.
147 @param[in, out] PpiFlags The physical presence interface flags.
149 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
150 @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
151 receiving response from TPM.
152 @retval Others Return code from the TPM device after command execution.
155 Tcg2ExecutePhysicalPresence (
156 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
157 IN UINT32 CommandCode
,
158 IN UINT32 CommandParameter
,
159 IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
*PpiFlags
163 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
164 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
166 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
167 ASSERT_EFI_ERROR (Status
);
169 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
170 Status
= Tcg2Protocol
->GetCapability (
174 ASSERT_EFI_ERROR (Status
);
176 switch (CommandCode
) {
177 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
178 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
179 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
180 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
181 Status
= Tpm2CommandClear (PlatformAuth
);
182 if (EFI_ERROR (Status
)) {
183 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
185 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
188 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
189 PpiFlags
->PPFlags
|= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
;
190 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
192 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
193 PpiFlags
->PPFlags
&= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
;
194 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
196 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
197 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, ProtocolCapability
.HashAlgorithmBitmap
, CommandParameter
);
198 if (EFI_ERROR (Status
)) {
199 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
201 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
204 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
205 Status
= Tpm2CommandChangeEps (PlatformAuth
);
206 if (EFI_ERROR (Status
)) {
207 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
209 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
212 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
213 Status
= Tpm2PcrAllocateBanks (PlatformAuth
, ProtocolCapability
.HashAlgorithmBitmap
, ProtocolCapability
.HashAlgorithmBitmap
);
214 if (EFI_ERROR (Status
)) {
215 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
217 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
221 if (CommandCode
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
222 return TCG_PP_OPERATION_RESPONSE_SUCCESS
;
224 return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
231 Read the specified key for user confirmation.
233 @param[in] CautionKey If true, F12 is used as confirm key;
234 If false, F10 is used as confirm key.
236 @retval TRUE User confirmed the changes by input.
237 @retval FALSE User discarded the changes.
241 IN BOOLEAN CautionKey
250 Status
= gBS
->CheckEvent (gST
->ConIn
->WaitForKey
);
251 if (!EFI_ERROR (Status
)) {
252 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
253 if (Key
.ScanCode
== SCAN_ESC
) {
254 InputKey
= Key
.ScanCode
;
256 if ((Key
.ScanCode
== SCAN_F10
) && !CautionKey
) {
257 InputKey
= Key
.ScanCode
;
259 if ((Key
.ScanCode
== SCAN_F12
) && CautionKey
) {
260 InputKey
= Key
.ScanCode
;
263 } while (InputKey
== 0);
265 if (InputKey
!= SCAN_ESC
) {
273 Fill Buffer With BootHashAlg.
275 @param[in] Buffer Buffer to be filled.
276 @param[in] BufferSize Size of buffer.
277 @param[in] BootHashAlg BootHashAlg.
281 Tcg2FillBufferWithBootHashAlg (
284 IN UINT32 BootHashAlg
288 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA1
) != 0) {
289 if (Buffer
[0] != 0) {
290 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
292 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA1", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
294 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA256
) != 0) {
295 if (Buffer
[0] != 0) {
296 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
298 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
300 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA384
) != 0) {
301 if (Buffer
[0] != 0) {
302 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
304 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA384", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
306 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SHA512
) != 0) {
307 if (Buffer
[0] != 0) {
308 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
310 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SHA512", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
312 if ((BootHashAlg
& EFI_TCG2_BOOT_HASH_ALG_SM3_256
) != 0) {
313 if (Buffer
[0] != 0) {
314 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
", ", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
316 StrnCatS (Buffer
, BufferSize
/ sizeof (CHAR16
), L
"SM3_256", (BufferSize
/ sizeof (CHAR16
)) - StrLen (Buffer
) - 1);
321 Display the confirm text and get user confirmation.
323 @param[in] TpmPpCommand The requested TPM physical presence command.
324 @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
326 @retval TRUE The user has confirmed the changes.
327 @retval FALSE The user doesn't confirm the changes.
331 IN UINT32 TpmPpCommand
,
332 IN UINT32 TpmPpCommandParameter
343 CHAR16 TempBuffer
[1024];
344 CHAR16 TempBuffer2
[1024];
345 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
346 EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability
;
347 UINT32 CurrentPCRBanks
;
350 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
351 ASSERT_EFI_ERROR (Status
);
353 ProtocolCapability
.Size
= sizeof(ProtocolCapability
);
354 Status
= Tcg2Protocol
->GetCapability (
358 ASSERT_EFI_ERROR (Status
);
360 Status
= Tcg2Protocol
->GetActivePcrBanks (
364 ASSERT_EFI_ERROR (Status
);
369 BufSize
= CONFIRM_BUFFER_SIZE
;
370 ConfirmText
= AllocateZeroPool (BufSize
);
371 ASSERT (ConfirmText
!= NULL
);
373 switch (TpmPpCommand
) {
375 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
376 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
377 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
378 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
380 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
382 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
383 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
386 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
387 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
388 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
393 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
396 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR
));
398 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR
));
399 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
402 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR
));
403 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
406 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR
));
407 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
408 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n\n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
413 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
415 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS
));
417 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
418 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
421 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1
));
422 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
425 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2
));
426 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
429 Tcg2FillBufferWithBootHashAlg (TempBuffer
, sizeof(TempBuffer
), TpmPpCommandParameter
);
430 Tcg2FillBufferWithBootHashAlg (TempBuffer2
, sizeof(TempBuffer2
), CurrentPCRBanks
);
432 TmpStr1
= AllocateZeroPool (BufSize
);
433 ASSERT (TmpStr1
!= NULL
);
434 UnicodeSPrint (TmpStr1
, BufSize
, L
"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks
, TempBuffer2
, TpmPpCommandParameter
, TempBuffer
);
436 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
437 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), L
" \n", (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
442 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
444 TmpStr2
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS
));
446 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR
));
447 UnicodeSPrint (ConfirmText
, BufSize
, TmpStr1
, TmpStr2
);
450 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1
));
451 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
454 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2
));
455 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
465 if (TmpStr2
== NULL
) {
466 FreePool (ConfirmText
);
470 if (TpmPpCommand
< TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN
) {
472 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY
));
474 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY
));
476 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
480 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO
));
481 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
485 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY
));
488 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY
));
490 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY
));
492 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
496 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO
));
497 StrnCatS (ConfirmText
, BufSize
/ sizeof (CHAR16
), TmpStr1
, (BufSize
/ sizeof (CHAR16
)) - StrLen (ConfirmText
) - 1);
501 TmpStr1
= Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY
));
503 BufSize
-= StrSize (ConfirmText
);
504 UnicodeSPrint (ConfirmText
+ StrLen (ConfirmText
), BufSize
, TmpStr1
, TmpStr2
);
507 for (Index
= 0; Index
< StrLen (ConfirmText
); Index
+= 80) {
508 StrnCpyS (DstStr
, sizeof (DstStr
) / sizeof (CHAR16
), ConfirmText
+ Index
, sizeof (DstStr
) / sizeof (CHAR16
) - 1);
514 FreePool (ConfirmText
);
516 if (Tcg2ReadUserKey (CautionKey
)) {
524 Check if there is a valid physical presence command request. Also updates parameter value
525 to whether the requested physical presence command already confirmed by user
527 @param[in] TcgPpData EFI Tcg2 Physical Presence request data.
528 @param[in] Flags The physical presence interface flags.
529 @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
530 True, it indicates the command doesn't require user confirm, or already confirmed
531 in last boot cycle by user.
532 False, it indicates the command need user confirm from UI.
534 @retval TRUE Physical Presence operation command is valid.
535 @retval FALSE Physical Presence operation command is invalid.
539 Tcg2HaveValidTpmRequest (
540 IN EFI_TCG2_PHYSICAL_PRESENCE
*TcgPpData
,
541 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
,
542 OUT BOOLEAN
*RequestConfirmed
545 BOOLEAN IsRequestValid
;
547 *RequestConfirmed
= FALSE
;
549 switch (TcgPpData
->PPRequest
) {
550 case TCG2_PHYSICAL_PRESENCE_NO_ACTION
:
551 *RequestConfirmed
= TRUE
;
554 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
555 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
556 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
557 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
558 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR
) == 0) {
559 *RequestConfirmed
= TRUE
;
563 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE
:
564 *RequestConfirmed
= TRUE
;
567 case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE
:
570 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
571 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS
) == 0) {
572 *RequestConfirmed
= TRUE
;
576 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
577 if ((Flags
.PPFlags
& TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS
) == 0) {
578 *RequestConfirmed
= TRUE
;
582 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
583 *RequestConfirmed
= TRUE
;
587 if (TcgPpData
->PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
588 IsRequestValid
= Tcg2PpVendorLibHasValidRequest (TcgPpData
->PPRequest
, Flags
.PPFlags
, RequestConfirmed
);
589 if (!IsRequestValid
) {
596 // Wrong Physical Presence command
602 if ((Flags
.PPFlags
& TCG2_LIB_PP_FLAG_RESET_TRACK
) != 0) {
604 // It had been confirmed in last boot, it doesn't need confirm again.
606 *RequestConfirmed
= TRUE
;
610 // Physical Presence command is correct
617 Check and execute the requested physical presence command.
619 Caution: This function may receive untrusted input.
620 TcgPpData variable is external input, so this function will validate
621 its data structure to be valid value.
623 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
624 @param[in] TcgPpData Point to the physical presence NV variable.
625 @param[in] Flags The physical presence interface flags.
628 Tcg2ExecutePendingTpmRequest (
629 IN TPM2B_AUTH
*PlatformAuth
, OPTIONAL
630 IN EFI_TCG2_PHYSICAL_PRESENCE
*TcgPpData
,
631 IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
636 BOOLEAN RequestConfirmed
;
637 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags
;
638 BOOLEAN ResetRequired
;
641 if (TcgPpData
->PPRequest
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
643 // No operation request
648 if (!Tcg2HaveValidTpmRequest(TcgPpData
, Flags
, &RequestConfirmed
)) {
650 // Invalid operation request.
652 if (TcgPpData
->PPRequest
<= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) {
653 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_SUCCESS
;
655 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE
;
657 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
658 TcgPpData
->PPRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
659 TcgPpData
->PPRequestParameter
= 0;
661 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
662 Status
= gRT
->SetVariable (
663 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
664 &gEfiTcg2PhysicalPresenceGuid
,
665 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
672 ResetRequired
= FALSE
;
673 if (TcgPpData
->PPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
675 NewPPFlags
= NewFlags
.PPFlags
;
676 TcgPpData
->PPResponse
= Tcg2PpVendorLibExecutePendingRequest (PlatformAuth
, TcgPpData
->PPRequest
, &NewPPFlags
, &ResetRequired
);
677 NewFlags
.PPFlags
= NewPPFlags
;
679 if (!RequestConfirmed
) {
681 // Print confirm text and wait for approval.
683 RequestConfirmed
= Tcg2UserConfirm (TcgPpData
->PPRequest
, TcgPpData
->PPRequestParameter
);
687 // Execute requested physical presence command
689 TcgPpData
->PPResponse
= TCG_PP_OPERATION_RESPONSE_USER_ABORT
;
691 if (RequestConfirmed
) {
692 TcgPpData
->PPResponse
= Tcg2ExecutePhysicalPresence (
694 TcgPpData
->PPRequest
,
695 TcgPpData
->PPRequestParameter
,
702 // Save the flags if it is updated.
704 if (CompareMem (&Flags
, &NewFlags
, sizeof(EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
)) != 0) {
705 Status
= gRT
->SetVariable (
706 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
707 &gEfiTcg2PhysicalPresenceGuid
,
708 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
709 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
),
717 if ((NewFlags
.PPFlags
& TCG2_LIB_PP_FLAG_RESET_TRACK
) == 0) {
718 TcgPpData
->LastPPRequest
= TcgPpData
->PPRequest
;
719 TcgPpData
->PPRequest
= TCG2_PHYSICAL_PRESENCE_NO_ACTION
;
720 TcgPpData
->PPRequestParameter
= 0;
726 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
727 Status
= gRT
->SetVariable (
728 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
729 &gEfiTcg2PhysicalPresenceGuid
,
730 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
734 if (EFI_ERROR (Status
)) {
738 if (TcgPpData
->PPResponse
== TCG_PP_OPERATION_RESPONSE_USER_ABORT
) {
743 // Reset system to make new TPM settings in effect
745 switch (TcgPpData
->LastPPRequest
) {
746 case TCG2_PHYSICAL_PRESENCE_CLEAR
:
747 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR
:
748 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2
:
749 case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3
:
750 case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS
:
751 case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS
:
752 case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS
:
756 if (TcgPpData
->LastPPRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
763 if (TcgPpData
->PPRequest
!= TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
769 Print (L
"Rebooting system to make TPM2 settings in effect\n");
770 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
775 Check and execute the pending TPM request.
777 The TPM request may come from OS or BIOS. This API will display request information and wait
778 for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
779 the TPM request is confirmed, and one or more reset may be required to make TPM request to
782 This API should be invoked after console in and console out are all ready as they are required
783 to display request information and get user input to confirm the request.
785 @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
789 Tcg2PhysicalPresenceLibProcessRequest (
790 IN TPM2B_AUTH
*PlatformAuth OPTIONAL
795 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData
;
796 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
797 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLockProtocol
;
798 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
800 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
801 if (EFI_ERROR (Status
)) {
808 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
809 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
813 mTcg2PpStringPackHandle
= HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid
, gImageHandle
, DxeTcg2PhysicalPresenceLibStrings
, NULL
);
814 ASSERT (mTcg2PpStringPackHandle
!= NULL
);
817 // Initialize physical presence flags.
819 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
820 Status
= gRT
->GetVariable (
821 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
822 &gEfiTcg2PhysicalPresenceGuid
,
827 if (EFI_ERROR (Status
)) {
828 PpiFlags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
;
829 Status
= gRT
->SetVariable (
830 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
831 &gEfiTcg2PhysicalPresenceGuid
,
832 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
833 sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
),
836 if (EFI_ERROR (Status
)) {
837 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence flag failed, Status = %r\n", Status
));
841 DEBUG ((EFI_D_INFO
, "[TPM2] PpiFlags = %x\n", PpiFlags
.PPFlags
));
844 // This flags variable controls whether physical presence is required for TPM command.
845 // It should be protected from malicious software. We set it as read-only variable here.
847 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**)&VariableLockProtocol
);
848 if (!EFI_ERROR (Status
)) {
849 Status
= VariableLockProtocol
->RequestToLock (
850 VariableLockProtocol
,
851 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
852 &gEfiTcg2PhysicalPresenceGuid
854 if (EFI_ERROR (Status
)) {
855 DEBUG ((EFI_D_ERROR
, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
, Status
));
856 ASSERT_EFI_ERROR (Status
);
861 // Initialize physical presence variable.
863 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
864 Status
= gRT
->GetVariable (
865 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
866 &gEfiTcg2PhysicalPresenceGuid
,
871 if (EFI_ERROR (Status
)) {
872 ZeroMem ((VOID
*)&TcgPpData
, sizeof (TcgPpData
));
873 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
874 Status
= gRT
->SetVariable (
875 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
876 &gEfiTcg2PhysicalPresenceGuid
,
877 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
881 if (EFI_ERROR (Status
)) {
882 DEBUG ((EFI_D_ERROR
, "[TPM2] Set physical presence variable failed, Status = %r\n", Status
));
887 DEBUG ((EFI_D_INFO
, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags
.PPFlags
, TcgPpData
.PPRequest
, TcgPpData
.LastPPRequest
));
890 // Execute pending TPM request.
892 Tcg2ExecutePendingTpmRequest (PlatformAuth
, &TcgPpData
, PpiFlags
);
893 DEBUG ((EFI_D_INFO
, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData
.PPResponse
, TcgPpData
.LastPPRequest
, PpiFlags
.PPFlags
));
898 Check if the pending TPM request needs user input to confirm.
900 The TPM request may come from OS. This API will check if TPM request exists and need user
901 input to confirmation.
903 @retval TRUE TPM needs input to confirm user physical presence.
904 @retval FALSE TPM doesn't need input to confirm user physical presence.
909 Tcg2PhysicalPresenceLibNeedUserConfirm(
914 EFI_TCG2_PHYSICAL_PRESENCE TcgPpData
;
916 BOOLEAN RequestConfirmed
;
917 EFI_TCG2_PROTOCOL
*Tcg2Protocol
;
918 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags
;
920 Status
= gBS
->LocateProtocol (&gEfiTcg2ProtocolGuid
, NULL
, (VOID
**) &Tcg2Protocol
);
921 if (EFI_ERROR (Status
)) {
928 if (GetBootModeHob () == BOOT_ON_S4_RESUME
) {
929 DEBUG ((EFI_D_INFO
, "S4 Resume, Skip TPM PP process!\n"));
934 // Check Tpm requests
936 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
937 Status
= gRT
->GetVariable (
938 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
939 &gEfiTcg2PhysicalPresenceGuid
,
944 if (EFI_ERROR (Status
)) {
948 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
949 Status
= gRT
->GetVariable (
950 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
951 &gEfiTcg2PhysicalPresenceGuid
,
956 if (EFI_ERROR (Status
)) {
960 if (TcgPpData
.PPRequest
== TCG2_PHYSICAL_PRESENCE_NO_ACTION
) {
962 // No operation request
967 if (!Tcg2HaveValidTpmRequest(&TcgPpData
, PpiFlags
, &RequestConfirmed
)) {
969 // Invalid operation request.
974 if (!RequestConfirmed
) {
976 // Need UI to confirm
986 The handler for TPM physical presence function:
987 Return TPM Operation Response to OS Environment.
989 @param[out] MostRecentRequest Most recent operation request.
990 @param[out] Response Response to the most recent operation request.
992 @return Return Code for Return TPM Operation Response to OS Environment.
996 Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
997 OUT UINT32
*MostRecentRequest
,
1003 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
1005 DEBUG ((EFI_D_INFO
, "[TPM2] ReturnOperationResponseToOsFunction\n"));
1008 // Get the Physical Presence variable
1010 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1011 Status
= gRT
->GetVariable (
1012 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1013 &gEfiTcg2PhysicalPresenceGuid
,
1018 if (EFI_ERROR (Status
)) {
1019 *MostRecentRequest
= 0;
1021 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
1022 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE
;
1025 *MostRecentRequest
= PpData
.LastPPRequest
;
1026 *Response
= PpData
.PPResponse
;
1028 return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS
;
1032 The handler for TPM physical presence function:
1033 Submit TPM Operation Request to Pre-OS Environment and
1034 Submit TPM Operation Request to Pre-OS Environment 2.
1036 Caution: This function may receive untrusted input.
1038 @param[in] OperationRequest TPM physical presence operation request.
1039 @param[in] RequestParameter TPM physical presence operation request parameter.
1041 @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
1042 Submit TPM Operation Request to Pre-OS Environment 2.
1046 Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
1047 IN UINT32 OperationRequest
,
1048 IN UINT32 RequestParameter
1053 EFI_TCG2_PHYSICAL_PRESENCE PpData
;
1054 EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags
;
1056 DEBUG ((EFI_D_INFO
, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest
, RequestParameter
));
1059 // Get the Physical Presence variable
1061 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1062 Status
= gRT
->GetVariable (
1063 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1064 &gEfiTcg2PhysicalPresenceGuid
,
1069 if (EFI_ERROR (Status
)) {
1070 DEBUG ((EFI_D_ERROR
, "[TPM2] Get PP variable failure! Status = %r\n", Status
));
1071 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
1074 if ((OperationRequest
> TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX
) &&
1075 (OperationRequest
< TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) ) {
1077 // This command requires UI to prompt user for Auth data.
1079 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED
;
1082 if ((PpData
.PPRequest
!= OperationRequest
) ||
1083 (PpData
.PPRequestParameter
!= RequestParameter
)) {
1084 PpData
.PPRequest
= (UINT8
)OperationRequest
;
1085 PpData
.PPRequestParameter
= RequestParameter
;
1086 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE
);
1087 Status
= gRT
->SetVariable (
1088 TCG2_PHYSICAL_PRESENCE_VARIABLE
,
1089 &gEfiTcg2PhysicalPresenceGuid
,
1090 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1096 if (EFI_ERROR (Status
)) {
1097 DEBUG ((EFI_D_ERROR
, "[TPM2] Set PP variable failure! Status = %r\n", Status
));
1098 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE
;
1101 if (OperationRequest
>= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION
) {
1102 DataSize
= sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS
);
1103 Status
= gRT
->GetVariable (
1104 TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE
,
1105 &gEfiTcg2PhysicalPresenceGuid
,
1110 if (EFI_ERROR (Status
)) {
1111 Flags
.PPFlags
= TCG2_BIOS_TPM_MANAGEMENT_FLAG_DEFAULT
;
1113 return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest
, Flags
.PPFlags
, RequestParameter
);
1116 return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS
;